1{- git-annex command data types
2 -
3 - Copyright 2010-2021 Joey Hess <id@joeyh.name>
4 -
5 - Licensed under the GNU AGPL version 3 or higher.
6 -}
7
8{-# LANGUAGE RankNTypes #-}
9
10module Types.Command where
11
12import Data.Ord
13import Options.Applicative.Types (Parser)
14import Options.Applicative.Builder (InfoMod)
15
16import Types
17import Types.DeferredParse
18import Types.ActionItem
19
20{- A command runs in these stages.
21 -
22 - a. The parser stage parses the command line and generates a CommandSeek
23 -    action. -}
24type CommandParser = Parser CommandSeek
25{- b. The check stage runs checks, that error out if
26 -    anything prevents the command from running. -}
27data CommandCheck = CommandCheck { idCheck :: Int, runCheck :: Annex () }
28{- c. The seek stage is passed input from the parser, looks through
29 -    the repo to find things to act on (ie, new files to add), and
30 -    runs commandAction to handle all necessary actions. -}
31type CommandSeek = Annex ()
32{- d. The start stage is run before anything is output, is passed some
33 -    value from the seek stage, and can check if anything needs to be
34 -    done, and early abort if not. It should run quickly and should
35 -    not modify Annex state or output anything. -}
36type CommandStart = Annex (Maybe (StartMessage, CommandPerform))
37{- e. The perform stage is run after a message is printed about the command
38 -    being run, and it should be where the bulk of the work happens. -}
39type CommandPerform = Annex (Maybe CommandCleanup)
40{- f. The cleanup stage is run only if the perform stage succeeds, and it
41 -    returns the overall success/fail of the command. -}
42type CommandCleanup = Annex Bool
43
44{- Input that was seeked on to make an ActionItem. Eg, the input filename,
45 - or directory name. -}
46newtype SeekInput = SeekInput { fromSeekInput :: [String] }
47	deriving (Show)
48
49{- Message that is displayed when starting to perform an action on
50 - something. The String is typically the name of the command or action
51 - being performed.
52 -}
53data StartMessage
54	= StartMessage String ActionItem SeekInput
55	| StartUsualMessages String ActionItem SeekInput
56	-- ^ Like StartMessage, but makes sure to enable usual message
57	-- display in case it was disabled by cmdnomessages.
58	| StartNoMessage ActionItem
59	-- ^ Starts, without displaying any message but also without
60	-- disabling display of any of the usual messages.
61	| CustomOutput ActionItem
62	-- ^ Prevents any start, end, or other usual messages from
63	-- being displayed, letting a command output its own custom format.
64	deriving (Show)
65
66instance MkActionItem StartMessage where
67	mkActionItem (StartMessage _ ai _) = ai
68	mkActionItem (StartUsualMessages _ ai _) = ai
69	mkActionItem (StartNoMessage ai) = ai
70	mkActionItem (CustomOutput ai) = ai
71
72{- A command is defined by specifying these things. -}
73data Command = Command
74	{ cmdcheck :: [CommandCheck]
75	-- ^ check stage
76	, cmdnocommit :: Bool
77	-- ^ don't commit journalled state changes
78	, cmdnomessages :: Bool
79	-- ^ don't output normal messages
80	, cmdname :: String
81	, cmdparamdesc :: CmdParamsDesc
82	-- ^ description of params for usage
83	, cmdsection :: CommandSection
84	, cmddesc :: String
85	-- ^ description of command for usage
86	, cmdparser :: CommandParser
87	-- ^ command line parser
88	, cmdinfomod :: forall a. InfoMod a
89	-- ^ command-specific modifier for ParserInfo
90	, cmdglobaloptions :: [GlobalOption]
91	-- ^ additional global options
92	, cmdnorepo :: Maybe (Parser (IO ()))
93	-- ^used when not in a repo
94	}
95
96{- Command-line parameters, after the command is selected and options
97 - are parsed. -}
98type CmdParams = [String]
99
100type CmdParamsDesc = String
101
102{- CommandCheck functions can be compared using their unique id. -}
103instance Eq CommandCheck where
104	a == b = idCheck a == idCheck b
105
106instance Eq Command where
107	a == b = cmdname a == cmdname b
108
109{- Order commands by name. -}
110instance Ord Command where
111	compare = comparing cmdname
112
113{- The same sections are listed in doc/git-annex.mdwn -}
114data CommandSection
115	= SectionCommon
116	| SectionSetup
117	| SectionMaintenance
118	| SectionQuery
119	| SectionMetaData
120	| SectionUtility
121	| SectionPlumbing
122	| SectionTesting
123	| SectionAddOn
124	deriving (Eq, Ord, Enum, Bounded)
125
126descSection :: CommandSection -> String
127descSection SectionCommon = "Commonly used commands"
128descSection SectionSetup = "Repository setup commands"
129descSection SectionMaintenance = "Repository maintenance commands"
130descSection SectionQuery = "Query commands"
131descSection SectionMetaData = "Metadata commands"
132descSection SectionUtility = "Utility commands"
133descSection SectionPlumbing = "Plumbing commands"
134descSection SectionTesting = "Testing commands"
135descSection SectionAddOn = "Addon commands"
136