Skip to content

Commit

Permalink
more cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
bwireman committed Jul 7, 2024
1 parent 37ce701 commit 8456eb3
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 61 deletions.
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
gleam 1.2.1
erlang 27.0
nodejs 20.14.0
deno 1.44.2
deno 1.44.4
14 changes: 10 additions & 4 deletions src/cactus.gleam
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import cactus/run
import cactus/util.{type CactusErr, CLIErr, as_fs_err, str}
import cactus/util.{
type CactusErr, CLIErr, as_fs_err, err_as_str, join_text, quote,
}
import cactus/write
import filepath
import gleam/io
Expand Down Expand Up @@ -46,10 +48,14 @@ pub fn main() -> Result(Nil, CactusErr) {

case res {
Ok(_) -> Nil
Error(CLIErr(err)) -> {
io.println_error(err_as_str(CLIErr(err)))
shellout.exit(1)
}
Error(reason) -> {
io.println_error(
util.quote(cmd) <> " hook failed. Reason: " <> str(reason),
)
[quote(cmd), "hook failed. Reason:", err_as_str(reason)]
|> join_text()
|> io.println_error()
shellout.exit(1)
}
}
Expand Down
87 changes: 45 additions & 42 deletions src/cactus/run.gleam
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import cactus/util.{
type CactusErr, ActionFailedErr, InvalidFieldErr, as_invalid_field_err, cactus,
join_text, parse_gleam_toml, quote,
}
import gleam/dict.{type Dict}
import gleam/io
Expand All @@ -15,16 +16,6 @@ const actions = "actions"

const gleam = "gleam"

pub type ActionKind {
Module
SubCommand
Binary
}

pub type Action {
Action(command: String, kind: ActionKind, args: List(String))
}

fn do_parse_kind(kind: String) -> Result(ActionKind, CactusErr) {
case kind {
"module" -> Ok(Module)
Expand All @@ -34,9 +25,11 @@ fn do_parse_kind(kind: String) -> Result(ActionKind, CactusErr) {
Error(InvalidFieldErr(
Some("kind"),
Right(
"got: "
<> util.quote(kind)
<> " expected: one of ['sub_command', 'binary', or 'module']",
join_text([
"got:",
quote(kind),
"expected: one of ['sub_command', 'binary', or 'module']",
]),
),
))
}
Expand All @@ -60,6 +53,44 @@ fn do_parse_action(t: Dict(String, Toml)) -> Result(Action, CactusErr) {
Action(command: command, kind: action_kind, args: args)
}

fn do_run(action: Action) {
let #(bin, args) = case action.kind {
Module -> #(gleam, ["run", "-m", action.command, "--", ..action.args])
SubCommand -> #(gleam, [action.command, ..action.args])
Binary -> #(action.command, action.args)
}

io.println(join_text(["Running", bin, ..args]))
case shellout.command(run: bin, with: args, in: ".", opt: []) {
Ok(res) -> {
io.print(res)
Ok(res)
}
Error(#(_, err)) -> Error(ActionFailedErr(err))
}
}

fn as_string(t: Toml) -> Result(String, CactusErr) {
case t {
tom.String(v) -> Ok(v)
_ ->
Error(InvalidFieldErr(
Some("args"),
Right("'args' was not a list of strings"),
))
}
}

pub type ActionKind {
Module
SubCommand
Binary
}

pub type Action {
Action(command: String, kind: ActionKind, args: List(String))
}

pub fn parse_action(raw: Toml) -> Result(Action, CactusErr) {
case raw {
tom.InlineTable(t) -> do_parse_action(t)
Expand All @@ -76,45 +107,17 @@ pub fn get_actions(
path: String,
action: String,
) -> Result(List(Toml), CactusErr) {
use manifest <- try(util.parse_gleam_toml(path))
use manifest <- try(parse_gleam_toml(path))
use action_body <- try(
as_invalid_field_err(tom.get_table(manifest, [cactus, action])),
)
as_invalid_field_err(tom.get_array(action_body, [actions]))
}

fn do_run(action: Action) {
let #(bin, args) = case action.kind {
Module -> #(gleam, ["run", "-m", action.command, "--", ..action.args])
SubCommand -> #(gleam, [action.command, ..action.args])
Binary -> #(action.command, action.args)
}

io.println(string.join(["Running", bin, ..args], " "))
case shellout.command(run: bin, with: args, in: ".", opt: []) {
Ok(res) -> {
io.print(res)
Ok(res)
}
Error(#(_, err)) -> Error(ActionFailedErr(err))
}
}

pub fn run(path: String, action: String) -> Result(List(String), CactusErr) {
use actions <- try(get_actions(path, action))
actions
|> list.map(parse_action)
|> list.map(result.try(_, do_run))
|> result.all
}

pub fn as_string(t: Toml) -> Result(String, CactusErr) {
case t {
tom.String(v) -> Ok(v)
_ ->
Error(InvalidFieldErr(
Some("args"),
Right("'args' was not a list of strings"),
))
}
}
24 changes: 15 additions & 9 deletions src/cactus/util.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,23 @@ pub fn as_fs_err(
}
}

pub fn str(err: CactusErr) -> String {
pub fn err_as_str(err: CactusErr) -> String {
case err {
InvalidFieldErr(_, Left(NotFound(keys))) ->
"Missing field in config: " <> quote(string.join(keys, "."))

InvalidFieldErr(_, Left(WrongType(keys, expected, got))) ->
"Invalid field in config: "
<> quote(string.join(keys, "."))
<> " expected: "
<> quote(expected)
<> " got "
<> quote(got)
join_text([
"Invalid field in config:",
quote(string.join(keys, ".")),
"expected:",
quote(expected),
"got:",
quote(got),
])

InvalidFieldErr(Some(field), Right(err)) ->
"Invalid field in config: " <> field <> " " <> err
join_text(["Invalid field in config:", field, err])

InvalidFieldErr(None, Right(err)) -> "Invalid field in config: " <> err

Expand All @@ -61,7 +63,7 @@ pub fn str(err: CactusErr) -> String {
ActionFailedErr(output) -> "Action Failed Error:\n" <> output

FSErr(path, err) ->
"FS Error at " <> path <> " with " <> describe_error(err)
join_text(["FS Error at", path, "with", describe_error(err)])

CLIErr(arg) -> "CLI Error: invalid arg " <> quote(arg)

Expand All @@ -77,3 +79,7 @@ pub fn parse_gleam_toml(path: String) -> Result(Dict(String, Toml), CactusErr) {
use body <- result.try(as_fs_err(simplifile.read(path), path))
tom.parse(body) |> as_err(InvalidTomlErr)
}

pub fn join_text(text: List(String)) -> String {
string.join(text, " ")
}
13 changes: 8 additions & 5 deletions src/cactus/write.gleam
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import cactus/util.{type CactusErr, as_fs_err, as_invalid_field_err, cactus}
import cactus/util.{
type CactusErr, as_fs_err, as_invalid_field_err, cactus, parse_gleam_toml,
quote,
}
import filepath
import gleam/dict
import gleam/io
Expand All @@ -8,14 +11,14 @@ import gleam/set
import simplifile
import tom

pub const tmpl = "gleam run -m cactus -- "

const valid_hooks = [
"applypatch-msg", "commit-msg", "fsmonitor-watchman", "post-update",
"pre-applypatch", "pre-commit", "pre-merge-commit", "prepare-commit-msg",
"pre-push", "pre-rebase", "pre-receive", "push-to-checkout", "update", "test",
]

pub const tmpl = "gleam run -m cactus -- "

pub fn is_valid_hook_name(name: String) -> Bool {
list.contains(valid_hooks, name)
}
Expand All @@ -24,7 +27,7 @@ pub fn create_script(
hooks_dir: String,
command: String,
) -> Result(String, CactusErr) {
io.println("Initializing hook: " <> util.quote(command))
io.println("Initializing hook: " <> quote(command))
let path = filepath.join(hooks_dir, command)
let all =
set.from_list([simplifile.Read, simplifile.Write, simplifile.Execute])
Expand All @@ -43,7 +46,7 @@ pub fn create_script(

pub fn init(hooks_dir: String, path: String) -> Result(List(String), CactusErr) {
{
use manifest <- try(util.parse_gleam_toml(path))
use manifest <- try(parse_gleam_toml(path))
use action_body <- result.map(
as_invalid_field_err(tom.get_table(manifest, [cactus])),
)
Expand Down

0 comments on commit 8456eb3

Please sign in to comment.