-
Notifications
You must be signed in to change notification settings - Fork 131
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
Log a warning for missing dependency versions #1321
Conversation
Hey @f-f could you please approve the workflows to run? |
Hey @f-f thank you for the detailed feedback, I've made the changes you have suggested. Summary of changes:
I have some questions about the style and conventions that you'd reccommend for purescript and I'd really appreciate your advice:
Is your preference to use
Would you also inline a large function that is only used once? For example What do you think about a function like
I have seen in some of the |
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.
Lovely! Left a few more style suggestions but otherwise this is good to merge
src/Spago/Command/Fetch.purs
Outdated
let list k v = " - " <> PackageName.print k <> ": " <> v | ||
|
||
logWarn <<< joinWith "\n" $ join | ||
[ [ "The following package versions do not exist in your package set:" ] | ||
, (\{ name, requested } -> list name $ Range.print requested) <$> missing | ||
, [ "", "Proceeding with the latest available versions instead:" ] | ||
, (\{ name, resolved } -> list name $ Version.print resolved) <$> missing | ||
] |
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.
We have facilities for logging on multiple lines: logWarn
(and the rest of the logging functions) take a Loggable a
, which includes arrays.
So the next function could read like this:
let list k v = " - " <> PackageName.print k <> ": " <> v | |
logWarn <<< joinWith "\n" $ join | |
[ [ "The following package versions do not exist in your package set:" ] | |
, (\{ name, requested } -> list name $ Range.print requested) <$> missing | |
, [ "", "Proceeding with the latest available versions instead:" ] | |
, (\{ name, resolved } -> list name $ Version.print resolved) <$> missing | |
] | |
let listItem k v = toDoc $ " - " <> PackageName.print k <> ": " <> v | |
logWarn $ | |
[ toDoc "The following package versions do not exist in your package set:" ] | |
<> map (\{ name, requested } -> list name $ Range.print requested) missing | |
[ Log.break, toDoc "Proceeding with the latest available versions instead:" ] | |
<> map (\{ name, resolved } -> list name $ Version.print resolved) missing |
(I didn't test this code so might not be exactly right, but you'll find this pattern all over the codebase if you search for toDoc
)
src/Spago/Command/Fetch.purs
Outdated
resolvePackageVersionsToRanges registry = Map.toUnfoldable >>> Array.foldl | ||
( \acc (Tuple name requested) -> | ||
case (Map.lookup name registry) of | ||
Just (RegistryVersion resolved) -> Array.snoc acc { name, requested, resolved } | ||
_ -> acc | ||
) | ||
[] |
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.
This can be condensed with mapMaybeWithKey
(and let's move it to the let
block as well):
resolvePackageVersionsToRanges registry = Map.toUnfoldable >>> Array.foldl | |
( \acc (Tuple name requested) -> | |
case (Map.lookup name registry) of | |
Just (RegistryVersion resolved) -> Array.snoc acc { name, requested, resolved } | |
_ -> acc | |
) | |
[] | |
resolvePackageVersionsToRanges registry = Array.fromFoldable | |
<<< Map.values | |
<<< Map.mapMaybeWithKey \name requested -> | |
Map.lookup name registry <#> \(RegistryVersion resolved) -> | |
{ name, requested, resolved } |
@JoelLefkowitz to answer to your excellent points above: (Note: I'm happy to state my style preferences, but keep in mind that these are in fact preferences about how I like the codebases I contribute to. My main goal is to make code easy to read/understand/reason about, but someone else might have different preferences)
To me yes,
Yes, because functions that are used only once are generally situational so it makes sense to not expose them to the broader scope, or the rest of the code might be tempted to use them. If they are in the inner scope one has to think before moving the function around. We do this a lot in the Spago codebase, e.g. see here
Type annotations in let blocks are as useful as type annotations at the top level, as they help the compiler to typecheck, and provide documentation to future readers. We do this a lot as well, e.g. see here
A lot of that comes down to how generic the function is. Things like |
Thanks @f-f I've constructed the warning message with the Loggable class now and I've taken some of the repetition out. For mapping the intermediate value from Thank you for explaining your style preferences they're really insightful, especially regarding scoping functions. It resonates strongly with me to prioritise readability and I'd be quite interested to read the threads on discord that discuss these ideas. |
This is great - thank you! |
Description of the change
Fixes #1313 by adding a warning message when the installed versions of packages are outside the specified dependency ranges.
Checklist:
README
Tests
Adds a test spec:
test/Spago/Install.purs > Spec.it "warns when specified dependency versions do not exist"
that creates a workspace and adds some packages with ranges that exceed the registry's versions. Asserts that a warning message is shown.Implementation
Adds a type
VersionResolution
to map the requested to the resolved versions for each package:In
src/Spago/Command/Fetch.purs
the versions are resolved and any missing versions log a warning: