Skip to content

Commit 6a51985

Browse files
Release 0.0.1.0
2 parents ae7b149 + ea50304 commit 6a51985

21 files changed

+1341
-0
lines changed

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# project
2+
/build/
3+
4+
# stack
5+
.stack-work
6+
*.yaml.lock
7+
8+
# vi
9+
.*.swp

.travis.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
sudo: true
2+
language: haskell
3+
4+
git:
5+
depth: 5
6+
7+
cabal: "2.4"
8+
9+
cache:
10+
directories:
11+
- "$HOME/.cabal/store"
12+
- "$HOME/.stack"
13+
- "$TRAVIS_BUILD_DIR/.stack-work"
14+
15+
matrix:
16+
include:
17+
18+
# Cabal
19+
- ghc: 8.2.2
20+
- ghc: 8.4.4
21+
- ghc: 8.6.5
22+
23+
# Stack
24+
- ghc: 8.2.2
25+
env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.2.2.yaml"
26+
- ghc: 8.4.4
27+
env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.4.4.yaml"
28+
- ghc: 8.6.5
29+
env: STACK_YAML="$TRAVIS_BUILD_DIR/stack.yaml"
30+
31+
install:
32+
- |
33+
if [ -z "$STACK_YAML" ]; then
34+
ghc --version
35+
cabal --version
36+
cabal new-update
37+
cabal new-build --enable-tests --enable-benchmarks
38+
else
39+
# install stack
40+
curl -sSL https://get.haskellstack.org/ | sh
41+
42+
# build project with stack
43+
stack --version
44+
stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks
45+
fi
46+
47+
script:
48+
- |
49+
if [ -z "$STACK_YAML" ]; then
50+
cabal new-test --enable-tests
51+
else
52+
stack test --system-ghc
53+
fi
54+
55+
notifications:
56+
email: false

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# `queue-sheet-haskell` Changelog
2+
3+
This project follows the [Haskell package versioning policy][PVP], with
4+
versions in `A.B.C.D` format. `A` may be incremented arbitrarily for
5+
non-technical reasons, but [semantic versioning][SemVer] is otherwise
6+
followed, where `A.B` is the major version, `C` is the minor version, and `D`
7+
is the patch version. Initial development uses versions `0.0.0.D`, for which
8+
every version is considered breaking.
9+
10+
[PVP]: <https://pvp.haskell.org/>
11+
[SemVer]: <https://semver.org/>
12+
13+
The format of this changelog is based on [Keep a Changelog][KaC], with the
14+
following conventions:
15+
16+
* Level-two heading `Unreleased` is used to track changes that have not been
17+
released.
18+
* Other level-two headings specify the release in `A.B.C.D (YYYY-MM-DD)`
19+
format, with newer versions above older versions.
20+
* Level-three headings are used to categorize changes as follows:
21+
1. Breaking
22+
2. Non-Breaking
23+
* Changes are listed in arbitrary order and present tense.
24+
25+
[KaC]: <https://keepachangelog.com/en/1.0.0/>
26+
27+
## 0.0.1.0 (2020-01-22)
28+
29+
### Breaking
30+
31+
* Initial public release

