diff options
author | Andrew Cady <d@jerkface.net> | 2018-07-10 07:00:11 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2018-07-10 07:00:11 -0400 |
commit | e4520bb718e8eca78b8ce2eee972830afb893b70 (patch) | |
tree | e820c5f2b3f023445ec0bf9bd6dceb59ac0da0ec | |
parent | 0af33cecec5d0a9a23fb4b1758455cef3840db88 (diff) |
Change command-line usage
Now using optparse-applicative to support subcommands
(There is presently only one subcommand: 'build')
-rw-r--r-- | fsmgr.cabal | 2 | ||||
-rw-r--r-- | fsmgr.hs | 46 |
2 files changed, 33 insertions, 15 deletions
diff --git a/fsmgr.cabal b/fsmgr.cabal index 3da9bf6..4b96133 100644 --- a/fsmgr.cabal +++ b/fsmgr.cabal | |||
@@ -35,7 +35,7 @@ executable fsmgr | |||
35 | ghc-options: -threaded -rtsopts -with-rtsopts=-N -W -Wall | 35 | ghc-options: -threaded -rtsopts -with-rtsopts=-N -W -Wall |
36 | build-depends: fsmgr, | 36 | build-depends: fsmgr, |
37 | base >=4.7 && <5, rebase, optparse-applicative, typed-process, | 37 | base >=4.7 && <5, rebase, optparse-applicative, typed-process, |
38 | directory, filepath, yaml-combinators, lens, lens-aeson, cryptonite, memory, basement, shake | 38 | directory, filepath, yaml-combinators, lens, lens-aeson, cryptonite, memory, basement, shake, optparse-applicative |
39 | default-language: Haskell2010 | 39 | default-language: Haskell2010 |
40 | 40 | ||
41 | -- test-suite fsmgr-test | 41 | -- test-suite fsmgr-test |
@@ -8,13 +8,16 @@ | |||
8 | {-# LANGUAGE ScopedTypeVariables #-} | 8 | {-# LANGUAGE ScopedTypeVariables #-} |
9 | 9 | ||
10 | module Main where | 10 | module Main where |
11 | import Rebase.Prelude hiding (bool, hash, (<.>)) | 11 | import Rebase.Prelude hiding (bool, hash, o, (<.>)) |
12 | 12 | ||
13 | import Development.Shake hiding (getEnv) | 13 | import qualified Rebase.Data.Text as Text |
14 | import Development.Shake.Command () | 14 | ;import Rebase.Data.Text (pack, unpack) |
15 | |||
16 | import Development.Shake hiding (getEnv) | ||
17 | import Development.Shake.Command () | ||
15 | import Development.Shake.FilePath | 18 | import Development.Shake.FilePath |
16 | import qualified Rebase.Data.Text as Text | 19 | |
17 | ;import Rebase.Data.Text (pack, unpack) | 20 | import Options.Applicative as Opt |
18 | 21 | ||
19 | import ConfigFile | 22 | import ConfigFile |
20 | 23 | ||
@@ -98,16 +101,31 @@ defaultImageName = "minbase" | |||
98 | stripSuffix :: Text -> String -> String | 101 | stripSuffix :: Text -> String -> String |
99 | stripSuffix s t = fromMaybe t $ fmap unpack $ Text.stripSuffix s $ pack t | 102 | stripSuffix s t = fromMaybe t $ fmap unpack $ Text.stripSuffix s $ pack t |
100 | 103 | ||
104 | data Options = Options { optCommand :: Command } | ||
105 | data Command = Build BuildOpts | ||
106 | data BuildOpts = BuildOpts { optTarget :: String } | ||
107 | |||
108 | buildOpts :: Parser Command | ||
109 | buildOpts = Build . BuildOpts <$> argument str idm | ||
110 | |||
111 | -- TODO: Fail early on: | ||
112 | -- 1. not running as root | ||
113 | -- 2. no "selfstrap" in PATH | ||
101 | main :: IO () | 114 | main :: IO () |
102 | main = do | 115 | main = customExecParser (prefs showHelpOnEmpty) (info opts desc) >>= run |
103 | -- TODO: Fail early on: | 116 | where |
104 | -- 1. not running as root | 117 | opts :: Parser Options |
105 | -- 2. no "selfstrap" in PATH | 118 | opts = Options <$> parseCommand |
106 | args <- getArgs | 119 | desc = fullDesc <> progDesc detailed <> header "fsmgr - Debian rootfs image manager" |
107 | case args of | 120 | detailed = unwords ["This program generates btrfs filesystem images using 'selfstrap'", |
108 | [target] -> shakeBuildOneImage (stripSuffix ".yaml" target) | 121 | "which, much like 'debootstrap', creates new installations of Debian."] |
109 | [] -> shakeBuildOneImage defaultImageName | 122 | parseCommand :: Parser Command |
110 | _ -> error "usage" | 123 | parseCommand = subparser $ Opt.command "build" (info' buildOpts buildDesc) |
124 | buildDesc = ["build the image specified by the YAML config file"] | ||
125 | info' o d = info (helper <*> o) (progDesc $ unwords d) | ||
126 | |||
127 | run :: Options -> IO () | ||
128 | run (Options (Build (BuildOpts target)))= shakeBuildOneImage (stripSuffix ".yaml" target) | ||
111 | 129 | ||
112 | shakeBuildOneImage :: FilePath -> IO () | 130 | shakeBuildOneImage :: FilePath -> IO () |
113 | shakeBuildOneImage target = | 131 | shakeBuildOneImage target = |