Skeleton for text and graph backends

This commit is contained in:
Rodrigo Setti 2017-08-09 18:32:46 -07:00
parent d26a700048
commit 25c988574d
No known key found for this signature in database
GPG Key ID: 3E2EB67B3A72ABD3
9 changed files with 94 additions and 25 deletions

View File

@ -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 "%"
```

View File

@ -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

View File

@ -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

View 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"

View File

@ -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
-}

View 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"

View File

@ -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
-}

View File

@ -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
-}

View File

@ -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