LibOA.hs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
------------------------------------------------------------------------------
2+
-- |
3+
-- Module : LibOA
4+
-- Description : supplementary functions for optparse-applicative
5+
-- Copyright : Copyright (c) 2019-2020 Travis Cardwell
6+
-- License : MIT
7+
--
8+
-- This is a collection of functions that I often use with
9+
-- @optparse-applicative@. I do not feel that it is worth maintaining yet
10+
-- another helper package on Hackage, so I just copy the code to different
11+
-- projects as required. If the library grows to a substantial size or others
12+
-- with to use it, I will reconsider.
13+
--
14+
-- Revision: 2020-01-02
15+
------------------------------------------------------------------------------
16+
17+
{-# LANGUAGE CPP #-}
18+
19+
module LibOA
20+
( -- * Options
21+
-- $Options
22+
helper
23+
, versioner
24+
-- * Utilities
25+
, commands
26+
-- * Help
27+
, (<||>)
28+
, section
29+
, table
30+
, vspace
31+
) where
32+
33+
-- https://hackage.haskell.org/package/ansi-wl-pprint
34+
import qualified Text.PrettyPrint.ANSI.Leijen as Doc
35+
import Text.PrettyPrint.ANSI.Leijen (Doc)
36+
37+
-- https://hackage.haskell.org/package/base
38+
import qualified Data.List as List
39+
#if !MIN_VERSION_base (4,11,0)
40+
import Data.Monoid ((<>))
41+
#endif
42+
43+
-- https://hackage.haskell.org/package/optparse-applicative
44+
import qualified Options.Applicative as OA
45+
import qualified Options.Applicative.Common as OAC
46+
import qualified Options.Applicative.Types as OAT
47+
48+
------------------------------------------------------------------------------
49+
-- $Options
50+
--
51+
-- Option descriptions are not capitalized.
52+
53+
-- | A hidden @-h@ / @--help@ option that always fails, showing the help
54+
--
55+
-- This is the same as 'OA.helper' except that it has a different help
56+
-- message.
57+
helper :: OA.Parser (a -> a)
58+
helper = OA.abortOption OA.ShowHelpText $ mconcat
59+
[ OA.short 'h'
60+
, OA.long "help"
61+
, OA.help "show help and exit"
62+
, OA.hidden
63+
]
64+
65+
-- | A hidden @--version@ option that always fails, showing the version
66+
versioner
67+
:: String -- ^ version string
68+
-> OA.Parser (a -> a)
69+
versioner verStr = OA.infoOption verStr $ mconcat
70+
[ OA.long "version"
71+
, OA.help "show version and exit"
72+
, OA.hidden
73+
]
74+
75+
------------------------------------------------------------------------------
76+
-- $Utilities
77+
78+
-- | Get a list of commands for a parser
79+
commands :: OA.Parser a -> [String]
80+
commands =
81+
let go _ opt = case OAT.optMain opt of
82+
OAT.CmdReader _ cmds _ -> reverse cmds
83+
_ -> []
84+
in concat . OAC.mapParser go
85+
86+
------------------------------------------------------------------------------
87+
-- $Help
88+
89+
-- | Insert a blank line between two documents
90+
(<||>) :: Doc -> Doc -> Doc
91+
d1 <||> d2 = d1 <> Doc.line <> Doc.line <> d2
92+
93+
-- | Create a section with a title and indented body
94+
section :: String -> Doc -> Doc
95+
section title = (Doc.text title Doc.<$$>) . Doc.indent 2
96+
97+
-- | Create a two-column table
98+
table :: [(String, String)] -> Doc
99+
table rows =
100+
let width = 1 + maximum (map (length . fst) rows)
101+
in Doc.vcat
102+
[ Doc.fillBreak width (Doc.text l) Doc.<+> Doc.text r
103+
| (l, r) <- rows
104+
]
105+
106+
-- | Vertically space documents with blank lines between them
107+
vspace :: [Doc] -> Doc
108+
vspace = mconcat . List.intersperse (Doc.line <> Doc.line)

Makefile

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
##############################################################################
2+
# Project configuration
3+
4+
PACKAGE := queue-sheet
5+
BINARY := $(PACKAGE)
6+
CABAL_FILE := $(PACKAGE).cabal
7+
PROJECT := $(PACKAGE)-haskell
8+
9+
##############################################################################
10+
# Make configuration
11+
12+
ifeq ($(origin .RECIPEPREFIX), undefined)
13+
$(error GNU Make 4.0 or later required)
14+
endif
15+
.RECIPEPREFIX := >
16+
17+
SHELL := bash
18+
.SHELLFLAGS := -o nounset -o errexit -o pipefail -c
19+
20+
MAKEFLAGS += --no-builtin-rules
21+
MAKEFLAGS += --warn-undefined-variables
22+
23+
RESOLVER_ARGS :=
24+
ifneq ($(origin RESOLVER), undefined)
25+
RESOLVER_ARGS := "--resolver" "$(RESOLVER)"
26+
endif
27+
28+
STACK_YAML_ARGS :=
29+
ifneq ($(origin CONFIG), undefined)
30+
STACK_YAML_ARGS := "--stack-yaml" "$(CONFIG)"
31+
endif
32+
33+
##############################################################################
34+
# Functions
35+
36+
define all_files
37+
find . -not -path '*/\.*' -type f
38+
endef
39+
40+
define die
41+
(echo "error: $(1)" ; false)
42+
endef
43+
44+
define hs_files
45+
find . -not -path '*/\.*' -type f -name '*.hs'
46+
endef
47+
48+
##############################################################################
49+
# Rules
50+
51+
_default: build
52+
.PHONY: _default
53+
54+
build:
55+
> @command -v hr >/dev/null 2>&1 && hr -t || true
56+
> @stack build $(RESOLVER_ARGS) $(STACK_YAML_ARGS)
57+
.PHONY: build
58+
59+
clean:
60+
> @stack clean
61+
.PHONY: clean
62+
63+
clean-all: clean
64+
> @rm -rf .stack-work
65+
> @rm -rf build
66+
> @rm -f *.yaml.lock
67+
.PHONY: clean-all
68+
69+
grep:
70+
> $(eval E:= "")
71+
> @test -n "$(E)" || $(call die,"usage: make grep E=expression")
72+
> @$(call all_files) | xargs grep -Hn '$(E)' || true
73+
.PHONY: grep
74+
75+
help:
76+
> @echo "make build build package (default) *"
77+
> @echo "make clean clean package"
78+
> @echo "make clean-all clean package and remove artifacts"
79+
> @echo "make grep grep all non-hidden files for expression E"
80+
> @echo "make help show this help"
81+
> @echo "make hlint run hlint on all Haskell source"
82+
> @echo "make hsgrep grep all Haskell source for expression E"
83+
> @echo "make hsrecent show N most recently modified Haskell files"
84+
> @echo "make hssloc count lines of Haskell source"
85+
> @echo "make man build man page"
86+
> @echo "make recent show N most recently modified files"
87+
> @echo "make repl enter a REPL *"
88+
> @echo "make source-git create source tarball of git TREE"
89+
> @echo "make source-tar create source tarball using tar"
90+
> @echo "make test run tests, optionally for pattern P *"
91+
> @echo "make todo search for TODO items"
92+
> @echo "make version show current version"
93+
> @echo
94+
> @echo "* Use RESOLVER to specify a resolver."
95+
> @echo "* Use CONFIG to specify a Stack configuration file."
96+
.PHONY: help
97+
98+
hlint:
99+
> @$(call hs_files) | xargs hlint
100+
.PHONY: hlint
101+
102+
hsgrep:
103+
> $(eval E := "")
104+
> @test -n "$(E)" || $(call die,"usage: make hsgrep E=expression")
105+
> @$(call hs_files) | xargs grep -Hn '$(E)' || true
106+
.PHONY: hsgrep
107+
108+
hsrecent:
109+
> $(eval N := "10")
110+
> @find . -not -path '*/\.*' -type f -name '*.hs' -printf '%T+ %p\n' \
111+
> | sort --reverse \
112+
> | head -n $(N)
113+
.PHONY: hsrecent
114+
115+
hssloc:
116+
> @$(call hs_files) | xargs wc -l | tail -n 1 | sed 's/^ *\([0-9]*\).*$$/\1/'
117+
.PHONY: hssloc
118+
119+
man:
120+
> $(eval VERSION := $(shell \
121+
grep '^version:' $(CABAL_FILE) | sed 's/^version: *//'))
122+
> $(eval DATE := $(shell date --rfc-3339=date))
123+
> @mkdir -p build
124+
> @pandoc -s -t man -o build/$(BINARY).1 \
125+
> --variable header="$(BINARY) Manual" \
126+
> --variable footer="$(PROJECT) $(VERSION) ($(DATE))" \
127+
> doc/$(BINARY).1.md
128+
.PHONY: man
129+
130+
recent:
131+
> $(eval N := "10")
132+
> @find . -not -path '*/\.*' -type f -printf '%T+ %p\n' \
133+
> | sort --reverse \
134+
> | head -n $(N)
135+
.PHONY: recent
136+
137+
repl:
138+
> @stack exec ghci $(RESOLVER_ARGS) $(STACK_YAML_ARGS)
139+
.PHONY: repl
140+
141+
source-git:
142+
> $(eval TREE := "HEAD")
143+
> $(eval BRANCH := $(shell git rev-parse --abbrev-ref $(TREE)))
144+
> @test "${BRANCH}" = "master" || echo "WARNING: Not in master branch!" >&2
145+
> $(eval VERSION := $(shell \
146+
grep '^version:' $(CABAL_FILE) | sed 's/^version: *//'))
147+
> @mkdir -p build
148+
> @git archive --format=tar --prefix=$(PROJECT)-$(VERSION)/ $(TREE) \
149+
> | xz \
150+
> > build/$(PROJECT)-$(VERSION).tar.xz
151+
.PHONY: source-git
152+
153+
source-tar:
154+
> $(eval VERSION := $(shell \
155+
grep '^version:' $(CABAL_FILE) | sed 's/^version: *//'))
156+
> @mkdir -p build
157+
> @sed -e 's,^/,./,' -e 's,/$$,,' .gitignore > build/.gitignore
158+
> @tar \
159+
> --exclude-vcs \
160+
> --exclude-ignore-recursive=build/.gitignore \
161+
> --transform "s,^\.,$(PROJECT)-$(VERSION)," \
162+
> -Jcf build/$(PROJECT)-$(VERSION).tar.xz \
163+
> .
164+
> @rm -f build/.gitignore
165+
.PHONY: source-tar
166+
167+
test:
168+
> $(eval P := "")
169+
> @command -v hr >/dev/null 2>&1 && hr -t || true
170+
> @test -z "$(P)" \
171+
> && stack test $(RESOLVER_ARGS) $(STACK_YAML_ARGS) \
172+
> || stack test $(RESOLVER_ARGS) $(STACK_YAML_ARGS) \
173+
> --test-arguments '--pattern $(P)'
174+
.PHONY: test
175+
176+
todo:
177+
> @find . -type f \
178+
> -not -path '*/\.*' \
179+
> -not -path './build/*' \
180+
> -not -path './project/*' \
181+
> -not -path ./Makefile \
182+
> | xargs grep -Hn TODO || true
183+
.PHONY: todo
184+
185+
version:
186+
> @grep '^version:' $(CABAL_FILE) | sed 's/^version: */$(PROJECT) /'
187+
.PHONY: version

0 commit comments

Comments
 (0)