mirror of
https://github.com/rodrigosetti/master-plan.git
synced 2024-11-22 04:13:26 +03:00
Skeleton for text and graph backends
This commit is contained in:
parent
d26a700048
commit
25c988574d
39
README.md
39
README.md
@ -38,17 +38,33 @@ The tool is able to build visualizations and reports from the plan file.
|
||||
Ideally, the plan file should be kept in version control so that execution and
|
||||
planning progress can be recorded.
|
||||
|
||||
### Commands
|
||||
### Command line Arguments
|
||||
|
||||
The `mp` command line tool supports the following commands:
|
||||
```
|
||||
master-plan - project management tool for hackers
|
||||
|
||||
* `prioritize` - list, in order of priority, the projects ready for execution.
|
||||
* `render` - generate a report output, specified by one of the backend formats.
|
||||
Usage: master-plan [-i|--input FILENAME] [-o|--output FILENAME]
|
||||
[--progress-below N]
|
||||
[--hide title|description|url|owner|cost|trust|progress]
|
||||
[-p|--prioritize] (-m|--mode identity|text|graph)
|
||||
See documentation on how to write project plan files
|
||||
|
||||
Available options:
|
||||
-i,--input FILENAME plan file to read from (default: "master.plan")
|
||||
-o,--output FILENAME output file name
|
||||
--progress-below N only display projects which progress is < N%
|
||||
--hide title|description|url|owner|cost|trust|progress
|
||||
hide a particular property
|
||||
-p,--prioritize prioritize projects to minimize cost
|
||||
-m,--mode identity|text|graph
|
||||
render mode
|
||||
-h,--help Show this help text
|
||||
```
|
||||
|
||||
### Syntax
|
||||
|
||||
Comments are preceded by hashtag (`#`), and extend to the end of line
|
||||
(like Shell and Python).
|
||||
Comments are C-style: multiline in between `/*` and `*/`, and single line starts
|
||||
with `//`, extending to the end of line. Every definition must end with semicolon.
|
||||
|
||||
Everything else are definitions, in the form `lrs = rhs`.
|
||||
There are two kinds of definitions with respect to `lrs` (left hand side):
|
||||
@ -66,7 +82,7 @@ are three operators:
|
||||
|
||||
* `p = a + b` - Sum: `p` is executed when `a` or `b` is executed.
|
||||
* `p = a x b` - Product: `p` is executed when `a` and `b` is executed.
|
||||
* `p = a > b` - Sequence: `p` is executed when `a` and `b` is executed, in order.
|
||||
* `p = a -> b` - Sequence: `p` is executed when `a` and `b` is executed, in order.
|
||||
|
||||
#### Properties
|
||||
|
||||
@ -74,17 +90,18 @@ Following is a list of supported properties of projects:
|
||||
|
||||
| Property name | Expected Type | Description |
|
||||
|---------------|---------------|-------------|
|
||||
| name | text | title of the project |
|
||||
| title | text | title of the project |
|
||||
| description | text | longer description of what the project is |
|
||||
| url | URL | reference in the web for more context about the project |
|
||||
| owner | username | name of the person responsible for execution |
|
||||
| progress | percentage | how much progress has been made so far |
|
||||
| cost | number | estimated cost (aliases: "time", "estimation") |
|
||||
| risk | percentage | risk of failure |
|
||||
| cost | number | estimated cost |
|
||||
| trust | percentage | probability of success |
|
||||
|
||||
#### Grammar
|
||||
|
||||
```
|
||||
plan = (definition ";")*
|
||||
definition = project_def | predicate_def
|
||||
|
||||
project_def = identifier "=" expression
|
||||
@ -94,4 +111,6 @@ factor = "(" expression ")" | identifier
|
||||
|
||||
predicate_def = identifier "(" identifier ")" "=" value
|
||||
value = percentage | literalString
|
||||
|
||||
percentage = nonNegativeNumber "%"
|
||||
```
|
||||
|
34
app/Main.hs
34
app/Main.hs
@ -1,12 +1,23 @@
|
||||
{-|
|
||||
Module : Main
|
||||
Description : Parses command line and dispatches to correct backend
|
||||
Copyright : (c) Rodrigo Setti, 2017
|
||||
License : MIT
|
||||
Maintainer : rodrigosetti@gmail.com
|
||||
Stability : experimental
|
||||
Portability : POSIX
|
||||
-}
|
||||
{-# LANGUAGE UnicodeSyntax #-}
|
||||
module Main (main) where
|
||||
|
||||
import Data.List (intercalate)
|
||||
import qualified Data.List.NonEmpty as NE
|
||||
import qualified Data.Map as M
|
||||
import Data.Maybe (catMaybes)
|
||||
import Data.Maybe (catMaybes, fromMaybe)
|
||||
import Data.Semigroup ((<>))
|
||||
import qualified MasterPlan.Backend.Identity as ID
|
||||
import qualified MasterPlan.Backend.Graph as BG
|
||||
import qualified MasterPlan.Backend.Identity as BI
|
||||
import qualified MasterPlan.Backend.Text as BT
|
||||
import MasterPlan.Data
|
||||
import qualified MasterPlan.Parser as P
|
||||
import Options.Applicative
|
||||
@ -99,21 +110,24 @@ filterBinding _ _ b = Just b
|
||||
|
||||
masterPlan ∷ Opts → IO ()
|
||||
masterPlan opts =
|
||||
do let filename = inputPath opts
|
||||
contents <- readFile filename
|
||||
do contents <- readFile filename
|
||||
case P.runParser filename contents of
|
||||
Left e -> hPutStr stderr e
|
||||
Right sys@(ProjectSystem b) ->
|
||||
render $ maybeOptimize $ ProjectSystem $ M.mapMaybe
|
||||
(filterBinding sys $ projFilter opts) b
|
||||
where
|
||||
filename = inputPath opts
|
||||
|
||||
maybeOptimize = if prioritize opts then optimizeSys else id
|
||||
|
||||
outputToFileOrOut s = case outputPath opts of
|
||||
Nothing -> putStr s
|
||||
Just path -> writeFile path s
|
||||
|
||||
render sys =
|
||||
case renderMode opts of
|
||||
IdentityRenderMode -> do let result = ID.render sys $ properties opts
|
||||
case outputPath opts of
|
||||
Nothing -> putStr result
|
||||
Just path -> writeFile path result
|
||||
TextRenderMode -> error "not implemented"
|
||||
GraphRenderMode -> error "not implemented"
|
||||
IdentityRenderMode -> outputToFileOrOut $ BI.render sys $ properties opts
|
||||
TextRenderMode -> outputToFileOrOut $ BT.render sys $ properties opts
|
||||
GraphRenderMode -> do let outfile = fromMaybe (filename ++ ".png") $ outputPath opts
|
||||
BG.render outfile sys $ properties opts
|
||||
|
@ -39,6 +39,8 @@ library
|
||||
exposed-modules: MasterPlan.Data
|
||||
, MasterPlan.Parser
|
||||
, MasterPlan.Backend.Identity
|
||||
, MasterPlan.Backend.Graph
|
||||
, MasterPlan.Backend.Text
|
||||
|
||||
test-suite spec
|
||||
type: exitcode-stdio-1.0
|
||||
|
16
src/MasterPlan/Backend/Graph.hs
Normal file
16
src/MasterPlan/Backend/Graph.hs
Normal file
@ -0,0 +1,16 @@
|
||||
{-|
|
||||
Module : MasterPlan.Backend.Graph
|
||||
Description : a backend that renders to PNG diagram
|
||||
Copyright : (c) Rodrigo Setti, 2017
|
||||
License : MIT
|
||||
Maintainer : rodrigosetti@gmail.com
|
||||
Stability : experimental
|
||||
Portability : POSIX
|
||||
-}
|
||||
{-# LANGUAGE UnicodeSyntax #-}
|
||||
module MasterPlan.Backend.Graph (render) where
|
||||
|
||||
import MasterPlan.Data
|
||||
|
||||
render ∷ FilePath -> ProjectSystem → [ProjProperty] -> IO ()
|
||||
render = error "not implemented"
|
@ -3,7 +3,7 @@ Module : MasterPlan.Backend.Identity
|
||||
Description : a backend that renders to a text that can be parsed
|
||||
Copyright : (c) Rodrigo Setti, 2017
|
||||
License : MIT
|
||||
Maintainer : rodrigosetti@email.com
|
||||
Maintainer : rodrigosetti@gmail.com
|
||||
Stability : experimental
|
||||
Portability : POSIX
|
||||
-}
|
||||
|
16
src/MasterPlan/Backend/Text.hs
Normal file
16
src/MasterPlan/Backend/Text.hs
Normal file
@ -0,0 +1,16 @@
|
||||
{-|
|
||||
Module : MasterPlan.Backend.Text
|
||||
Description : a backend that renders to a UI text
|
||||
Copyright : (c) Rodrigo Setti, 2017
|
||||
License : MIT
|
||||
Maintainer : rodrigosetti@gmail.com
|
||||
Stability : experimental
|
||||
Portability : POSIX
|
||||
-}
|
||||
{-# LANGUAGE UnicodeSyntax #-}
|
||||
module MasterPlan.Backend.Text (render) where
|
||||
|
||||
import MasterPlan.Data
|
||||
|
||||
render ∷ ProjectSystem → [ProjProperty] -> String
|
||||
render = error "not implemented"
|
@ -3,7 +3,7 @@ Module : MasterPlan.Data
|
||||
Description : Types for defining project and project systems
|
||||
Copyright : (c) Rodrigo Setti, 2017
|
||||
License : MIT
|
||||
Maintainer : rodrigosetti@email.com
|
||||
Maintainer : rodrigosetti@gmail.com
|
||||
Stability : experimental
|
||||
Portability : POSIX
|
||||
-}
|
||||
|
@ -3,7 +3,7 @@ Module : MasterPlan.Parser
|
||||
Description : export parser for project systems
|
||||
Copyright : (c) Rodrigo Setti, 2017
|
||||
License : MIT
|
||||
Maintainer : rodrigosetti@email.com
|
||||
Maintainer : rodrigosetti@gmail.com
|
||||
Stability : experimental
|
||||
Portability : POSIX
|
||||
-}
|
||||
|
@ -13,10 +13,12 @@ spec ∷ Spec
|
||||
spec =
|
||||
describe "parser" $ do
|
||||
|
||||
let allProps = [minBound :: ProjProperty ..]
|
||||
|
||||
it "rendered should be parseable" $ do
|
||||
let renderedIsParseable ∷ ProjectSystem → Property
|
||||
renderedIsParseable sys =
|
||||
let rendered = render sys
|
||||
let rendered = render sys allProps
|
||||
in counterexample rendered $ isRight (runParser "test1" rendered)
|
||||
|
||||
property $ withMaxSuccess 50 renderedIsParseable
|
||||
@ -26,7 +28,7 @@ spec =
|
||||
let propertyParseAndOutputIdentity ∷ ProjectSystem → Property
|
||||
propertyParseAndOutputIdentity sys =
|
||||
let sys' = simplify sys
|
||||
parsed = runParser "test2" (render sys')
|
||||
parsed = runParser "test2" (render sys' allProps)
|
||||
in isRight parsed ==> parsed === Right sys'
|
||||
|
||||
property $ withMaxSuccess 50 propertyParseAndOutputIdentity
|
||||
|
Loading…
Reference in New Issue
Block a user