-
-
Notifications
You must be signed in to change notification settings - Fork 236
Look up dub.selections.json files in parent directories too
#2272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
5384fac to
8b1f3a9
Compare
|
Ouch, looks like the testsuite fails due to dub's own |
ed59793 to
979905f
Compare
|
I don't think this is a good behavior to add and it might confuse tools assuming that dub.selections.json is the truth for your packages. There is already Additionally if we were to change dub.selections.json (semantics) here, I think a version bump in the file would be in order. |
|
I understand this is a pretty big breaking change and might not land that easily, possibly having to resort to some environment variable to control it. The obvious usage is for us at Symmetry, for mono/big repos with a big |
|
I think it's probably fine to add the feature, but I'm not sure yet on the semantics. If we just inherit from parent directories that would be nice for sub-packages of projects, which want to read from the dub.selections.json anyway and not need to manually I think it might be best to have some kind of What do you think @s-ludwig ? |
Why is that? Seems to make it more complicated. Instead I would either error out or change parent |
The number one reason is implementation complexity - the current changes are trivial and don't require any keeping-around of the used path and re-mapping relative paths. Then I don't know enough about I don't see why that makes it more complicated. The expected use case is a big, complete master |
|
ok I think it makes sense to have only one dub.selections.json - but I think it should not check the parent dub.selections.json files (e.g. to avoid issues such as with the test runner here), but instead only use the parent package dub.selections.json, if it's a subpackage. When running Also note Sönke Ludwig added support for CC @s-ludwig |
I think we're ought to either stick with this principle and properly document it, OR re-evaluate what is people's natural expectation / need around subpackages. It's confusing even to maintainers when subpackages should be used vs configurations. |
|
How do other languages solves these issues? Would be interesting to check if Rust have these same issues and implement them in a similar way to what we plan. |
|
Apart from merging with master what more work needs to happen in this MR, @kinke? |
What is meant by "changes are always saved to a local dub.selections.json file.", @kinke? I interpret "Such an 'inherited' selections file is never mutated when running dub for a nested project" as no dub.selections.json will ever be written in such cases but then you say there will be a dub.selections.json saved; I don't understand. |
Well, it's a pretty big breaking change and might not be always desirable. So maybe make it opt-in via cmdline flag or extending the dub.selections.json file (
If you run e.g. |
979905f to
1ee1bfc
Compare
|
✅ PR OK, no changes in deprecations or warnings Total deprecations: 0 Total warnings: 0 Build statistics: statistics (-before, +after)
-executable size=5259464 bin/dub
+executable size=5263616 bin/dub
rough build time=64sFull build output |
In case the root package directory doesn't contain a `dub.selections.json` file, look in parent directories too and load the first (deepest) one. This allows using a 'central' `dub.selections.json` file for a repository containing multiple dub projects, making it automatically apply to all builds in that source tree if located in the repository root directory (unless a local `dub.selections.json` overrides it). Such an 'inherited' selections file is never mutated when running dub for a nested project, i.e., changes are always saved to a *local* `dub.selections.json` file.
…m applying to test projects]
1ee1bfc to
6e088c8
Compare
|
Rebased and made opt-in via a new optional I've left the |
|
I think keeping fileVersion at 1 is fine here, since it's not backwards incompatible |
|
Ping. |
955aed5 to
b81c967
Compare
As e.g. reggae needs to know which dub.selections.json file was used.
|
Given the opt-in nature now with having to set inheritability in the parent selections file, I don't see any reason to not merget his. Objections? |
3a0451d to
b5a6b8d
Compare
|
Updated yet again to resolve merge conflicts. The change is better integrated now; I got rid of the earlier new extra helper ( |
…ent-dir Conflicts: source/dub/project.d
b5a6b8d to
db1139a
Compare
| struct SelectionsFileLookupResult { | ||
| NativePath absolutePath; // to dub.selections.json | ||
| SelectionsFile selectionsFile; | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Every public symbol should have DDOC, even if simple
- I think we could fold this into
SelectionsFile, can't we ? In which case we can disregard (1).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- would be doable after a quick glance, but would need a changed signature for the public
SelectionsFile.fromYAML()factory function (unused in dub AFAICT), adding apathparameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fromYAML is a hook used by Configy so changing the signature is not going to work out so well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I figured, so I went with option 1.
source/dub/packagemanager.d
Outdated
| * might use an unsupported version (see `SelectionsFile` documentation). | ||
| */ | ||
| package final Nullable!SelectionsFile readSelections(in Package project) { | ||
| final Nullable!SelectionsFileLookupResult readSelections(in NativePath absProjectPath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we make it public, I'm not sure it should be final anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-final now.
test/selections-from-parent-dir.sh
Outdated
| #!/usr/bin/env bash | ||
|
|
||
| . $(dirname "${BASH_SOURCE[0]}")/common.sh | ||
| cd "${CURR_DIR}/selections-from-parent-dir/pkg2" || die "Could not cd." | ||
|
|
||
| "$DUB" build --nodeps | ||
|
|
||
| if [ -f dub.selections.json ]; then | ||
| die "Shouldn't create a dub.selections.json in pkg2 subdir." | ||
| fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any chance you could convert this to the new test framework ? E.g. see source/dub/test/other.d.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did; pretty cool. 👍 - dub test -c library-nonet fails for some rather bizarre reason (the CI problem), dub test alone works fine.
object.Exception@source/dub/packagemanager.d(408): No package file found in /dub/project/pkg2/../pkg1/, expected one of dub.json/dub.sdl/package.json
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solved; was a problem of the mocked file system (no entries for . and .., so needs extra normalization; might be required in other places too).
c23d3c2 to
4b6638f
Compare
Geod24
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Made a few suggestions. I thing there's nothing blocking the merge (although I would like to see the points addressed, especially the ones about inheritable property and absolute path, as that could trigger an assert easily) but can do it myself if you just want to go agead.
source/dub/packagemanager.d
Outdated
| // check for dub.selections.json in root project dir first, then walk up its | ||
| // parent directories and look for inheritable dub.selections.json files | ||
| for (NativePath dir = absProjectPath; !dir.empty; dir = dir.hasParentPath ? dir.parentPath : NativePath.init) { | ||
| const path = dir ~ "dub.selections.json"; | ||
| if (!this.existsFile(path)) | ||
| continue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logically this would be better represented as something that returns a path that is then acted on. The code as-is does not mean to be changed (it works, that's what matters) but a loop that ends up with an unconditional break is not a loop (or IOW, contains too much code).
source/dub/project.d
Outdated
| auto selected = mgr.readSelections(pack); | ||
| // Parsing error that will be displayed to the user or just no selections | ||
| if (selected.isNull()) | ||
| auto lookupResult = mgr.readSelections(pack.path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we know here that the path is absolute ?
Loops like we should just change the signature of the function ?
| /// A SelectionsFile associated with its file-system path. | ||
| struct SelectionsFileLookupResult { | ||
| /// The absolute path to the dub.selections.json file | ||
| /// (potentially inherited from a parent directory of the root package). | ||
| NativePath absolutePath; | ||
| /// The parsed dub.selections.json file. | ||
| SelectionsFile selectionsFile; | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to fold this into SelectionsFile, but I know it's not currently possible. All things considered, it might be a good thing to add to Configy, so I'll have a look at it myself. It should not block this being merged.
| @@ -0,0 +1,113 @@ | |||
| module dub.test.selections_from_parent_dir; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Module doc please
| assert(dub.fs.existsFile(nestedPath)); | ||
| assert(dub.fs.readFile(path) == dubSelectionsJsonContent, | ||
| "Inherited dub.selections.json modified after dub upgrade!"); | ||
| const nestedContent = cast(string) dub.fs.readFile(nestedPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
readText
| // no selections for root/a/b/ | ||
| { | ||
| const result = dub.packageManager.readSelections(root_a_b); | ||
| assert(result.isNull()); | ||
| } | ||
|
|
||
| // local selections for root/a/ | ||
| { | ||
| const result = dub.packageManager.readSelections(root_a); | ||
| assert(!result.isNull()); | ||
| assert(result.get().absolutePath == root_a ~ "dub.selections.json"); | ||
| assert(!result.get().selectionsFile.inheritable); | ||
| } | ||
|
|
||
| // local selections for root/ | ||
| { | ||
| const result = dub.packageManager.readSelections(root); | ||
| assert(!result.isNull()); | ||
| assert(result.get().absolutePath == root ~ "dub.selections.json"); | ||
| assert(result.get().selectionsFile.inheritable); | ||
| } | ||
|
|
||
| // after removing non-inheritable root/a/dub.selections.json: inherited root selections for root/a/b/ | ||
| { | ||
| dub.fs.removeFile(root_a ~ "dub.selections.json"); | ||
|
|
||
| const result = dub.packageManager.readSelections(root_a_b); | ||
| assert(!result.isNull()); | ||
| assert(result.get().absolutePath == root ~ "dub.selections.json"); | ||
| assert(result.get().selectionsFile.inheritable); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe those tests should check the version too ? IIUC before the rm hasAlldependencies should be false, and it should be true afterwards. You can use TestDub.newTest to easily test this.
|
@kinke : I took the liberty to push the requested fixes, as I know you are away and I'm sure you'd like this fixed sooner than later. |
|
Well looks like vibe-core has a bug too, but we can work around that. |
|
None of the workaround is pretty though, so I opened vibe-d/vibe-core#400 |
bb236b9 to
cd770ed
Compare
|
Thanks Mathias! |
In case the root package directory doesn't contain a
dub.selections.jsonfile, dub now looks in parent directories too and potentially uses the first (deepest) one it finds - iff that JSON file contains an optional new"inheritable": trueflag.This allows using a 'central'
dub.selections.jsonfile for a repository containing multiple dub projects, making it automatically apply to all builds in that source tree if located in the repository root directory (unless a localdub.selections.jsonoverrides it).Such an inherited selections file is never mutated when running dub for a nested project, i.e., changes are always saved to a local
dub.selections.jsonfile.