Skip to content

Commit c4d003b

Browse files
committed
Add --world-full and --preserved-rebuild
--world-full is an alias for `--world -- --newuse --with-bdeps=y`. This is added for convenience since these flags often times help portage get to a state where `emerge --depclean` can be run. --preserved-rebuild runs basic mode, but appending @preserved-rebuild to the package list. Also, this mode will loop until the broken list is unchanged between runs (the same looping behavior as --mode=reinstall-atoms). This is added for convenience since @preserved-rebuild often times catches extra breakages, such as haskell executables with no library. The hope here is that these options will allow a complete fix of the system with one command: haskell-updater --world-full && \ emerge --depclean && \ haskell-updater --preserved-rebuild Signed-off-by: hololeap <[email protected]>
1 parent 69ba2ad commit c4d003b

File tree

4 files changed

+151
-45
lines changed

4 files changed

+151
-45
lines changed

Distribution/Gentoo/CmdLine.hs

+63-15
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,17 @@ import Distribution.Gentoo.Types
2828
import qualified Distribution.Gentoo.Types.HUMode as Mode
2929
import Output
3030

31+
-- | Process arguments from the command line. Returns an error string if the
32+
-- user provided incorrect or unknown options.
3133
parseArgs :: PkgManager -> RawPMArgs -> Either String (CmdLineArgs, RawPMArgs)
3234
parseArgs defPM args = case getOpt' Permute options args of
3335
(_, _, _, errs@(_:_)) -> Left $ unwords $ "Errors in arguments:" : errs
3436
(_, _, unk@(_:_), _) -> Left $ unwords $ "Unknown options:" : unk
3537
(fs, raw, _, _) ->
3638
(,raw) <$> foldr (>=>) pure fs (defCmdLineArgs defPM)
3739

40+
-- | Parse processed command line arguments into a 'Mode.HUMode'. Returns an
41+
-- error string if the user supplied non-compatible option combinations.
3842
mkHUMode :: CmdLineArgs -> RawPMArgs -> Either String Mode.HUMode
3943
mkHUMode cmdLine raw
4044
| cmdLineHelp cmdLine = pure Mode.HelpMode
@@ -52,39 +56,73 @@ mkHUMode cmdLine raw
5256
pm@(InvalidPM _) -> Left $
5357
"Invalid package manager in mkHUMode: " ++ show pm
5458

59+
-- Logic for parsing modes for non-portage package managers
5560
mkMode :: RunMode -> Either String Mode.RunMode
5661
mkMode = \case
5762
BasicMode -> Mode.BasicMode <$> mkTarget (cmdLineTarget cmdLine)
5863
ListMode -> Mode.ListMode <$> mkTarget (cmdLineTarget cmdLine)
5964
ReinstallAtomsMode -> Left
6065
"reinstall-atoms mode is only supported by the portage package manager"
6166

62-
mkPortageMode
63-
:: RunMode
64-
-> Either String (Either Mode.RunMode Mode.ReinstallAtomsMode)
65-
mkPortageMode = \case
66-
BasicMode -> Left . Mode.BasicMode <$> mkTarget (cmdLineTarget cmdLine)
67-
ListMode -> Left . Mode.ListMode <$> mkTarget (cmdLineTarget cmdLine)
68-
ReinstallAtomsMode -> Right . Mode.ReinstallAtomsMode
69-
<$> mkRATarget (cmdLineTarget cmdLine)
70-
67+
-- Logic for parsing targets for non-portage package managers
7168
mkTarget :: Either CustomTargets BuildTarget -> Either String Mode.Target
7269
mkTarget = \case
7370
Right OnlyInvalid -> Right Mode.OnlyInvalid
7471
Right AllInstalled -> Right Mode.AllInstalled
72+
Right PreservedRebuild -> Left $
73+
"preserved-rebuild target is only supported by the portage \
74+
\package manager"
7575
Right WorldTarget -> Left
7676
"world target is only supported in reinstall-atoms mode"
7777
Left _ -> Left
7878
"custom targets are only supported in reinstall-atoms mode"
7979

