Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions installers/linux/packages/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
elm-stuff
work
out
3 changes: 3 additions & 0 deletions installers/linux/packages/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"elmLS.elmFormatPath": "elm-format-hack"
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidental commit?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nooot really? The Do helpers for elm-pages kinda require elm-format-hack to produce sensible formatting

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right I see. That makes me like the <| \_ -> incantation even less compared to the passthrough variant approach we use in lamdera/script... first person to edit the script is going to get a surprise when the formatting kicks in 😅

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you deal with using the result of previous steps usually? To be fair, this script mostly does <| \_ ->, where a passthrough would work, but what if you actually care about the result instead of ignoring it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've got examples in runtime builds – I'll DM you.

3 changes: 3 additions & 0 deletions installers/linux/packages/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To run the packaging script: `npx elm-pages run src/Main.elm`.

This will put the results in the `out` folder.
60 changes: 60 additions & 0 deletions installers/linux/packages/elm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"dillonkearns/elm-cli-options-parser": "3.2.0",
"dillonkearns/elm-pages": "10.2.2",
"elm/bytes": "1.0.8",
"elm/core": "1.0.5",
"elm/json": "1.1.3",
"elmcraft/core-extra": "2.2.0",
"wolfadex/elm-ansi": "3.0.0"
},
"indirect": {
"Chadtech/elm-bool-extra": "2.4.2",
"avh4/elm-color": "1.0.0",
"danfishgold/base64-bytes": "1.1.0",
"danyx23/elm-mimetype": "4.0.1",
"dillonkearns/elm-bcp47-language-tag": "2.0.0",
"dillonkearns/elm-date-or-date-time": "2.0.0",
"dillonkearns/elm-form": "3.0.1",
"elm/browser": "1.0.2",
"elm/file": "1.0.5",
"elm/html": "1.0.0",
"elm/http": "2.0.0",
"elm/parser": "1.1.0",
"elm/random": "1.0.0",
"elm/regex": "1.0.0",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.4",
"elm-community/basics-extra": "4.1.0",
"elm-community/list-extra": "8.7.0",
"elm-community/maybe-extra": "5.3.0",
"fredcy/elm-parseint": "2.0.1",
"jluckyiv/elm-utc-date-strings": "1.0.0",
"justinmimbs/date": "4.1.0",
"mdgriffith/elm-codegen": "5.2.0",
"miniBill/elm-codec": "2.3.0",
"miniBill/elm-unicode": "1.1.1",
"noahzgordon/elm-color-extra": "1.0.2",
"robinheghan/fnv1a": "1.0.0",
"robinheghan/murmur3": "1.0.0",
"rtfeldman/elm-css": "18.0.0",
"rtfeldman/elm-hex": "1.0.0",
"rtfeldman/elm-iso8601-date-strings": "1.1.4",
"stil4m/elm-syntax": "7.3.9",
"stil4m/structured-writer": "1.0.3",
"the-sett/elm-pretty-printer": "3.1.1",
"the-sett/elm-syntax-dsl": "6.0.3"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}
191 changes: 191 additions & 0 deletions installers/linux/packages/src/Main.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
module Main exposing (run)

import Ansi.Color
import BackendTask exposing (BackendTask)
import BackendTask.Do as Do
import FatalError exposing (FatalError)
import Json.Encode
import Packages exposing (Arch(..), Package)
import Pages.Script as Script exposing (Script)


run : Script
run =
Script.withoutCliOptions task


task : BackendTask FatalError ()
task =
logExec "👷 Creating temporary work directory" "mkdir" [ "-p", "work" ] <| \_ ->
logExec "👷 Creating output directory" "mkdir" [ "-p", "out" ] <| \_ ->
Do.each Packages.packages
(\({ name, version, url, arch } as package) ->
let
fullName : String
fullName =
name ++ "-" ++ version ++ "-" ++ archToDebian arch

binaryPath : String
binaryPath =
"work/" ++ fullName
in
Do.log (Ansi.Color.fontColor Ansi.Color.brightYellow ("🏃 " ++ fullName)) <| \_ ->
logExecs " 🔽 Downloading"
[ ( "curl", [ url, "-sSL", "-o", binaryPath ] )
, ( "chmod", [ "+x", binaryPath ] )
]
<| \_ ->
logExec " 🕵️ Verifying hash" "sha256sum" [ binaryPath ] <| \actualHash ->
let
expectedHash : String
expectedHash =
package.hash ++ " " ++ binaryPath
in
if String.trim actualHash == expectedHash then
Do.do (prepareDeb { package = package, binaryPath = binaryPath }) <| \_ ->
Do.noop

else
BackendTask.fail
(FatalError.fromString
("Invalid hash:\n expected: "
++ expectedHash
++ ",\n got: "
++ String.trim actualHash
)
)
)
<| \_ ->
logExec "🧹 Cleaning up temporary work directory" "rm" [ "-r", "work" ] <| \_ ->
Do.noop


