blob: 17ff239e0546a7d6e0667acd9548f269d79ae6c7 [file] [log] [blame]
// Copyright 2023 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package com.google.devtools.build.lib.bazel.bzlmod;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.bazel.repository.starlark.StarlarkRepositoryFunction;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.build.skyframe.SkyframeLookupResult;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
/**
* Gather and fetch all the repositories from MODULE.bazel resolution and extensions evaluation. If
* this is fetch configure, only configure repos will be fetched and returned
*/
public class BazelFetchAllFunction implements SkyFunction {
@Override
@Nullable
public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException {
// Collect all the repos we want to fetch here
List<RepositoryName> reposToFetch = new ArrayList<>();
// 1. Run resolution and collect the dependency graph repos except for main
BazelDepGraphValue depGraphValue = (BazelDepGraphValue) env.getValue(BazelDepGraphValue.KEY);
if (depGraphValue == null) {
return null;
}
reposToFetch.addAll(
depGraphValue.getCanonicalRepoNameLookup().keySet().stream()
.filter(repo -> !repo.isMain())
.collect(toImmutableList()));
// 2. Run every extension found in the modules & collect its generated repos
ImmutableSet<ModuleExtensionId> extensionIds =
depGraphValue.getExtensionUsagesTable().rowKeySet();
ImmutableSet<SkyKey> singleExtensionKeys =
extensionIds.stream().map(SingleExtensionValue::key).collect(toImmutableSet());
SkyframeLookupResult singleExtensionValues = env.getValuesAndExceptions(singleExtensionKeys);
for (SkyKey singleExtensionKey : singleExtensionKeys) {
SingleExtensionValue singleExtensionValue =
(SingleExtensionValue) singleExtensionValues.get(singleExtensionKey);
if (singleExtensionValue == null) {
return null;
}
reposToFetch.addAll(singleExtensionValue.getCanonicalRepoNameToInternalNames().keySet());
}
// 3. If this is fetch configure, get repo rules and only collect repos marked as configure
Boolean fetchConfigure = (Boolean) skyKey.argument();
if (fetchConfigure) {
ImmutableSet<SkyKey> repoRuleKeys =
reposToFetch.stream().map(BzlmodRepoRuleValue::key).collect(toImmutableSet());
reposToFetch.clear(); // empty this list to only add configured repos
SkyframeLookupResult repoRuleValues = env.getValuesAndExceptions(repoRuleKeys);
for (SkyKey repoRuleKey : repoRuleKeys) {
BzlmodRepoRuleValue repoRuleValue = (BzlmodRepoRuleValue) repoRuleValues.get(repoRuleKey);
if (repoRuleValue == null) {
return null;
}
if (StarlarkRepositoryFunction.isConfigureRule(repoRuleValue.getRule())) {
reposToFetch.add((RepositoryName) repoRuleKey.argument());
}
}
}
// 4. Fetch all the collected repos
List<RepositoryName> shouldVendor = new ArrayList<>();
ImmutableSet<SkyKey> repoDelegatorKeys =
reposToFetch.stream().map(RepositoryDirectoryValue::key).collect(toImmutableSet());
SkyframeLookupResult repoDirValues = env.getValuesAndExceptions(repoDelegatorKeys);
for (SkyKey repoDelegatorKey : repoDelegatorKeys) {
RepositoryDirectoryValue repoDirValue =
(RepositoryDirectoryValue) repoDirValues.get(repoDelegatorKey);
if (repoDirValue == null) {
return null;
}
if (!repoDirValue.excludeFromVendoring()) {
shouldVendor.add((RepositoryName) repoDelegatorKey.argument());
}
}
return BazelFetchAllValue.create(
ImmutableList.copyOf(reposToFetch), ImmutableList.copyOf(shouldVendor));
}
}