80-
mkRATarget
80+
-- Logic for parsing modes for portage
81+
mkPortageMode
82+
:: RunMode
83+
-> Either String Mode.PortageMode
84+
mkPortageMode = \case
85+
BasicMode -> Mode.PortageBasicMode
86+
<$> mkPortageBasicTarget (cmdLineTarget cmdLine)
87+
ListMode -> Mode.PortageListMode
88+
<$> mkPortageTarget (cmdLineTarget cmdLine)
89+
ReinstallAtomsMode -> Mode.ReinstallAtomsMode
90+
<$> mkPortageRATarget (cmdLineTarget cmdLine)
91+
92+
-- Logic for parsing targets for portage's basic mode
93+
mkPortageBasicTarget
94+
:: Either CustomTargets BuildTarget
95+
-> Either String (Either Mode.PortageBasicTarget Mode.Target)
96+
mkPortageBasicTarget = \case
97+
Right PreservedRebuild -> Right $ Left Mode.PreservedRebuild
98+
targ -> Right <$> mkPortageTarget targ
99+
100+
-- Logic for parsing targets for portage's reinstall-atoms mode
101+
mkPortageRATarget
81102
:: Either CustomTargets BuildTarget
82103
-> Either String (Either Mode.Target Mode.ReinstallAtomsTarget)
83-
mkRATarget = Right . \case
84-
Right OnlyInvalid -> Left Mode.OnlyInvalid
85-
Right AllInstalled -> Left Mode.AllInstalled
86-
Right WorldTarget -> Right Mode.WorldTarget
87-
Left cts -> Right $ Mode.CustomTargets cts
104+
mkPortageRATarget = \case
105+
Right WorldTarget -> Right $ Right $
106+
if cmdLineWorldFull cmdLine
107+
then Mode.WorldFullTarget
108+
else Mode.WorldTarget
109+
Left cts -> Right $ Right $ Mode.CustomTargets cts
110+
targ -> Left <$> mkPortageTarget targ
111+
112+
-- Logic for parsing targets for portage's list mode; also common logic
113+
-- for parsing targets, between portage's basic and reinstall-atoms modes
114+
mkPortageTarget
115+
:: Either CustomTargets BuildTarget
116+
-> Either String Mode.Target
117+
mkPortageTarget = \case
118+
Right OnlyInvalid -> Right Mode.OnlyInvalid
119+
Right AllInstalled -> Right Mode.AllInstalled
120+
Right PreservedRebuild -> Left
121+
"preserved-rebuild target is only supported in basic mode"
122+
Right WorldTarget -> Left
123+
"world target is only supported in reinstall-atoms mode"
124+
Left _ -> Left
125+
"custom targets are only supported in reinstall-atoms mode"
88126

89127
runModifier :: RunModifier
90128
runModifier = RM
@@ -140,6 +178,16 @@ options =
140178
) $ "alias for --package-manager=portage"
141179
++ " \\\n --target=" ++ argString WorldTarget
142180
++ " \\\n --mode=" ++ argString ReinstallAtomsMode
181+
, Option [] ["world-full"]
182+
(naUpdate $ \c -> updateTarget (Right WorldTarget) c
183+
{ cmdLinePkgManager = Portage
184+
, cmdLineMode = ReinstallAtomsMode
185+
, cmdLineWorldFull = True
186+
}
187+
) $ "alias for --world -- --newuse --with-bdeps=y"
188+
, Option [] ["preserved-rebuild"]
189+
(naUpdate $ updateTarget (Right PreservedRebuild))
190+
$ "alias for --target=" ++ argString PreservedRebuild
143191
, Option ['T'] ["custom-target"]
144192
(ReqArg
145193
(\s c -> pure $ updateTarget (Left s) c

Distribution/Gentoo/CmdLine/Types.hs

+8
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ data CmdLineArgs = CmdLineArgs
4444
, cmdLineMode :: RunMode
4545
, cmdLineVerbosity :: Verbosity
4646
, cmdLineHelp :: Bool
47+
, cmdLineWorldFull :: Bool
4748
} deriving (Show, Eq, Ord)
4849

4950
defCmdLineArgs :: PkgManager -> CmdLineArgs
@@ -57,11 +58,13 @@ defCmdLineArgs defPM = CmdLineArgs
5758
BasicMode
5859
Normal
5960
False
61+
False
6062

6163
data BuildTarget
6264
= OnlyInvalid -- ^ Default
6365
| AllInstalled -- ^ Rebuild every haskell package
6466
| WorldTarget -- ^ Target @world portage set
67+
| PreservedRebuild -- ^ Append @preserved-rebuild set
6568
deriving (Eq, Ord, Show, Read, Enum, Bounded)
6669

6770
data RunMode
@@ -106,6 +109,11 @@ instance CmdlineOpt BuildTarget where
106109
, Just $ "@world set (only valid with portage package\n"
107110
++ "manager and reinstall-atoms mode)"
108111
)
112+
argInfo PreservedRebuild =
113+
( "preserved-rebuild"
114+
, Just $ "Append @preserved-rebuild set (only valid with\n"
115+
++ "portage package manager and basic mode)"
116+
)
109117

