-
Notifications
You must be signed in to change notification settings - Fork 80
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
Support "Colocation" #602
Comments
Here's my current understanding: spago-next as well as the registry work on a hardcoded Example 1 (registry-dev/App/API.purs): Log.debug $ "Package downloaded to " <> packageDirectory <> ", verifying it contains a src directory with valid modules..."
Internal.Path.readPursFiles (Path.concat [ packageDirectory, "src" ]) >>= case _ of And Example 2 (spago/spaghetto/Spago/Command/Publish.purs): unlessM (Operation.Validation.containsPursFile (Path.concat [ selected.path, "src" ])) $ addError $ toDoc
[ "Your package has no .purs files in the src directory. "
, "All package sources must be in the `src` directory, with any additional "
, "sources indicated by the `files` key in your manifest."
] Interestingly, the error message here already hints at a planned feature of supporting the , files :: Maybe (NonEmptyArray NonEmptyString) So my first idea about how to support colocation was to implement the handling of the excludeFiles:
- /src/**/*Spec.purs However after using the Github search I found this particular issue which has a broken link to this short discussion thread. When building the project, these directories will be internally expanded to be Because I have a shallow view on any related other features I will propose the simplest solution that fits my use case that I can think of: Add a key called:
Which supports only simple globs with Implementation-wise this would mean extending this function to not only exclude the hardcoded globs but also the user-specified ones. One downside is that in conjunction with Please let me know your input. |
Thanks @i-am-the-slime for looking into this! |
cc @thomashoneyman: we discussed this briefly when it first came up, but I don't recall the specifics of which direction we wanted to take |
I can take a thorough read later on, but a quick clarification: the registry already supports the “files” key in a manifest, so there is already an implementation we can tweak as needed. |
I'd be happy about any feedback here. Thus, a little ping. |
Right now We could support this in the registry by adding a way to exclude things from the All in all I am not sure it'd be worth adding these complications to provide direct support for this workflow that, while interesting, doesn't seem very widespread. |
It is simpler, that's for sure. However, it's a convention on the top-level directory names. There could just as well be a convention on the source file names which would only be marginally more complicated to support (e.g.
I strongly feel this feature is worth the added complexity to
What makes you say that? My googling has given me lots of proponents of this in various languages. The term "colocation" seems to be mostly used in the JS/TS worlds but I've found examples in various languages with the more modern ones even opting for support for tests within the source file itself.
|
I am generally in favor of colocation myself. In the context of this discussion we need to separate spago and the registry, as the registry is meant to support multiple package managers (including those that don't have a native understanding of colocation). For that reason we need to come up with a scheme that would allow the registry to take the following actions without using Spago:
We've so far followed NPM's lead in using the Although, since Pursuit and some The challenge then is how to make this discoverable for users; after all, if you just go ahead and colocate your test files and try to publish your library and see a sudden failure, you may have to do some digging to figure out you have to manually exclude files ending in If we want to make colocation first class in the registry in that it already understands to exclude any .purs file that ends in e.g. |
I think there are nice benefits to colocation, but what I don't like about a suffix like Also keep in mind that the reason the compiler itself supports source globs is that it's easy to reach shell/OS limits on argument length if you try to pass each file you want to compile individually. |
I think I'm missing some bigger picture knowledge here about potential package managers and what they can't do or how they're hard to maintain. I'll try to present how cheaply I think we could get this feature and maybe you can give me an example of where this will lead to a problem:
So what happens is that we build an I suggest we add a third and final step where you can specify an optional glob to exclude files from this array that we've built, e.g. something like: newGlobs today'sFileArray = do
excludedFiles <- expandGlobsCwd finallyExcludeGlobs
pure $ Array.filter (notIn excludedFiles) today'sFileArray This is the change that I see would need to happen wherever we want to support this.
I actually think this is another argument in favour of supporting colocation. With the current design there's no support for colocation yet, I can still colocate test files in my package, they'll just get distributed alongside my regular files. Somebody will notice eventually, and I'll have to change my project's setup to exclude them for a newer version of my library instead of adding some exclude glob.
Can you clarify for me where this is an actual problem? Are you saying that there are package managers that can't perform the code I showed above? Or that there's some advantage to being able to somehow only pick files from bash or something? I guess it would be harder to only pass the files that shall be published to |
If you're have a local dependency with colocations, spago (or whatever) is going to have to pass to the compiler exactly the files to include from that dependency (since it can't pass a glob for them – the package and test files both exist locally). It can't pass all of this dependency's files because its test dependencies may not be installed in the project you are depending on it from. If you do this for a lot of dependencies you will exceed the OS limit of argument lengths as I said. |
@MonoidMusician Thanks for the reply, now even I understand it!
|
I think that changing the manifest from having a We don't have to change the globs used for compilation in the case of registry-dev/app/src/App/API.purs Lines 1074 to 1084 in 30e0003
We won't even have to regenerate the manifest index in the case we change these key names because no packages in the registry are currently using the The important thing is to guarantee that you cannot exclude files via the registry-dev/app/test/App/API.purs Lines 100 to 101 in 30e0003
|
Thank you for your reply! I'm trying to find the list of files that minimally need to be there. It seems like there should be a check for this independently of exclude files (in case there just isn't a
I'm thinking there probably needs to be a In short, I'm happy to add the required tests but I need to know what these minimum files are. |
The list of always-included and always-excluded files is listed here: https://github.com/purescript/registry-dev/blob/master/SPEC.md#51-publish-a-package I think you’re right, the registry could simply warn that you are excluding an always-included file (and therefore it will be included anyway), but ideally Spago would error out. I think we should put the lists of always-included and always-excluded files into the Registry.Lib.Operation.Validation module, which is shared by Spago |
@thomashoneyman I pushed some changes that hopefully address this in my PR. Would be cool if you could tell me if it's the right thing/direction. |
Is this complete (as seen in #613)? cc: @i-am-the-slime |
We are missing the Spago implementation to shake out any issues with how it's implemented here in the registry, but it should be otherwise done. |
I think that’s tracked by #594, so I’d like to close this one if that’s ok with y’all @i-am-the-slime @f-f |
I am a big fan of colocation.
In my specific case this implies I can keep a `Spec.purs` and a `Story.purs` as descendents of `/src/`.Example
For example, I would like to be able to structure my project similarly to this
Advantages
I can see quickly which files have a corresponding test (
Sidebar
has one, butAtom
doesn't). Both have aStory
.I do not need to keep the module structure between
test
andsrc
.Thus, I can easily delete or move all files relating to some functionality.
From what I can tell, this is necessary:
*Spec.purs
)src
with more dependencies than what's specified inspago.yaml
Possible solution to 1:
Quoting @f-f on Discord:
The text was updated successfully, but these errors were encountered: