Skip to content

Instantly share code, notes, and snippets.

@thomashoneyman
Created November 9, 2023 21:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomashoneyman/8fc0ed115f657a591f1931ba0050829a to your computer and use it in GitHub Desktop.
Save thomashoneyman/8fc0ed115f657a591f1931ba0050829a to your computer and use it in GitHub Desktop.
solve with compilers
-- | 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