110118
optName _ = "target"
111119
optDescription _ =

Distribution/Gentoo/Types/HUMode.hs

+35-12
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ module Distribution.Gentoo.Types.HUMode
1717
, runMode
1818
, Target(..)
1919
, getTarget
20-
, ReinstallAtomsMode(..)
20+
, PortageMode(..)
21+
, PortageBasicTarget(..)
2122
, ReinstallAtomsTarget(..)
2223
, getLoopType
2324
, getExtraRawArgs
@@ -32,7 +33,7 @@ data HUMode
3233
deriving (Eq, Ord, Show)
3334

3435
data PkgManager
35-
= Portage (Either RunMode ReinstallAtomsMode)
36+
= Portage PortageMode
3637
| PkgCore RunMode
3738
| Paludis RunMode
3839
| CustomPM String RunMode
@@ -48,17 +49,23 @@ data Target
4849
| AllInstalled
4950
deriving (Eq, Ord, Show)
5051

51-
newtype ReinstallAtomsMode
52-
= ReinstallAtomsMode (Either Target ReinstallAtomsTarget)
52+
data PortageMode
53+
= PortageBasicMode (Either PortageBasicTarget Target)
54+
| PortageListMode Target
55+
| ReinstallAtomsMode (Either Target ReinstallAtomsTarget)
56+
deriving (Eq, Ord, Show)
57+
58+
data PortageBasicTarget = PreservedRebuild
5359
deriving (Eq, Ord, Show)
5460

5561
data ReinstallAtomsTarget
5662
= WorldTarget
63+
| WorldFullTarget
5764
| CustomTargets CustomTargets
5865
deriving (Eq, Ord, Show)
5966

60-
runMode :: PkgManager -> Either RunMode ReinstallAtomsMode
61-
runMode (Portage rm) = rm
67+
runMode :: PkgManager -> Either RunMode PortageMode
68+
runMode (Portage rm) = Right rm
6269
runMode (PkgCore rm) = Left rm
6370
runMode (Paludis rm) = Left rm
6471
runMode (CustomPM _ rm) = Left rm
@@ -74,23 +81,39 @@ getTarget (ListMode t) = t
7481
-- sense.
7582
getLoopType :: PkgManager -> LoopType
7683
getLoopType = \case
77-
-- Even @--mode=reinstall-atoms@ should not loop if @--target=all@ is set
78-
Portage (Right (ReinstallAtomsMode (Left AllInstalled))) -> NoLoop
79-
Portage (Right (ReinstallAtomsMode _)) -> UntilNoChange
80-
Portage (Left mode) -> fromRunMode mode
84+
-- @--mode=reinstall-atoms@ should not loop if @--target=all@ is set
85+
Portage (ReinstallAtomsMode (Left AllInstalled)) -> NoLoop
86+
87+
-- otherwise, it should always use UntilNoChange
88+
Portage (ReinstallAtomsMode _) -> UntilNoChange
89+
90+
-- @--target=preserved-rebuild@ should use UntilNoChange
91+
Portage (PortageBasicMode (Left PreservedRebuild)) -> UntilNoChange
92+
93+
-- The rest follow a standard pattern
94+
Portage (PortageBasicMode (Right t)) -> fromTarget t
95+
Portage (PortageListMode _) -> NoLoop
8196
PkgCore mode -> fromRunMode mode
8297
Paludis mode -> fromRunMode mode
8398
CustomPM _ mode -> fromRunMode mode
8499
where
85100
fromRunMode :: RunMode -> LoopType
86101
fromRunMode = \case
87-
BasicMode _ -> UntilNoPending
102+
BasicMode t -> fromTarget t
88103
ListMode _ -> NoLoop
89104

