diff --git a/.forgejo/workflows/test.yaml b/.forgejo/workflows/test.yaml deleted file mode 100644 index ee81782..0000000 --- a/.forgejo/workflows/test.yaml +++ /dev/null @@ -1,99 +0,0 @@ -name: Haskell CI -on: - pull_request: - branches: - - dev - - main - push: - branches: - - main - -jobs: - build: - runs-on: docker - container: - image: elland/haddock2:latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Check versions - run: | - ghc --version - cabal --version - node --version - - name: Cache Cabal packages - uses: actions/cache@v4 - with: - path: | - ~/.cabal/packages - ~/.cabal/store - dist-newstyle - key: ${{ runner.os }}-haskell-9.10-cabal-${{ hashFiles('**/*.cabal', '**/cabal.project') }} - restore-keys: | - ${{ runner.os }}-haskell-9.10-cabal- - - name: Update Cabal package index - run: cabal update - - name: Configure project - run: cabal configure --enable-tests --enable-benchmarks - - name: Build dependencies - run: cabal build --only-dependencies --enable-tests --enable-benchmarks - - name: Build project - run: cabal build --enable-tests --enable-benchmarks - - name: Run documentation build - run: cabal haddock - - test: - runs-on: docker - container: - image: elland/haddock2:latest - needs: build - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Cache Cabal packages - uses: actions/cache@v4 - with: - path: | - ~/.cabal/packages - ~/.cabal/store - dist-newstyle - key: ${{ runner.os }}-haskell-9.10-cabal-${{ hashFiles('**/*.cabal', '**/cabal.project') }} - restore-keys: | - ${{ runner.os }}-haskell-9.10-cabal- - - name: Update Cabal package index - run: cabal update - - name: Configure project - run: cabal configure --enable-tests --enable-benchmarks - - name: Build dependencies - run: cabal build --only-dependencies --enable-tests --enable-benchmarks - - name: Build project - run: cabal build --enable-tests --enable-benchmarks - - name: Run tests - run: cabal test --test-show-details=direct - - fourmolu: - runs-on: docker - container: - image: elland/haddock2:latest - needs: build - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Run fourmolu - run: | - find src test app -name "*.hs" -exec fourmolu --check-idempotence {} \; 2>/dev/null || true - find src test app -name "*.hs" -exec fourmolu --mode check {} \; - - hlint: - runs-on: docker - container: - image: elland/haddock2:latest - needs: build - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Run hlint - run: | - if [ -d src ]; then hlint src/; fi - if [ -d test ]; then hlint test/; fi - if [ -d app ]; then hlint app/; fi diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index c2919c5..0000000 --- a/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -FROM haskell:9.10.2-bullseye AS builder - -RUN apt-get update && apt-get install -y curl git && rm -rf /var/lib/apt/lists/* - -RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \ - apt-get install -y nodejs && \ - rm -rf /var/lib/apt/lists/* - -RUN cabal update && \ - cabal install --install-method=copy --installdir=/usr/local/bin \ - fourmolu hlint cabal-gild - -WORKDIR /workspace - -FROM haskell:9.10.2-bullseye - -RUN apt-get update && apt-get install -y \ - libgmp10 \ - curl \ - && rm -rf /var/lib/apt/lists/* - -RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \ - apt-get install -y nodejs && \ - rm -rf /var/lib/apt/lists/* - -RUN cabal update - -COPY --from=builder /usr/local/bin/cabal /usr/local/bin/ -COPY --from=builder /usr/local/bin/fourmolu /usr/local/bin/ -COPY --from=builder /usr/local/bin/hlint /usr/local/bin/ -COPY --from=builder /usr/local/bin/cabal-gild /usr/local/bin/ - -WORKDIR /workspace - -CMD [ "bash" ] - diff --git a/Makefile b/Makefile index 6bc9ca2..62cad36 100644 --- a/Makefile +++ b/Makefile @@ -1,44 +1,9 @@ .PHONY: help -help: ## Show this help +help: ## Show this help. @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' -.PHONY: build -build: ## Build the project - cabal build - -.PHONY: test -test: ## Run tests - cabal test --test-show-details=direct - -.PHONY: clean -clean: ## Clean build artifacts - cabal clean - -.PHONY: fourmolu -fourmolu: ## Format Haskell code +.PHONY: format +format: find . -type f -name "*.hs" ! -path "./dist-newstyle/*" -exec fourmolu -i {} + - -.PHONY: fourmolu-check -fourmolu-check: ## Check if code is formatted - find . -type f -name "*.hs" ! -path "./dist-newstyle/*" -exec fourmolu --mode check {} \; - -.PHONY: lint -lint: ## Run hlint - hlint src test app - -.PHONY: cabal-gild -cabal-gild: ## Format cabal file cabal-gild --io=haddock2.cabal -.PHONY: format -format: fourmolu cabal-gild ## Run all formatters - -.PHONY: check -check: fourmolu-check lint ## Run all checks (CI-style) - -.PHONY: ci -ci: build test check ## Run full CI pipeline locally - -.PHONY: docs -docs: ## Generate documentation - cabal haddock --haddock-hyperlink-source diff --git a/src/Lexer.hs b/src/Lexer.hs index 77fc84a..47c4e1c 100644 --- a/src/Lexer.hs +++ b/src/Lexer.hs @@ -70,7 +70,7 @@ located :: Parser a -> Parser (SourcePos, a) located p = (,) <$> getPosition <*> p tokenise :: [Parser a] -> Parser [(SourcePos, a)] -tokenise = mapM located +tokenise = sequence . map located lexer :: String -> Either ParseError [LocatedToken] lexer = Parsec.runParser lexText initialParserState "input" . Text.pack @@ -148,7 +148,7 @@ delimitedNoTrailing openP closeP openTok = asList <$> delimitedAsTuple (openTok asList (a, tok, _) = [a, tok] delimitedSymmetric :: Parser a -> Token -> Token -> Parser [LocatedToken] -delimitedSymmetric s = delimited s s +delimitedSymmetric s t1 t2 = delimited s s t1 t2 eol :: Parser () eol = void "\n" <|> void "\r\n" <|> Parsec.eof diff --git a/src/Parser/Util.hs b/src/Parser/Util.hs index a75fcef..4cf96cb 100644 --- a/src/Parser/Util.hs +++ b/src/Parser/Util.hs @@ -13,9 +13,7 @@ import Text.Parsec.Pos (updatePosChar) Return everything consumed except for the end pattern itself. -} takeUntil :: Text -> Parser Text -takeUntil end_ = - requireEnd (scan p (False, end)) - >>= gotSome . Text.dropEnd (Text.length end_) +takeUntil end_ = Text.dropEnd (Text.length end_) <$> requireEnd (scan p (False, end)) >>= gotSome where end = Text.unpack end_ diff --git a/src/Types.hs b/src/Types.hs index ec7a4e4..a41e38b 100644 --- a/src/Types.hs +++ b/src/Types.hs @@ -9,8 +9,6 @@ module Types ( ) where -import Data.Foldable (fold) - newtype Document = Document { meta :: Meta } @@ -30,7 +28,6 @@ data Since = Since -- Could have a better type? type Version = [Int] - type Package = String data DocMarkup mod id @@ -54,78 +51,78 @@ data DocMarkup mod id | -- | Bold __bold text__ DocBold (DocMarkup mod id) | {- | Unordered lists - * this - or - - this + * this + or + - this -} DocUnorderedList [DocMarkup mod id] | {- | Ordered lists - 1. this - or - (1) this + 1. this + or + (1) this -} DocOrderedList [(Int, DocMarkup mod id)] | {- | Definition lists - [term] a term - [another term] another definition + [term] a term + [another term] another definition -} DocDefinitionList [(DocMarkup mod id, DocMarkup mod id)] | {- | Code blocks - @ - a code block in here - with multiple lines - @ + @ + a code block in here + with multiple lines + @ - Or with bird tracks: - > some code - > goes here + Or with bird tracks: + > some code + > goes here -} DocCodeBlock (DocMarkup mod id) | {- | Hyperlinks - __marked__: - - - __Auto-detected URLs__: - http://example.com - https://example.com - ftp://example.com - __Markdown style__ - [link text](http://example.com) - [link text]("Module.Name") + __marked__: + + + __Auto-detected URLs__: + http://example.com + https://example.com + ftp://example.com + __Markdown style__ + [link text](http://example.com) + [link text]("Module.Name") -} DocHyperlink (Hyperlink (DocMarkup mod id)) | {- | Pictures - <> - <> + <> + <> - __Markdown Images__ + __Markdown Images__ - ![alt text](image.png) + ![alt text](image.png) -} DocPicture Picture | {- | Inline math expressions - \(mathematical expression\) + \(mathematical expression\) -} DocMathInline String | {- | Math multiline display - \[ - mathematical expression - in multiple lines - \] + \[ + mathematical expression + in multiple lines + \] -} DocMathDisplay String | {- | Anchors, no spaces allowed - #anchor-name# + #anchor-name# -} DocAnchor String | {- | Property descriptions - prop> property description + prop> property description -} DocProperty String | {- | Examples - >>> expression - result line 1 - result line 2 + >>> expression + result line 1 + result line 2 -} DocExamples [Example] | -- | Header @@ -139,7 +136,7 @@ instance Semigroup (DocMarkup mod id) where instance Monoid (DocMarkup mod id) where mempty = DocEmpty - mconcat = fold + mconcat = foldr (<>) mempty data ModuleLink id = ModuleLink { name :: String diff --git a/test/Spec.hs b/test/Spec.hs index 2040e2f..03e1b81 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -1,15 +1,16 @@ {-# LANGUAGE OverloadedStrings #-} {-# OPTIONS_GHC -Wno-orphans #-} -import Data.String (IsString (..)) -import Data.Text (Text) -import GHC.Stack +import Test.Hspec + import Identifier (Identifier) import Lexer import Parser import Types -import Test.Hspec +import Data.String (IsString (..)) +import Data.Text (Text) +import GHC.Stack import Text.Parsec.Pos main :: IO () @@ -34,9 +35,9 @@ main = hspec $ do describe "Parser" do it "Bold" do - "__bold__" `shouldParseTo` DocBold (DocString "bold") + "__bold__" `shouldParseTo` (DocBold (DocString "bold")) it "Emphasis" do - "/emphasis/" `shouldParseTo` DocEmphasis (DocString "emphasis") + "/emphasis/" `shouldParseTo` (DocEmphasis (DocString "emphasis")) ------------ -- Tests @@ -57,7 +58,6 @@ modules = do `shouldLexTo` [ (1, 2, Module "OtherModule.Name") , (1, 18, Anchor "myAnchor") ] - link :: Expectation link = "[link to](http://some.website)"