Skip to content

Commit

Permalink
bazel sync: add an option to only sync a particular set of repositories
Browse files Browse the repository at this point in the history
Add an option --only to `bazel sync` allowing to specify that only a specified
set of external repositories be synced. Still, all repositories (or only the
configure-like ones, if --configure is given) are considered out of date; so if
the specified repository depends one of those, those are fetched as well.

Change-Id: I1712963077081452fbaca0f34e2ab9415d80f880
PiperOrigin-RevId: 290583672
  • Loading branch information
aehlig authored and copybara-github committed Jan 20, 2020
1 parent 044264e commit 912e822
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public BlazeCommandResult exec(CommandEnvironment env, OptionsParsingResult opti
// fetch anyway. So the only task remaining is to record the use of "bind" for whoever
// collects resolved information.
env.getReporter().post(resolveBind(rule));
} else if (shouldSync(rule, syncOptions.configure)) {
} else if (shouldSync(rule, syncOptions)) {
// TODO(aehlig): avoid the detour of serializing and then parsing the repository name
try {
repositoriesToFetch.add(
Expand Down Expand Up @@ -221,12 +221,16 @@ public BlazeCommandResult exec(CommandEnvironment env, OptionsParsingResult opti
return BlazeCommandResult.exitCode(exitCode);
}

private static boolean shouldSync(Rule rule, boolean configure) {
private static boolean shouldSync(Rule rule, SyncOptions options) {
if (!rule.getRuleClassObject().getWorkspaceOnly()) {
// We should only sync workspace rules
return false;
}
if (configure) {
if (options.only != null && !options.only.isEmpty() && !options.only.contains(rule.getName())) {
// There is a whitelist of what to sync, but the rule is not in this white list
return false;
}
if (options.configure) {
// If this is only a configure run, only sync Starlark rules that
// declare themselves as configure-like.
return SkylarkRepositoryFunction.isConfigureRule(rule);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
import com.google.devtools.common.options.OptionsBase;
import java.util.List;

/** Defines the options specific to Bazel's sync command */
public class SyncOptions extends OptionsBase {
Expand All @@ -27,4 +28,15 @@ public class SyncOptions extends OptionsBase {
effectTags = {OptionEffectTag.CHANGES_INPUTS},
help = "Only sync repositories marked as 'configure' for system-configuration purpose.")
public boolean configure;

@Option(
name = "only",
defaultValue = "null",
allowMultiple = true,
documentationCategory = OptionDocumentationCategory.EXECUTION_STRATEGY,
effectTags = {OptionEffectTag.CHANGES_INPUTS},
help =
"If this option is given, only sync the repositories specified with this option."
+ " Still consider all (or all configure-like, of --configure is given) outdated.")
public List<String> only;
}
49 changes: 49 additions & 0 deletions src/test/shell/bazel/skylark_repository_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,55 @@ EOF
|| fail "expected success after successful sync"
}

function test_sync_only() {
# Set up two repositories that count how often they are fetched
cat >environ.bzl <<'EOF'
def environ(r_ctx, var):
return r_ctx.os.environ[var] if var in r_ctx.os.environ else "undefined"
EOF
cat <<'EOF' >bar.tpl
FOO=%{FOO} BAR=%{BAR} BAZ=%{BAZ}
EOF
write_environ_skylark "${TEST_TMPDIR}/executionFOO" ""
mv test.bzl testfoo.bzl
write_environ_skylark "${TEST_TMPDIR}/executionBAR" ""
mv test.bzl testbar.bzl
cat > WORKSPACE <<'EOF'
load("//:testfoo.bzl", foorepo="repo")
load("//:testbar.bzl", barrepo="repo")
foorepo(name="foo")
barrepo(name="bar")
EOF
touch BUILD
bazel clean --expunge
echo 0 > "${TEST_TMPDIR}/executionFOO"
echo 0 > "${TEST_TMPDIR}/executionBAR"

# Normal sync should hit both repositories
echo; echo bazel sync; echo
bazel sync
assert_equals 1 $(cat "${TEST_TMPDIR}/executionFOO")
assert_equals 1 $(cat "${TEST_TMPDIR}/executionBAR")

# Only foo
echo; echo bazel sync --only foo; echo
bazel sync --only foo
assert_equals 2 $(cat "${TEST_TMPDIR}/executionFOO")
assert_equals 1 $(cat "${TEST_TMPDIR}/executionBAR")

# Only bar
echo; echo bazel sync --only bar; echo
bazel sync --only bar
assert_equals 2 $(cat "${TEST_TMPDIR}/executionFOO")
assert_equals 2 $(cat "${TEST_TMPDIR}/executionBAR")

# Only bar
echo; echo bazel sync --only bar; echo
bazel sync --only bar
assert_equals 2 $(cat "${TEST_TMPDIR}/executionFOO")
assert_equals 3 $(cat "${TEST_TMPDIR}/executionBAR")
}

function test_download_failure_message() {
# Regression test for #7850
# Verify that the for a failed downlaod, it is clearly indicated
Expand Down

0 comments on commit 912e822

Please sign in to comment.