Skip to content

Commit f7627e0

Browse files
SalmaSamycopybara-github
authored andcommitted
Support (workspace) relative paths in --override_module
closes bazelbuild#17551 PiperOrigin-RevId: 519710834 Change-Id: I992d68e40b600ba921000d34d878186701baad2c
1 parent 16c639c commit f7627e0

File tree

5 files changed

+149
-49
lines changed

5 files changed

+149
-49
lines changed

src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java

+20-4
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,8 @@ public void beforeCommand(CommandEnvironment env) throws AbruptExitException {
394394
// We use a LinkedHashMap to preserve the iteration order.
395395
Map<RepositoryName, PathFragment> overrideMap = new LinkedHashMap<>();
396396
for (RepositoryOverride override : repoOptions.repositoryOverrides) {
397-
overrideMap.put(override.repositoryName(), override.path());
397+
String repoPath = getAbsolutePath(override.path(), env);
398+
overrideMap.put(override.repositoryName(), PathFragment.create(repoPath));
398399
}
399400
ImmutableMap<RepositoryName, PathFragment> newOverrides = ImmutableMap.copyOf(overrideMap);
400401
if (!Maps.difference(overrides, newOverrides).areEqual()) {
@@ -406,9 +407,9 @@ public void beforeCommand(CommandEnvironment env) throws AbruptExitException {
406407

407408
if (repoOptions.moduleOverrides != null) {
408409
Map<String, ModuleOverride> moduleOverrideMap = new LinkedHashMap<>();
409-
for (RepositoryOptions.ModuleOverride modOverride : repoOptions.moduleOverrides) {
410-
moduleOverrideMap.put(
411-
modOverride.moduleName(), LocalPathOverride.create(modOverride.path()));
410+
for (RepositoryOptions.ModuleOverride override : repoOptions.moduleOverrides) {
411+
String modulePath = getAbsolutePath(override.path(), env);
412+
moduleOverrideMap.put(override.moduleName(), LocalPathOverride.create(modulePath));
412413
}
413414
ImmutableMap<String, ModuleOverride> newModOverrides =
414415
ImmutableMap.copyOf(moduleOverrideMap);
@@ -471,6 +472,21 @@ public void beforeCommand(CommandEnvironment env) throws AbruptExitException {
471472
}
472473
}
473474

475+
/**
476+
* If the given path is absolute path, leave it as it is. If the given path is a relative path, it
477+
* is relative to the current working directory. If the given path starts with '%workspace%, it is
478+
* relative to the workspace root, which is the output of `bazel info workspace`.
479+
*
480+
* @return Absolute Path
481+
*/
482+
private String getAbsolutePath(String path, CommandEnvironment env) {
483+
path = path.replace("%workspace%", env.getWorkspace().getPathString());
484+
if (!PathFragment.isAbsolute(path)) {
485+
path = env.getWorkingDirectory().getRelative(path).getPathString();
486+
}
487+
return path;
488+
}
489+
474490
@Override
475491
public ImmutableList<Injected> getPrecomputedValues() {
476492
return ImmutableList.of(

src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java

+20-23
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,12 @@ public class RepositoryOptions extends OptionsBase {
151151
converter = RepositoryOverrideConverter.class,
152152
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
153153
effectTags = {OptionEffectTag.UNKNOWN},
154-
help = "Overrides a repository with a local directory.")
154+
help =
155+
"Override a repository with a local path in the form of <repository name>=<path>. If the"
156+
+ " given path is an absolute path, it will be used as it is. If the given path is a"
157+
+ " relative path, it is relative to the current working directory. If the given path"
158+
+ " starts with '%workspace%, it is relative to the workspace root, which is the"
159+
+ " output of `bazel info workspace`")
155160
public List<RepositoryOverride> repositoryOverrides;
156161

157162
@Option(
@@ -161,7 +166,12 @@ public class RepositoryOptions extends OptionsBase {
161166
converter = ModuleOverrideConverter.class,
162167
documentationCategory = OptionDocumentationCategory.BZLMOD,
163168
effectTags = {OptionEffectTag.UNKNOWN},
164-
help = "Overrides a module with a local directory.")
169+
help =
170+
"Override a module with a local path in the form of <module name>=<path>. If the given"
171+
+ " path is an absolute path, it will be used as it is. If the given path is a"
172+
+ " relative path, it is relative to the current working directory. If the given path"
173+
+ " starts with '%workspace%, it is relative to the workspace root, which is the"
174+
+ " output of `bazel info workspace`")
165175
public List<ModuleOverride> moduleOverrides;
166176

167177
@Option(
@@ -325,17 +335,10 @@ public RepositoryOverride convert(String input) throws OptionsParsingException {
325335
throw new OptionsParsingException(
326336
"Repository overrides must be of the form 'repository-name=path'", input);
327337
}
328-
OptionsUtils.AbsolutePathFragmentConverter absolutePathFragmentConverter =
329-
new OptionsUtils.AbsolutePathFragmentConverter();
330-
PathFragment path;
331-
try {
332-
path = absolutePathFragmentConverter.convert(pieces[1]);
333-
} catch (OptionsParsingException e) {
334-
throw new OptionsParsingException(
335-
"Repository override directory must be an absolute path", input, e);
336-
}
338+
OptionsUtils.PathFragmentConverter pathConverter = new OptionsUtils.PathFragmentConverter();
339+
String pathString = pathConverter.convert(pieces[1]).getPathString();
337340
try {
338-
return RepositoryOverride.create(RepositoryName.create(pieces[0]), path);
341+
return RepositoryOverride.create(RepositoryName.create(pieces[0]), pathString);
339342
} catch (LabelSyntaxException e) {
340343
throw new OptionsParsingException("Invalid repository name given to override", input, e);
341344
}
@@ -367,15 +370,9 @@ public ModuleOverride convert(String input) throws OptionsParsingException {
367370
pieces[0]));
368371
}
369372

370-
OptionsUtils.AbsolutePathFragmentConverter absolutePathFragmentConverter =
371-
new OptionsUtils.AbsolutePathFragmentConverter();
372-
try {
373-
var path = absolutePathFragmentConverter.convert(pieces[1]);
374-
return ModuleOverride.create(pieces[0], path.toString());
375-
} catch (OptionsParsingException e) {
376-
throw new OptionsParsingException(
377-
"Module override directory must be an absolute path", input, e);
378-
}
373+
OptionsUtils.PathFragmentConverter pathConverter = new OptionsUtils.PathFragmentConverter();
374+
String pathString = pathConverter.convert(pieces[1]).getPathString();
375+
return ModuleOverride.create(pieces[0], pathString);
379376
}
380377

381378
@Override
@@ -388,13 +385,13 @@ public String getTypeDescription() {
388385
@AutoValue
389386
public abstract static class RepositoryOverride {
390387

391-
private static RepositoryOverride create(RepositoryName repositoryName, PathFragment path) {
388+
private static RepositoryOverride create(RepositoryName repositoryName, String path) {
392389
return new AutoValue_RepositoryOptions_RepositoryOverride(repositoryName, path);
393390
}
394391

395392
public abstract RepositoryName repositoryName();
396393

397-
public abstract PathFragment path();
394+
public abstract String path();
398395
}
399396

400397
/** A module override, represented by a name and an absolute path to a module. */

src/test/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptionsTest.java

+13-9
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,22 @@ public class RepositoryOptionsTest {
4545
public void testOverrideConverter() throws Exception {
4646
RepositoryOverride actual = converter.convert("foo=/bar");
4747
assertThat(actual.repositoryName()).isEqualTo(RepositoryName.createUnvalidated("foo"));
48-
assertThat(actual.path()).isEqualTo(PathFragment.create("/bar"));
48+
assertThat(PathFragment.create(actual.path())).isEqualTo(PathFragment.create("/bar"));
4949
}
5050

5151
@Test
5252
public void testOverridePathWithEqualsSign() throws Exception {
5353
RepositoryOverride actual = converter.convert("foo=/bar=/baz");
5454
assertThat(actual.repositoryName()).isEqualTo(RepositoryName.createUnvalidated("foo"));
55-
assertThat(actual.path()).isEqualTo(PathFragment.create("/bar=/baz"));
55+
assertThat(PathFragment.create(actual.path())).isEqualTo(PathFragment.create("/bar=/baz"));
5656
}
5757

5858
@Test
5959
public void testOverridePathWithTilde() throws Exception {
6060
RepositoryOverride actual = converter.convert("foo=~/bar");
6161
assertThat(actual.repositoryName()).isEqualTo(RepositoryName.createUnvalidated("foo"));
62-
assertThat(actual.path()).isEqualTo(PathFragment.create(USER_HOME.value() + "/bar"));
62+
assertThat(PathFragment.create(actual.path()))
63+
.isEqualTo(PathFragment.create(USER_HOME.value() + "/bar"));
6364
}
6465

6566
@Test
@@ -70,6 +71,15 @@ public void testModuleOverridePathWithTilde() throws Exception {
7071
.isEqualTo(PathFragment.create(USER_HOME.value() + "/bar"));
7172
}
7273

74+
@Test
75+
public void testModuleOverrideRelativePath() throws Exception {
76+
var converter = new ModuleOverrideConverter();
77+
ModuleOverride actual = converter.convert("foo=%workspace%/bar");
78+
assertThat(actual.path()).isEqualTo("%workspace%/bar");
79+
actual = converter.convert("foo=../../bar");
80+
assertThat(actual.path()).isEqualTo("../../bar");
81+
}
82+
7383
@Test
7484
public void testInvalidOverride() throws Exception {
7585
expectedException.expect(OptionsParsingException.class);
@@ -85,10 +95,4 @@ public void testInvalidRepoOverride() throws Exception {
8595
converter.convert("foo/bar=/baz");
8696
}
8797

88-
@Test
89-
public void testInvalidPathOverride() throws Exception {
90-
expectedException.expect(OptionsParsingException.class);
91-
expectedException.expectMessage("Repository override directory must be an absolute path");
92-
converter.convert("foo=bar");
93-
}
9498
}

src/test/py/bazel/bzlmod/bazel_module_test.py

+85-6
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,8 @@ def testRepositoryRuleErrorInModuleExtensionFailsTheBuild(self):
389389
in line for line in stderr
390390
]))
391391

392-
def testCommandLineModuleOverride(self):
392+
def testCmdAbsoluteModuleOverride(self):
393+
# test commandline_overrides takes precedence over local_path_override
393394
self.ScratchFile('MODULE.bazel', [
394395
'bazel_dep(name = "ss", version = "1.0")',
395396
'local_path_override(',
@@ -416,15 +417,93 @@ def testCommandLineModuleOverride(self):
416417
])
417418
self.ScratchFile('bb/WORKSPACE')
418419

419-
_, _, stderr = self.RunBazel([
420-
'build', '--experimental_enable_bzlmod', '@ss//:all',
421-
'--override_module', 'ss=' + self.Path('bb')
422-
],
423-
allow_failure=False)
420+
_, _, stderr = self.RunBazel(
421+
['build', '@ss//:all', '--override_module', 'ss=' + self.Path('bb')],
422+
allow_failure=False,
423+
)
424424
# module file override should be ignored, and bb directory should be used
425425
self.assertIn(
426426
'Target @ss~override//:choose_me up-to-date (nothing to build)', stderr)
427427

428+
def testCmdRelativeModuleOverride(self):
429+
self.ScratchFile('aa/WORKSPACE')
430+
self.ScratchFile(
431+
'aa/MODULE.bazel',
432+
[
433+
'bazel_dep(name = "ss", version = "1.0")',
434+
],
435+
)
436+
self.ScratchFile('aa/BUILD')
437+
438+
self.ScratchFile('aa/cc/BUILD')
439+
440+
self.ScratchFile('bb/WORKSPACE')
441+
self.ScratchFile(
442+
'bb/MODULE.bazel',
443+
[
444+
'module(name="ss")',
445+
],
446+
)
447+
self.ScratchFile(
448+
'bb/BUILD',
449+
[
450+
'filegroup(name = "choose_me")',
451+
],
452+
)
453+
454+
_, _, stderr = self.RunBazel(
455+
[
456+
'build',
457+
'@ss//:all',
458+
'--override_module',
459+
'ss=../../bb',
460+
'--enable_bzlmod',
461+
],
462+
cwd=self.Path('aa/cc'),
463+
allow_failure=False,
464+
)
465+
self.assertIn(
466+
'Target @ss~override//:choose_me up-to-date (nothing to build)', stderr
467+
)
468+
469+
def testCmdWorkspaceRelativeModuleOverride(self):
470+
self.ScratchFile('WORKSPACE')
471+
self.ScratchFile(
472+
'MODULE.bazel',
473+
[
474+
'bazel_dep(name = "ss", version = "1.0")',
475+
],
476+
)
477+
self.ScratchFile('BUILD')
478+
self.ScratchFile('aa/BUILD')
479+
self.ScratchFile('bb/WORKSPACE')
480+
self.ScratchFile(
481+
'bb/MODULE.bazel',
482+
[
483+
'module(name="ss")',
484+
],
485+
)
486+
self.ScratchFile(
487+
'bb/BUILD',
488+
[
489+
'filegroup(name = "choose_me")',
490+
],
491+
)
492+
493+
_, _, stderr = self.RunBazel(
494+
[
495+
'build',
496+
'@ss//:all',
497+
'--override_module',
498+
'ss=%workspace%/bb',
499+
],
500+
cwd=self.Path('aa'),
501+
allow_failure=False,
502+
)
503+
self.assertIn(
504+
'Target @ss~override//:choose_me up-to-date (nothing to build)', stderr
505+
)
506+
428507
def testDownload(self):
429508
data_path = self.ScratchFile('data.txt', ['some data'])
430509
data_url = pathlib.Path(data_path).resolve().as_uri()

src/test/shell/bazel/workspace_test.sh

+11-7
Original file line numberDiff line numberDiff line change
@@ -263,29 +263,33 @@ local_repository(
263263
path = "original",
264264
)
265265
EOF
266+
# Test absolute path
266267
bazel build --override_repository="o=$PWD/override" @o//:gen &> $TEST_log \
267268
|| fail "Expected build to succeed"
268269
assert_contains "override" bazel-genfiles/external/o/gen.out
269-
270+
# Test no override used
270271
bazel build @o//:gen &> $TEST_log \
271272
|| fail "Expected build to succeed"
272273
assert_contains "original" bazel-genfiles/external/o/gen.out
273-
274-
bazel build --override_repository="o=$PWD/override" @o//:gen &> $TEST_log \
274+
# Test relative path (should be relative to working directory)
275+
bazel build --override_repository="o=override" @o//:gen &> $TEST_log \
275276
|| fail "Expected build to succeed"
276277
assert_contains "override" bazel-genfiles/external/o/gen.out
277278

278-
bazel build @o//:gen &> $TEST_log \
279-
|| fail "Expected build to succeed"
280-
assert_contains "original" bazel-genfiles/external/o/gen.out
281-
282279
# For multiple override options, the latest should win
283280
bazel build --override_repository=o=/ignoreme \
284281
--override_repository="o=$PWD/override" \
285282
@o//:gen &> $TEST_log \
286283
|| fail "Expected build to succeed"
287284
assert_contains "override" bazel-genfiles/external/o/gen.out
288285

286+
# Test workspace relative path
287+
mkdir -p dummy
288+
cd dummy
289+
bazel build --override_repository="o=%workspace%/override" @o//:gen &> $TEST_log \
290+
|| fail "Expected build to succeed"
291+
assert_contains "override" ../bazel-genfiles/external/o/gen.out
292+
289293
}
290294

291295
function test_workspace_override_starlark(){

0 commit comments

Comments
 (0)