Skip to content
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

Improve usability on 'ghcup config add-release-channel' #781

Merged
merged 3 commits into from
Feb 19, 2023
Merged

Conversation

hasufell
Copy link
Member

Fixes #751 (or so I hope).

@andreasabel


Test:

ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/develop/ghcup-vanilla-0.0.7.yaml
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/develop/ghcup-vanilla-0.0.7.yaml

Result:

[ Error ] [GHCup-00350] Duplicate release channel detected when adding:
[ ...   ]   https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-vanilla-0.0.7.yaml
[ ...   ] Giving up. You can use '--force' to remove and append the duplicate URI (this may change order/semantics).

@hasufell hasufell added this to the 0.1.19.1 milestone Feb 12, 2023
Comment on lines +231 to +238
-- appends the element to the end of the list, but also removes it from the existing list
appendUnique :: Eq a => [a] -> a -> [a]
appendUnique xs' e = go xs'
where
go [] = [e]
go (x:xs)
| x == e = go xs -- skip
| otherwise = x : go xs
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the meat.

r <- runE @'[DuplicateReleaseChannel] $ do
case urlSource settings of
AddSource xs -> do
when (not force && Right uri `elem` xs) $ throwE (DuplicateReleaseChannel uri)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we error

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, if I understand correctly, addition sequence a.b.a will now error unless forced.
But also a.a will error, but this is in effect the same as a, because the action of adding a fixed channel at the end is idempotent (if we ignore the extra entry in xs).
I am a bit worried about the error in such don't-care situations. This could lead to regressions for uses of ghcup in scripts.
But I understand that just ignoring duplicate additions with a warning (unless force) is also not a backwards-compatible solution, and even worse than a hard error.

Could one stick with a warning just in case the last channel is added again? In these cases we know that adding it again is redundant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think we can skip error if the last element equals the new element and simply do nothing.

lift $ doConfig (defaultUserSettings { uUrlSource = Just $ AddSource [Right uri] })
pure ()
OwnSource xs -> do
when (not force && Right uri `elem` xs) $ throwE (DuplicateReleaseChannel uri)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

@cartazio
Copy link

conceptually, is the configuration a Map from keys to config values wrapped in the First Monoid https://hackage.haskell.org/package/base-4.17.0.0/docs/Data-Monoid.html#t:First by default, and the --force flag would correspond with the Last monoid? https://hackage.haskell.org/package/base-4.17.0.0/docs/Data-Monoid.html#t:Last

roughly Map ConfigName (First ConfigValue)?

@hasufell
Copy link
Member Author

@cartazio no idea. Never used those.

--force does not have an effect on which keys in the nested Maps are overwritten, it only changes the overwrite order.

Say:

  • A: ghcup-vanilla-0.0.7.yaml
  • B: ghcup-0.0.7.yaml

Both have duplicate keys (GHC versions).

If you have configured the order [ A, B ], then B takes precedence.

If you now say add A with current GHCup, you get [ A, B, A ] which is the same as [ B, A ] just more inefficient.

With the new patch, ghcup will error out.

With --force, you'll get [ B, A ] (as opposed to [ A, B, A ]).

Does that make sense?

@cartazio
Copy link

cartazio commented Feb 17, 2023 via email

@hasufell
Copy link
Member Author

hasufell commented Feb 17, 2023

What’s the current shadowing override rule on conflict and what’s the new one?

Duplicate keys are overwritten right biased, no matter whether you use --force or not. --force just changes the index of one of the elements in the list we union over.

@hasufell hasufell merged commit e57a8ab into master Feb 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Should ghcup config add-release-channel build a set rather than a list?
3 participants