105+
fromTarget :: Target -> LoopType
106+
fromTarget = \case
107+
OnlyInvalid -> UntilNoPending
108+
AllInstalled -> NoLoop
109+
90110
-- | Convert from the @haskell-updater@ ADT to 'ExtraRawArgs', hard-coded extra
91111
-- arguments that will be passed to the package manager.
92112
--
93113
-- Takes a 'PkgManager' as 'RunMode' is the only mode which runs a package
94114
-- manager.
95115
getExtraRawArgs :: PkgManager -> ExtraRawArgs
96-
getExtraRawArgs _ = ExtraRawArgs [] -- currently unused feature
116+
getExtraRawArgs = ExtraRawArgs . \case
117+
Portage (ReinstallAtomsMode (Right WorldFullTarget)) ->
118+
["--newuse", "--with-bdeps=y"]
119+
_ -> []

Main.hs

+45-18
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,18 @@ runUpdater rm pkgMgr userArgs = do
8484
systemInfo rm pkgMgr userArgs
8585
(ps, ts, bps) <- getPackageState v pkgMgr
8686
case runMode pkgMgr of
87-
Left (ListMode _) -> do
88-
mapM_ (putStrLn . printPkg) (getPkgs ps)
89-
success v "done!"
87+
Left (ListMode _) -> listPkgs ps
88+
Right (PortageListMode _) -> listPkgs ps
9089
_ -> case getLoopType pkgMgr of
9190
UntilNoPending -> loopUntilNoPending ps ts bps Seq.empty
9291
UntilNoChange -> loopUntilNoChange ps ts bps Seq.empty
9392
NoLoop -> buildPkgs rm rawArgs ps ts bps >>= exitWith
9493
success v "done!"
9594
where
96-
v = verbosity rm
95+
listPkgs :: PendingPackages -> IO ()
96+
listPkgs ps = do
97+
mapM_ (putStrLn . printPkg) (getPkgs ps)
98+
success v "done!"
9799

98100
loopUntilNoPending :: UpdaterLoop
99101
loopUntilNoPending ps ts bps hist
@@ -125,6 +127,7 @@ runUpdater rm pkgMgr userArgs = do
125127
die "Updater stuck in the loop and can't progress"
126128

127129
rawArgs = getExtraRawArgs pkgMgr
130+
v = verbosity rm
128131