archToDebian : Arch -> String
archToDebian arch =
case arch of
X86_64 ->
"amd64"

Arm64 ->
"aarch64"


prepareDeb : { package : Package, binaryPath : String } -> BackendTask FatalError ()
prepareDeb { package, binaryPath } =
let
revision : String
revision =
"1"

debName : String
debName =
package.name ++ "_" ++ package.version ++ "-" ++ revision

debPath : String
debPath =
"work/" ++ debName
in
logExecs " 🌀 📁 Preparing folders for .deb "
[ ( "rm", [ "-rf", debPath ] )
, ( "mkdir", [ "-p", debPath ++ "/usr/local/bin" ] )
, ( "cp", [ binaryPath, debPath ++ "/usr/local/bin/" ++ package.name ] )
, ( "mkdir", [ debPath ++ "/DEBIAN" ] )
]
<| \_ ->
logCyan " 🌀 📰 Writing DEBIAN/control file" <| \_ ->
Do.allowFatal
(Script.writeFile
{ path = debPath ++ "/DEBIAN/control"
, body = controlFile { package = package, revision = revision }
}
)
<| \_ ->
logExecs " 🌀 📦 Creating the package"
[ ( "dpkg-deb", [ "--root-owner-group", "--build", debPath, "out/" ++ debName ++ "_" ++ archToDebian package.arch ++ ".deb" ] ) ]
<| \_ ->
Do.noop


controlFile : { package : Package, revision : String } -> String
controlFile { package, revision } =
[ "Package: " ++ package.name
, "Version: " ++ package.version ++ "-" ++ revision
, "Section: base"
, "Priority: optional"
, "Architecture: " ++ archToDebian package.arch

-- , "Depends:"
, "Maintainer: " ++ package.maintainer
, "Description: " ++ package.description
, ""
]
|> String.join "\n"


logExec : String -> String -> List String -> (String -> BackendTask FatalError a) -> BackendTask FatalError a
logExec msg cmd args k =
logCyan msg <| \_ ->
Do.log (formatCmd cmd args) <| \_ ->
Do.command cmd args k


logExecs : String -> List ( String, List String ) -> (() -> BackendTask FatalError a) -> BackendTask FatalError a
logExecs msg cmds k =
logCyan msg <| \_ ->
Do.each cmds
(\( cmd, args ) ->
Do.log (formatCmd cmd args) <| \_ ->
Do.exec cmd args <| \_ ->
Do.noop
)
<| \_ ->
k ()


logCyan : String -> ((() -> BackendTask FatalError a) -> BackendTask FatalError a)
logCyan msg =
Do.log (Ansi.Color.fontColor Ansi.Color.cyan msg)


formatCmd : String -> List String -> String
formatCmd cmd args =
String.join " " <|
" "
:: Ansi.Color.fontColor Ansi.Color.green (escapeMaybe cmd)
:: List.map
(\arg ->
let
escaped : String
escaped =
escapeMaybe arg
in
if String.startsWith "\"" escaped then
Ansi.Color.fontColor Ansi.Color.yellow escaped

else if String.startsWith "-" escaped then
Ansi.Color.fontColor
(Ansi.Color.rgb
{ blue = 0xB0
, green = 0xB0
, red = 0xB0
}
)
escaped

else
Ansi.Color.fontColor Ansi.Color.brightWhite escaped
)
args


escapeMaybe : String -> String
escapeMaybe input =
let
escaped =
input |> Json.Encode.string |> Json.Encode.encode 0
in
if not (String.contains " " input) && escaped == "\"" ++ input ++ "\"" then
input

else
escaped
Loading