Skip to content

Commit

Permalink
Prefer non pre-existing packages
Browse files Browse the repository at this point in the history
When choosing between two packages in the plan with the same version number, choose the non pre-existing package.
  • Loading branch information
hamishmack committed Jun 17, 2024
1 parent be65bfc commit b487c93
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions nix-tools/nix-tools/plan2nix/Plan2Nix.hs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ writeDoc file doc =
hPutDoc handle doc
hClose handle

-- PackageKey is used when selecting which version is the most recent
-- when to deduplicate the plan.
-- By including PackageType as well as version we can select the
-- NonPreExisting version of the package if the versions match.
data PackageType = PreExisting | NotPreExisting deriving (Eq, Ord)
data PackageKey = PackageKey Version PackageType deriving (Eq, Ord)

plan2nix :: Args -> Plan -> IO NExpr
plan2nix args Plan { packages, extras, components, compilerVersion, compilerPackages } = do
-- TODO: this is an aweful hack and expects plan-to-nix to be
Expand Down Expand Up @@ -260,13 +267,19 @@ value2plan plan = Plan { packages, components, extras, compilerVersion, compiler
filterInstallPlan :: (Value -> Maybe b) -> HashMap Text b
filterInstallPlan f = fmap snd .
-- If the same package occurs more than once, choose the latest
Map.fromListWith (\a b -> if parseVersion (fst a) > parseVersion (fst b) then a else b)
$ mapMaybe (\pkg -> (,) (pkg ^. key "pkg-name" . _String) . (pkg ^. key "pkg-version" . _String,) <$> f pkg)
Map.fromListWith (\a b -> if fst a > fst b then a else b)
$ mapMaybe (\pkg -> (,) (pkg ^. key "pkg-name" . _String) . (getPackageKey pkg,) <$> f pkg)
$ Vector.toList (plan ^. key "install-plan" . _Array)

parseVersion :: Text -> Version
parseVersion s = fromMaybe (error $ "Unable to parse version " <> show s) . simpleParsec $ Text.unpack s

getPackageKey :: Value -> PackageKey
getPackageKey pkg = PackageKey (parseVersion (pkg ^. key "pkg-version" . _String)) (
if pkg ^. key "type" . _String == "pre-existing"
then PreExisting
else NotPreExisting)

-- Set of components that are included in the plan.
components :: HashSet Text
components =
Expand Down

0 comments on commit b487c93

Please sign in to comment.