129132
-- | Determines which function 'buildPkgs' will run to get the package-manager
130133
-- command.
@@ -141,11 +144,13 @@ getPackageState
141144
-> IO (PendingPackages, Set.Set Types.Target, BuildPkgs)
142145
getPackageState v pkgMgr =
143146
case runMode pkgMgr of
144-
Left mode -> do
145-
p <- case getTarget mode of
146-
OnlyInvalid -> InvalidPending <$> getInvalid
147-
AllInstalled -> AllPending <$> getAll
148-
pure (p, Set.empty, BuildNormal pkgMgr)
147+
Left mode -> fromRunMode mode
148+
Right (PortageBasicMode (Left PreservedRebuild)) -> do
149+
p <- InvalidPending <$> getInvalid
150+
let s = Set.singleton $ CustomTarget "@preserved-rebuild"
151+
pure (p, s, BuildNormal pkgMgr)
152+
Right (PortageBasicMode (Right targ)) -> fromRunMode (BasicMode targ)
153+
Right (PortageListMode targ) -> fromRunMode (ListMode targ)
149154
Right (ReinstallAtomsMode targ) -> do
150155
aps <- getAll
151156
(p,ts) <- case targ of
@@ -158,10 +163,20 @@ getPackageState v pkgMgr =
158163
ips <- getInvalid
159164
let ts = case t of
160165
WorldTarget -> Set.singleton (CustomTarget "@world")
166+
WorldFullTarget -> Set.singleton (CustomTarget "@world")
161167
CustomTargets cts -> Set.fromList (CustomTarget <$> cts)
162168
pure (InvalidPending ips, ts)
163169
pure (p, ts, BuildRAMode aps)
164170
where
171+
fromRunMode
172+
:: RunMode
173+
-> IO (PendingPackages, Set.Set Types.Target, BuildPkgs)
174+
fromRunMode mode = do
175+
p <- case getTarget mode of
176+
OnlyInvalid -> InvalidPending <$> getInvalid
177+
AllInstalled -> AllPending <$> getAll
178+
pure (p, Set.empty, BuildNormal pkgMgr)
179+
165180
getInvalid = do
166181
say v "Searching for packages installed with a different version of GHC."
167182
say v ""
@@ -279,25 +294,37 @@ systemInfo rm pkgMgr rawArgs = do
279294
v = verbosity rm
280295

281296
(m, ts) = case runMode pkgMgr of
282-
Left mode -> case mode of
283-
BasicMode OnlyInvalid ->
284-
(CmdLine.BasicMode, argString CmdLine.OnlyInvalid)
285-
BasicMode AllInstalled ->
286-
(CmdLine.BasicMode, argString CmdLine.AllInstalled)
287-
ListMode OnlyInvalid ->
288-
(CmdLine.ListMode, argString CmdLine.OnlyInvalid)
289-
ListMode AllInstalled ->
290-
(CmdLine.ListMode, argString CmdLine.AllInstalled)
297+
Left mode -> printRunMode mode
298+
Right (PortageBasicMode (Left PreservedRebuild)) ->
299+
(CmdLine.BasicMode, argString CmdLine.PreservedRebuild)
300+
Right (PortageBasicMode (Right targ)) ->
301+
printRunMode (BasicMode targ)
302+
Right (PortageListMode targ) ->
303+
printRunMode (ListMode targ)
291304
Right (ReinstallAtomsMode targ) -> case targ of
292305
Left OnlyInvalid ->
293306
(CmdLine.ReinstallAtomsMode, argString CmdLine.OnlyInvalid)
294307
Left AllInstalled ->
295308
(CmdLine.ReinstallAtomsMode, argString CmdLine.AllInstalled)
296309
Right WorldTarget ->
297310
(CmdLine.ReinstallAtomsMode, argString CmdLine.WorldTarget)
311+
Right WorldFullTarget ->
312+
(CmdLine.ReinstallAtomsMode, unwords
313+
[argString CmdLine.WorldTarget, "(full)"])
298314
Right (CustomTargets cts) ->
299315
(CmdLine.ReinstallAtomsMode, unwords cts)
300316

317+
printRunMode :: RunMode -> (CmdLine.RunMode, String)
318+
printRunMode = \case
319+
BasicMode OnlyInvalid ->
320+
(CmdLine.BasicMode, argString CmdLine.OnlyInvalid)
321+
BasicMode AllInstalled ->
322+
(CmdLine.BasicMode, argString CmdLine.AllInstalled)
323+
ListMode OnlyInvalid ->
324+
(CmdLine.ListMode, argString CmdLine.OnlyInvalid)
325+
ListMode AllInstalled ->
326+
(CmdLine.ListMode, argString CmdLine.AllInstalled)
327+
301328
-- -----------------------------------------------------------------------------
302329
-- Utility functions
303330

0 commit comments

Comments
 (0)