Skip to content

Commit 4c71a00

Browse files
committed
Add support for Elm projects
1 parent 906308a commit 4c71a00

36 files changed

+1482
-121
lines changed

.last-exported-commit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Last exported commit from parent repo: 63e68ff8c47e2606e54d2e318af226c41350b755
1+
Last exported commit from parent repo: 9428df9a3d71867350f17c1a022e744fce6d2410

README.md

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,28 @@ The following symbols are used throughout this page to indicate support status:
3333

3434
### Toolchain Support
3535

36-
| Toolchain\\\\Feature | Development Environment | VSCode DevContainer | Gitignore | Pre-Commit Hooks<sup>[1](#footnote1)</sup> | Reproducible Production Builds |
37-
| :----------------------------------------: | :-------------------------------------------------------------------: | :--------------------------------------------------------------------------------: | :-------: | :----------------------------------------: | :------------------------------------------------------------------------------------------: |
38-
| Golang || ✅ <p>With the official Go extension installed.</p> ||| 🟠 <p>Support is currently considered _experimental_.</p> |
39-
| Java | ✅ <p>With maven, google-java-format, and optionally minishift.</p> | ✅ <p>With the official Java, and optionally the Lombok, extensions installed.</p> ||| 🟠 <p>Only supports Spring applications. Support is currently considered _experimental_.</p> |
40-
| Minimal (With no project-specific tooling) |||| 🟠 ||
41-
| NodeJS | ✅ <p>With latest stable node, AWS CLI, and optionally PNPm/Yarn.</p> |||||
42-
| Python | ✅ <p>With Python version 3.9</p> | ✅ <p>With the official Python VSCode extension.</p> || 🟠 ||
36+
| Toolchain\\\\Feature | Development Environment | VSCode DevContainer | Gitignore | Pre-Commit Hooks<sup>[1](#footnote1)</sup> | Reproducible Production Builds |
37+
| :----------------------------------------: | :----------------------------------------------------------------------------: | :--------------------------------------------------------------------------------: | :-------: | :----------------------------------------: | :------------------------------------------------------------------------------------------: |
38+
| Elm | ✅ <p>Either as a standalone app or as part of a Node project with Parcel.</p> | ✅ <br>With the Elm extension installed. ||||
39+
| Golang || ✅ <p>With the official Go extension installed.</p> ||| 🟠 <p>Support is currently considered _experimental_.</p> |
40+
| Java | ✅ <p>With maven, google-java-format, and optionally minishift.</p> | ✅ <p>With the official Java, and optionally the Lombok, extensions installed.</p> ||| 🟠 <p>Only supports Spring applications. Support is currently considered _experimental_.</p> |
41+
| Minimal (With no project-specific tooling) |||| 🟠 ||
42+
| NodeJS | ✅ <p>With latest stable node, AWS CLI, and optionally PNPm/Yarn.</p> |||||
43+
| Python | ✅ <p>With Python version 3.9</p> | ✅ <p>With the official Python VSCode extension.</p> || 🟠 ||
4344

4445
<a id="footnote1"><sup>1</sup></a> Marked as fully supported if any non-nix pre-commit hooks are added.
4546
See the Pre-Commit Hooks table below for details.
4647

4748
### Pre-Commit Hooks
4849

49-
| Toolchain\\\\Hook Type | Nix Formatting<sup>[2](#footnote2)</sup> | Formatters | Linters | Testing |
50-
| :--------------------: | :--------------------------------------: | :--------------------------: | :-----: | :---------------: |
51-
| Golang || ✅ <p>go-fmt</p> || ✅ <p>go test</p> |
52-
| Java || ✅ <p>google-java-format</p> |||
53-
| Minimal |||||
54-
| NodeJS || ✅ <p>prettier</p> |||
55-
| Python |||||
50+
| Toolchain\\\\Hook Type | Nix Formatting<sup>[2](#footnote2)</sup> | Formatters | Linters | Testing |
51+
| :--------------------: | :--------------------------------------: | :--------------------------: | :------------------: | :---------------: |
52+
| Elm || ✅ <p>elm-format</p> | ✅ <p>elm-review</p> ||
53+
| Golang || ✅ <p>go-fmt</p> || ✅ <p>go test</p> |
54+
| Java || ✅ <p>google-java-format</p> |||
55+
| Minimal |||||
56+
| NodeJS || ✅ <p>prettier</p> |||
57+
| Python |||||
5658

5759
<a id="footnote2"><sup>2</sup></a> [`alejandra`](https://github.com/kamadorueda/alejandra) is set up to format nix files.
5860

@@ -67,6 +69,8 @@ nix-bootstrap provides configurations for GitLab CI out-of-the-box.
6769
| Pre-Commit Hooks Disabled, Production Build Configured ||||
6870
| Pre-Commit Hooks Enabled, Production Build Configured ||||
6971

72+
For Elm projects, it provides an additional CI job to build the Elm site.
73+
7074
</p>
7175
</details>
7276

nix-bootstrap.cabal

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ cabal-version: 2.0
55
-- see: https://github.com/sol/hpack
66

77
name: nix-bootstrap
8-
version: 1.3.1.3
8+
version: 1.3.2.0
99
author: gchquser
1010
maintainer: [email protected]
1111
copyright: Crown Copyright
@@ -27,6 +27,13 @@ library
2727
Bootstrap.Data.Bootstrappable.BuildNix
2828
Bootstrap.Data.Bootstrappable.DefaultNix
2929
Bootstrap.Data.Bootstrappable.DevContainer
30+
Bootstrap.Data.Bootstrappable.Elm.ElmJson
31+
Bootstrap.Data.Bootstrappable.Elm.IndexHtml
32+
Bootstrap.Data.Bootstrappable.Elm.IndexJs
33+
Bootstrap.Data.Bootstrappable.Elm.MainElm
34+
Bootstrap.Data.Bootstrappable.Elm.PackageJson
35+
Bootstrap.Data.Bootstrappable.Elm.Review.Config
36+
Bootstrap.Data.Bootstrappable.Elm.Review.ElmJson
3037
Bootstrap.Data.Bootstrappable.Envrc
3138
Bootstrap.Data.Bootstrappable.FlakeNix
3239
Bootstrap.Data.Bootstrappable.Gitignore
@@ -90,6 +97,7 @@ library
9097
aeson ==2.0.3.0
9198
, aeson-pretty ==0.8.9
9299
, base ==4.15.1.0
100+
, blaze-html ==0.9.1.2
93101
, dhall ==1.40.2
94102
, directory ==1.3.6.2
95103
, exceptions ==0.10.4
@@ -100,6 +108,7 @@ library
100108
, mtl ==2.2.2
101109
, parser-combinators ==1.3.0
102110
, process ==1.6.13.2
111+
, raw-strings-qq ==1.1
103112
, regex-compat ==0.95.2.1
104113
, relude ==1.0.0.1
105114
, silently ==1.2.5.2
@@ -151,6 +160,13 @@ test-suite nix-bootstrap-test
151160
Bootstrap.Data.Bootstrappable.BuildNixSpec
152161
Bootstrap.Data.Bootstrappable.DefaultNixSpec
153162
Bootstrap.Data.Bootstrappable.DevContainerSpec
163+
Bootstrap.Data.Bootstrappable.Elm.ElmJsonSpec
164+
Bootstrap.Data.Bootstrappable.Elm.IndexHtmlSpec
165+
Bootstrap.Data.Bootstrappable.Elm.IndexJsSpec
166+
Bootstrap.Data.Bootstrappable.Elm.MainElmSpec
167+
Bootstrap.Data.Bootstrappable.Elm.PackageJsonSpec
168+
Bootstrap.Data.Bootstrappable.Elm.Review.ConfigSpec
169+
Bootstrap.Data.Bootstrappable.Elm.Review.ElmJsonSpec
154170
Bootstrap.Data.Bootstrappable.EnvrcSpec
155171
Bootstrap.Data.Bootstrappable.FlakeNixSpec
156172
Bootstrap.Data.Bootstrappable.GitignoreSpec
@@ -198,6 +214,7 @@ test-suite nix-bootstrap-test
198214
build-depends:
199215
QuickCheck ==2.14.2
200216
, base ==4.15.1.0
217+
, dhall ==1.40.2
201218
, hspec ==2.8.5
202219
, hspec-expectations-pretty-diff ==0.7.2.6
203220
, nix-bootstrap

package.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
name: nix-bootstrap
15-
version: 1.3.1.3
15+
version: 1.3.2.0
1616
author: gchquser
1717
maintainer: [email protected]
1818
copyright: Crown Copyright
@@ -60,6 +60,7 @@ library:
6060
dependencies:
6161
- aeson == 2.0.3.0
6262
- aeson-pretty == 0.8.9
63+
- blaze-html == 0.9.1.2
6364
- directory == 1.3.6.2
6465
- dhall == 1.40.2
6566
- exceptions == 0.10.4
@@ -70,6 +71,7 @@ library:
7071
- mtl == 2.2.2
7172
- parser-combinators == 1.3.0
7273
- process == 1.6.13.2
74+
- raw-strings-qq == 1.1
7375
- regex-compat == 0.95.2.1
7476
- silently == 1.2.5.2
7577
- singletons == 3.0.1
@@ -94,6 +96,7 @@ tests:
9496
main: Spec.hs
9597
source-dirs: test
9698
dependencies:
99+
- dhall == 1.40.2
97100
- hspec == 2.8.5
98101
- hspec-expectations-pretty-diff == 0.7.2.6
99102
- nix-bootstrap

src/Bootstrap.hs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@ import Bootstrap.Data.Bootstrappable.DevContainer
2222
devContainerDockerfileFor,
2323
devContainerJsonFor,
2424
)
25+
import Bootstrap.Data.Bootstrappable.Elm.ElmJson (elmJsonFor)
26+
import Bootstrap.Data.Bootstrappable.Elm.IndexHtml (elmIndexHtmlFor)
27+
import Bootstrap.Data.Bootstrappable.Elm.IndexJs (elmIndexJsFor)
28+
import Bootstrap.Data.Bootstrappable.Elm.MainElm (mainElmFor)
29+
import Bootstrap.Data.Bootstrappable.Elm.PackageJson (elmPackageJsonFor)
30+
import Bootstrap.Data.Bootstrappable.Elm.Review.Config
31+
( elmReviewConfigFor,
32+
)
33+
import Bootstrap.Data.Bootstrappable.Elm.Review.ElmJson
34+
( elmReviewElmJsonFor,
35+
)
2536
import Bootstrap.Data.Bootstrappable.Envrc (Envrc (Envrc))
2637
import Bootstrap.Data.Bootstrappable.FlakeNix (flakeNixFor)
2738
import Bootstrap.Data.Bootstrappable.GitPodYml (GitPodYml (GitPodYml))
@@ -75,11 +86,14 @@ import Bootstrap.Data.PreCommitHook (PreCommitHooksConfig (PreCommitHooksConfig,
7586
import Bootstrap.Data.ProjectName (ProjectName, mkProjectName)
7687
import Bootstrap.Data.ProjectType
7788
( ArtefactId (ArtefactId),
89+
ElmMode (ElmModeBare, ElmModeNode),
90+
ElmModeSimple (ElmModeSimpleBare, ElmModeSimpleNode),
91+
ElmOptions (ElmOptions, elmOptionElmMode, elmOptionProvideElmReview),
7892
InstallLombok (InstallLombok),
7993
InstallMinishift (InstallMinishift),
8094
JavaOptions (JavaOptions),
81-
ProjectSuperType (PSTGo, PSTJava, PSTMinimal, PSTNode, PSTPython),
82-
ProjectType (Go, Java, Minimal, Node, Python),
95+
ProjectSuperType (PSTElm, PSTGo, PSTJava, PSTMinimal, PSTNode, PSTPython),
96+
ProjectType (Elm, Go, Java, Minimal, Node, Python),
8397
PythonVersion (Python39),
8498
SetUpGoBuild (SetUpGoBuild),
8599
SetUpJavaBuild (NoJavaBuild, SetUpJavaBuild),
@@ -331,6 +345,19 @@ promptProjectType devContainerConfig = do
331345
superType <- promptChoice "Select a project type:" universe projectSuperTypeName
332346
case superType of
333347
PSTMinimal -> pure Minimal
348+
PSTElm -> do
349+
elmModeSimple <- promptChoice "How would you like to use Elm?" universe \case
350+
ElmModeSimpleBare -> "On its own"
351+
ElmModeSimpleNode -> "As part of a Node application"
352+
elmOptionElmMode <- case elmModeSimple of
353+
ElmModeSimpleBare -> pure ElmModeBare
354+
ElmModeSimpleNode ->
355+
ElmModeNode
356+
<$> promptChoice "Select a node package manager:" universe nodePackageManagerName
357+
elmOptionProvideElmReview <-
358+
promptYesNo
359+
"Would you like to set up elm-review with a default configuration for code quality?"
360+
pure $ Elm ElmOptions {..}
334361
PSTNode -> do
335362
packageManager <- promptChoice "Select a package manager:" universe nodePackageManagerName
336363
pure $ Node packageManager
@@ -432,6 +459,13 @@ makeBuildPlan MakeBuildPlanArgs {..} = do
432459
~: vsCodeSettingsFor mbpDevContainerConfig
433460
~: goModfile
434461
~: pythonRequirementsFile
462+
~: mainElmFor mbpProjectType
463+
~: elmJsonFor mbpProjectType
464+
~: elmReviewElmJsonFor mbpProjectType
465+
~: elmReviewConfigFor mbpProjectType
466+
~: elmPackageJsonFor mbpProjectType
467+
~: elmIndexHtmlFor mbpProjectName mbpProjectType
468+
~: elmIndexJsFor mbpProjectType
435469
~: GitPodYml
436470
~: HNil
437471
)

src/Bootstrap/Data/Bootstrappable.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ module Bootstrap.Data.Bootstrappable
77
)
88
where
99

10-
import Bootstrap.Nix.Expr (Identifier (unIdentifier), IsNixExpr (toNixExpr), isMostlyCorrectlyScoped, writeExprFormatted)
10+
import Bootstrap.Nix.Expr
11+
( Identifier (unIdentifier),
12+
IsNixExpr (toNixExpr),
13+
isMostlyCorrectlyScoped,
14+
writeExprFormatted,
15+
)
1116
import Data.Aeson (ToJSON)
1217
import Data.Aeson.Encode.Pretty
1318
( Config (confCompare),

src/Bootstrap/Data/Bootstrappable/BootstrapState.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Bootstrap.Data.DevContainer (DevContainerConfig, devContainerConfigCodec)
2424
import Bootstrap.Data.PreCommitHook (PreCommitHooksConfig, preCommitHooksConfigCodec)
2525
import Bootstrap.Data.ProjectName (ProjectName)
2626
import qualified Bootstrap.Data.ProjectName as ProjectName
27-
import Bootstrap.Data.ProjectType (ProjectType, projectTypeCodec)
27+
import Bootstrap.Data.ProjectType (ProjectTypeV2, projectTypeCodec)
2828
import Data.Version (showVersion)
2929
import Paths_nix_bootstrap (version)
3030
import Toml (TomlCodec, (.=))
@@ -33,7 +33,7 @@ import qualified Toml
3333
data BootstrapState = BootstrapState
3434
{ stateVersion :: BootstrapVersion,
3535
stateProjectName :: ProjectName,
36-
stateProjectType :: ProjectType,
36+
stateProjectType :: ProjectTypeV2,
3737
statePreCommitHooksConfig :: PreCommitHooksConfig,
3838
stateContinuousIntegrationConfig :: ContinuousIntegrationConfig,
3939
stateDevContainerConfig :: DevContainerConfig,
@@ -74,7 +74,7 @@ newtype BootstrapVersion = BootstrapVersion {unBootstrapVersion :: String}
7474

7575
bootstrapStateFor ::
7676
ProjectName ->
77-
ProjectType ->
77+
ProjectTypeV2 ->
7878
PreCommitHooksConfig ->
7979
ContinuousIntegrationConfig ->
8080
DevContainerConfig ->
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{-# LANGUAGE QuasiQuotes #-}
2+
3+
-- | Copyright : (c) Crown Copyright GCHQ
4+
module Bootstrap.Data.Bootstrappable.Elm.ElmJson
5+
( ElmJson,
6+
elmJsonFor,
7+
)
8+
where
9+
10+
import Bootstrap.Data.Bootstrappable
11+
( Bootstrappable (bootstrapContent, bootstrapName, bootstrapReason),
12+
bootstrapContentPrettyJson,
13+
)
14+
import Bootstrap.Data.ProjectType (ProjectType (Elm))
15+
import Data.Aeson (ToJSON (toJSON))
16+
import Data.Aeson.QQ.Simple (aesonQQ)
17+
18+
data ElmJson = ElmJson
19+
20+
instance Bootstrappable ElmJson where
21+
bootstrapName = const "elm.json"
22+
bootstrapReason = const "The configuration of your elm project"
23+
bootstrapContent = bootstrapContentPrettyJson ["type", "source-directories", "elm-version"]
24+
25+
instance ToJSON ElmJson where
26+
toJSON ElmJson =
27+
[aesonQQ|{
28+
"type": "application",
29+
"source-directories": [
30+
"src"
31+
],
32+
"elm-version": "0.19.1",
33+
"dependencies": {
34+
"direct": {
35+
"elm/browser": "1.0.2",
36+
"elm/core": "1.0.5",
37+
"elm/html": "1.0.0"
38+
},
39+
"indirect": {
40+
"elm/json": "1.1.3",
41+
"elm/time": "1.0.0",
42+
"elm/url": "1.0.0",
43+
"elm/virtual-dom": "1.0.3"
44+
}
45+
},
46+
"test-dependencies": {
47+
"direct": {},
48+
"indirect": {}
49+
}
50+
}
51+
|]
52+
53+
elmJsonFor :: ProjectType -> Maybe ElmJson
54+
elmJsonFor = \case
55+
Elm _ -> Just ElmJson
56+
_ -> Nothing
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
-- | Copyright : (c) Crown Copyright GCHQ
2+
module Bootstrap.Data.Bootstrappable.Elm.IndexHtml
3+
( ElmIndexHtml,
4+
elmIndexHtmlFor,
5+
)
6+
where
7+
8+
import Bootstrap.Data.Bootstrappable
9+
( Bootstrappable (bootstrapContent, bootstrapName, bootstrapReason),
10+
)
11+
import Bootstrap.Data.ProjectName (ProjectName (unProjectName))
12+
import Bootstrap.Data.ProjectType (ElmMode (ElmModeNode), ElmOptions (ElmOptions), ProjectType (Elm))
13+
import Text.Blaze.Html.Renderer.Pretty (renderHtml)
14+
import Text.Blaze.XHtml5 ((!))
15+
import qualified Text.Blaze.XHtml5 as H
16+
import qualified Text.Blaze.XHtml5.Attributes as HAttr
17+
18+
newtype ElmIndexHtml = ElmIndexHtml ProjectName
19+
20+
instance Bootstrappable ElmIndexHtml where
21+
bootstrapName = const "src/index.html"
22+
bootstrapReason = const "The top-level HTML file for your site"
23+
bootstrapContent (ElmIndexHtml projectName) =
24+
pure . Right . toText . renderHtml $ H.docTypeHtml do
25+
H.head do
26+
H.meta ! HAttr.charset "utf-8"
27+
H.title . H.toHtml $ unProjectName projectName
28+
H.script ! HAttr.type_ "module" ! HAttr.src "./index.js" $ mempty
29+
H.body $ H.div ! HAttr.id "root" $ mempty
30+
31+
elmIndexHtmlFor :: ProjectName -> ProjectType -> Maybe ElmIndexHtml
32+
elmIndexHtmlFor projectName = \case
33+
Elm (ElmOptions (ElmModeNode _) _) -> Just $ ElmIndexHtml projectName
34+
_ -> Nothing

0 commit comments

Comments
 (0)