Skip to content

One shot install plan #1701

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

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
make-install-plan
- rename from install-plan
- cabal-compatible command line options (to some extent)
  • Loading branch information
andreabedini committed Sep 19, 2022
commit 2451eb969cc76c37b493594fc14f94e8450eefaa
22 changes: 6 additions & 16 deletions lib/call-cabal-project-to-nix.nix
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ let
# check first for cabal configure failure.
"maybeJson" # The `plan.json` file generated by cabal and used for `plan-to-nix` input
"maybeFreeze" # The `cabal.project.freeze` file created by `cabal v2-freeze`
"newInstallPlan"
"cabalFileRevisions"
];
passthru =
let
Expand All @@ -500,7 +500,7 @@ let
'';
cabal-file-revisions = evalPackages.runCommand (nameAndSuffix "cabal-file-revisions") {} ''
${checkCabalConfigure}
cp -r ${plan-nix.newInstallPlan}/cabal-files $out
cp -r ${plan-nix.cabalFileRevisions} $out
'';
};
} ''
Expand Down Expand Up @@ -564,20 +564,7 @@ let
index-state = cached-index-state;
sha256 = index-sha256-found;
}
} install-plan . $newInstallPlan

HOME=${
# This creates `.cabal` directory that is as it would have
# been at the time `cached-index-state`. We may include
# some packages that will be excluded by `index-state-found`
# which is used by cabal (cached-index-state >= index-state-found).
dotCabal {
inherit cabal-install nix-tools extra-hackage-tarballs;
extra-hackage-repos = fixedProject.repos;
index-state = cached-index-state;
sha256 = index-sha256-found;
}
} cabal v2-freeze ${
} make-install-plan ${
# Setting the desired `index-state` here in case it is not
# in the cabal.project file. This will further restrict the
# packages used by the solver (cached-index-state >= index-state-found).
Expand Down Expand Up @@ -626,6 +613,9 @@ let
# Make the plan.json file available in case we need to debug plan-to-nix
cp $tmp${subDir'}/dist-newstyle/cache/plan.json $maybeJson

# Make the revised cabal files available
cp -r $tmp${subDir'}/dist-newstyle/cabal-files $cabalFileRevisions

# Remove the non nix files ".project" ".cabal" "package.yaml" files
# as they should not be in the output hash (they may change slightly
# without affecting the nix).
Expand Down
7 changes: 3 additions & 4 deletions materialized/ghc8107/nix-tools/.plan.nix/nix-tools.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion materialized/ghc8107/nix-tools/default.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE NamedFieldPuns #-}

import Control.Monad (join)
import qualified Data.ByteString.Lazy as BSL
import Data.Foldable (for_)
import Distribution.Client.Config (getCabalDir)
import Distribution.Client.DistDirLayout
( CabalDirLayout,
DistDirLayout (distProjectCacheFile),
DistDirLayout (..),
defaultDistDirLayout,
mkCabalDirLayout,
)
import Distribution.Client.GlobalFlags
import Distribution.Client.HttpUtils (configureTransport)
import qualified Distribution.Client.InstallPlan as InstallPlan
import Distribution.Client.NixStyleOptions (NixStyleFlags (..), defaultNixStyleFlags, nixStyleOptions)
import Distribution.Client.ProjectConfig
import Distribution.Client.ProjectPlanOutput (writePlanExternalRepresentation)
import Distribution.Client.ProjectPlanning
Expand All @@ -25,42 +25,53 @@ import Distribution.Client.ProjectPlanning
rebuildInstallPlan,
rebuildProjectConfig,
)
import Distribution.Client.Setup
import Distribution.Compat.Directory (makeAbsolute)
import Distribution.Package (pkgName)
import Distribution.Parsec (eitherParsec)
import Distribution.Pretty (prettyShow)
import Distribution.Simple.Command
import Distribution.Simple.Flag
import qualified Distribution.Simple.Utils as Cabal
import Distribution.Verbosity (Verbosity, moreVerbose)
import qualified Distribution.Verbosity as Verbosity
import Options.Applicative
import System.Environment (getArgs)
import System.FilePath

main :: IO ()
main =
join $
execParser $
info
(optionsParser <**> helper)
(fullDesc <> progDesc "Extracts a cabal install plan")
where
optionsParser = do
verbosity <-
option
(eitherReader eitherParsec)
( long "verbosity"
<> metavar "VERBOSITY"
<> value Verbosity.normal
<> help "Verbosity"
)
inputDir <- optional (argument str (metavar "INPUT-DIR"))
outputDir <- argument str (metavar "OUTPUT-DIR" <> value "./out")
pure $ doMain verbosity inputDir outputDir

doMain :: Verbosity -> Maybe FilePath -> [Char] -> IO ()
doMain verbosity inputDir outputDir = do
Right projectRoot <- findProjectRoot inputDir Nothing
let distDirLayout = defaultDistDirLayout projectRoot (Just outputDir)
main = do
args <- getArgs
case commandParseArgs cmdUI True args of
CommandHelp help -> putStrLn (help "something")
CommandList opts -> putStrLn $ "commandList" ++ show opts
CommandErrors errs -> putStrLn $ "commandErrors: " ++ show errs
CommandReadyToGo (mkflags, _commandParse) ->
let globalFlags = defaultGlobalFlags
flags@NixStyleFlags {configFlags} = mkflags (commandDefaultFlags cmdUI)
verbosity = fromFlagOrDefault Verbosity.normal (configVerbosity configFlags)
cliConfig = commandLineFlagsToProjectConfig globalFlags flags mempty
in installPlanAction verbosity cliConfig

cmdUI :: CommandUI (NixStyleFlags ())
cmdUI =
CommandUI
{ commandName = "",
commandSynopsis = "Makes an install-plan",
commandUsage = ("Usage: " ++),
commandDescription = Nothing,
commandNotes = Nothing,
commandDefaultFlags = defaultNixStyleFlags (),
commandOptions = nixStyleOptions (const [])
}

installPlanAction :: Verbosity -> ProjectConfig -> IO ()
installPlanAction verbosity cliConfig = do
let ProjectConfigShared {projectConfigDistDir, projectConfigProjectFile} = projectConfigShared cliConfig
let mProjectFile = flagToMaybe projectConfigProjectFile
let mdistDirectory = flagToMaybe projectConfigDistDir

Right projectRoot <- findProjectRoot Nothing mProjectFile

let distDirLayout = defaultDistDirLayout projectRoot mdistDirectory

httpTransport <- configureTransport verbosity mempty mempty

Expand All @@ -71,7 +82,7 @@ doMain verbosity inputDir outputDir = do
(moreVerbose verbosity)
httpTransport
distDirLayout
mempty
cliConfig

cabalDirLayout <- cabalDirLayoutFromProjectConfig projectConfig

Expand All @@ -83,18 +94,16 @@ doMain verbosity inputDir outputDir = do
(_improvedPlan, elaboratedPlan, elaboratedSharedConfig, _tis, _at) <-
rebuildInstallPlan verbosity distDirLayout cabalDirLayout projectConfig localPackages

putStrLn $ "Writing detailed plan to " ++ outputDir

Cabal.notice verbosity $ "Writing plan.json to" ++ distProjectCacheFile distDirLayout "plan.json"
Cabal.notice verbosity $ "Writing plan.json to " ++ distProjectCacheFile distDirLayout "plan.json"
writePlanExternalRepresentation distDirLayout elaboratedPlan elaboratedSharedConfig

let cabalFreezeFile = outputDir </> "cabal.project.freeze"
Cabal.notice verbosity $ "Wrote freeze file: " ++ cabalFreezeFile
let cabalFreezeFile = distProjectFile distDirLayout "freeze"
Cabal.notice verbosity $ "Wrote freeze file to " ++ cabalFreezeFile
writeProjectConfigFile cabalFreezeFile projectConfig

let cabalFilesDir = outputDir </> "cabal-files"
let cabalFilesDir = distDirectory distDirLayout </> "cabal-files"
Cabal.createDirectoryIfMissingVerbose verbosity True cabalFilesDir
Cabal.notice verbosity $ "Writing cabal files to" ++ cabalFilesDir
Cabal.notice verbosity $ "Writing cabal files to " ++ cabalFilesDir

let ecps = [ecp | InstallPlan.Configured ecp <- InstallPlan.toList elaboratedPlan, not $ elabLocalToProject ecp]

Expand All @@ -115,7 +124,6 @@ cabalDirLayoutFromProjectConfig
projectConfigShared = ProjectConfigShared {projectConfigStoreDir}
} = do
cabalDir <- getCabalDir

let mlogsDir = flagToMaybe projectConfigLogsDir
mstoreDir <- sequenceA $ makeAbsolute <$> flagToMaybe projectConfigStoreDir
return $ mkCabalDirLayout cabalDir mstoreDir mlogsDir
7 changes: 3 additions & 4 deletions nix-tools/nix-tools.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -202,15 +202,14 @@ executable cabal-name
hs-source-dirs: cabal-name
default-language: Haskell2010

executable install-plan
executable make-install-plan
ghc-options: -Wall
main-is: InstallPlan.hs
main-is: MakeInstallPlan.hs
build-depends: base
, bytestring
, filepath
, Cabal >= 3.8
, Cabal-syntax >= 3.8
, cabal-install >= 3.8
, optparse-applicative
hs-source-dirs: install-plan
hs-source-dirs: make-install-plan
default-language: Haskell2010
2 changes: 1 addition & 1 deletion overlays/bootstrap.nix
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ in {
"truncate-index"
"stack-repos"
"cabal-name"
"install-plan"
"make-install-plan"
]) ++ [
(project.getComponent "hpack:exe:hpack")
];
Expand Down