Created
November 9, 2023 21:36
-
-
Save thomashoneyman/8fc0ed115f657a591f1931ba0050829a to your computer and use it in GitHub Desktop.
solve with compilers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- | A 'DependencyIndex' enriched to include the compiler versions supported by | |
-- | each package version as a dependency. | |
newtype CompilerIndex = CompilerIndex DependencyIndex | |
-- | Associate the compiler versions supported by each package version by | |
-- | inserting them as a range in the version's dependencies. | |
associateCompilers :: Map PackageName Metadata -> DependencyIndex -> CompilerIndex | |
associateCompilers allMetadata index = CompilerIndex do | |
foldlWithIndex | |
( \package prevIndex versions -> do | |
let | |
insertPurs version existingDeps = fromMaybe existingDeps do | |
Metadata metadata <- Map.lookup package allMetadata | |
published <- Map.lookup version metadata.published | |
pursRange <- case published.compilers of | |
-- If the dependency hasn't yet had all compilers computed for it, | |
-- then we don't add it to the dependencies to avoid over- | |
-- constraining the solver. | |
Left _ -> Nothing | |
-- Otherwise, we construct a maximal range for the compilers the | |
-- indicated package version supports. | |
Right compilers -> do | |
let | |
min = Foldable1.minimum compilers | |
max = let max' = Foldable1.maximum compilers in if max' == min then Version.bumpPatch max' else max' | |
Range.mk min max | |
pure $ Map.insert purs pursRange existingDeps | |
Map.insert package (mapWithIndex insertPurs versions) prevIndex | |
) | |
Map.empty | |
index | |
-- | Solve the given dependencies using a dependency index that includes compiler | |
-- | versions, such that the solution prunes results that would fall outside | |
-- | a compiler range accepted by all dependencies. | |
solveWithCompiler :: CompilerIndex -> Map PackageName Range -> Either SolverErrors (Map PackageName Version) | |
solveWithCompiler (CompilerIndex index) required = do | |
results <- Solver.solveFull { registry: Solver.initializeRegistry index, required: Solver.initializeRequired required } | |
pure $ Map.delete purs results | |
-- The 'metadata' package is a reserved name used to record compiler versions, | |
-- so we can safely use it when working with the registry index. | |
purs :: PackageName | |
purs = unsafeFromRight $ PackageName.parse "metadata" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment