Skip to content

Commit

Permalink
feat: pre-commit and github action generate commands
Browse files Browse the repository at this point in the history
Fixes #2115
Fixes #1692
  • Loading branch information
jdx committed May 19, 2024
1 parent d40f58b commit 6b28c8f
Show file tree
Hide file tree
Showing 18 changed files with 452 additions and 2 deletions.
1 change: 0 additions & 1 deletion .node-version

This file was deleted.

61 changes: 61 additions & 0 deletions docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,67 @@ Examples:
$ mise x -C /path/to/project node@20 -- node ./app.js
```

## `mise generate git-pre-commit [OPTIONS]`

```text
[experimental] Generate a git pre-commit hook
This command generates a git pre-commit hook that runs a mise task like `mise run pre-commit`
when you commit changes to your repository.
Usage: generate git-pre-commit [OPTIONS]
Options:
--hook <HOOK>
Which hook to generate (saves to .git/hooks/$hook)
[default: pre-commit]
-t, --task <TASK>
The task to run when the pre-commit hook is triggered
[default: pre-commit]
-w, --write
write to .git/hooks/pre-commit and make it executable
Examples:
$ mise generate git-pre-commit --write --task=pre-commit
$ git commit -m "feat: add new feature" # runs `mise run pre-commit`
```

## `mise generate github-action [OPTIONS]`

```text
[experimental] Generate a Github Action workflow file
This command generates a Github Action workflow file that runs a mise task like `mise run ci`
when you push changes to your repository.
Usage: generate github-action [OPTIONS]
Options:
-n, --name <NAME>
the name of the workflow to generate
[default: ci]
-t, --task <TASK>
The task to run when the workflow is triggered
[default: ci]
-w, --write
write to .github/workflows/$name.yml
Examples:
$ mise generate github-action --write --task=ci
$ git commit -m "feat: add new feature"
$ git push # runs `mise run ci` on Github
```

## `mise implode [OPTIONS]`

```text
Expand Down
4 changes: 4 additions & 0 deletions docs/registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ editLink: false
| jmespath | <https://github.com/skyzyx/asdf-jmespath> |
| jmeter | <https://github.com/comdotlinux/asdf-jmeter> |
| jnv | <https://github.com/raimon49/asdf-jnv> |
| jq | <https://github.com/mise-plugins/asdf-jq> |
| jqp | <https://gitlab.com/wt0f/asdf-jqp> |
| jreleaser | <https://github.com/joschi/asdf-jreleaser> |
| jsonnet | <https://github.com/Banno/asdf-jsonnet> |
Expand Down Expand Up @@ -606,7 +607,9 @@ editLink: false
| serverless | <https://github.com/pdemagny/asdf-serverless> |
| setup-envtest | <https://github.com/pmalek/mise-setup-envtest> |
| shell2http | <https://github.com/ORCID/asdf-shell2http> |
| shellcheck | <https://github.com/luizm/asdf-shellcheck> |
| shellspec | <https://github.com/poikilotherm/asdf-shellspec> |
| shfmt | <https://github.com/luizm/asdf-shfmt> |
| shorebird | <https://github.com/valian-ca/asdf-shorebird> |
| sinker | <https://github.com/elementalvoid/asdf-sinker> |
| skaffold | <https://github.com/nklmilojevic/asdf-skaffold> |
Expand Down Expand Up @@ -692,6 +695,7 @@ editLink: false
| thrift | <https://github.com/alisaifee/asdf-thrift> |
| tilt | <https://github.com/eaceaser/asdf-tilt> |
| timoni | <https://github.com/Smana/asdf-timoni> |
| tiny | <https://github.com/mise-plugins/mise-tiny> |
| tinytex | <https://github.com/Fbrisset/asdf-tinytex> |
| titan | <https://github.com/gabitchov/asdf-titan> |
| tlsg-cli | <https://github.com/0ghny/asdf-tlsgcli> |
Expand Down
1 change: 1 addition & 0 deletions e2e/forge/test_npm
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ require_cmd npm

export NPM_CONFIG_FUND=false

mise use node
assert "mise x npm:prettier@3.1.0 -- prettier -v" "3.1.0"
assert "FORCE_COLOR=0 mise x npm:@antfu/ni@0.21.12 -- ni -v 2>/dev/null | head -n1" "@antfu/ni v0.21.12"
3 changes: 3 additions & 0 deletions man/man1/mise.1
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ Exports env vars to activate mise a single time
mise\-exec(1)
Execute a command with tool(s) set
.TP
mise\-generate(1)
[experimental] Generate files for various tools/services
.TP
mise\-implode(1)
Removes mise CLI and all related data
.TP
Expand Down
40 changes: 40 additions & 0 deletions mise.usage.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,46 @@ The "--" separates runtimes from the commands to pass along to the subprocess."#
arg "[TOOL@VERSION]..." help="Tool(s) to start e.g.: node@20 python@3.10" var=true
arg "[COMMAND]..." help="Command string to execute (same as --command)" var=true
}
cmd "generate" subcommand_required=true help="[experimental] Generate files for various tools/services" {
cmd "git-pre-commit" help="[experimental] Generate a git pre-commit hook" {
alias "pre-commit" hide=true
long_help r"[experimental] Generate a git pre-commit hook

This command generates a git pre-commit hook that runs a mise task like `mise run pre-commit`
when you commit changes to your repository."
after_long_help r#"Examples:

$ mise generate git-pre-commit --write --task=pre-commit
$ git commit -m "feat: add new feature" # runs `mise run pre-commit`
"#
flag "--hook" help="Which hook to generate (saves to .git/hooks/$hook)" {
arg "<HOOK>"
}
flag "-t --task" help="The task to run when the pre-commit hook is triggered" {
arg "<TASK>"
}
flag "-w --write" help="write to .git/hooks/pre-commit and make it executable"
}
cmd "github-action" help="[experimental] Generate a Github Action workflow file" {
long_help r"[experimental] Generate a Github Action workflow file

This command generates a Github Action workflow file that runs a mise task like `mise run ci`
when you push changes to your repository."
after_long_help r#"Examples:

$ mise generate github-action --write --task=ci
$ git commit -m "feat: add new feature"
$ git push # runs `mise run ci` on Github
"#
flag "-n --name" help="the name of the workflow to generate" {
arg "<NAME>"
}
flag "-t --task" help="The task to run when the workflow is triggered" {
arg "<TASK>"
}
flag "-w --write" help="write to .github/workflows/$name.yml"
}
}
cmd "global" hide=true help="Sets/gets the global tool version(s)" {
alias "g" hide=true
long_help r"Sets/gets the global tool version(s)
Expand Down
82 changes: 82 additions & 0 deletions src/cli/generate/git_pre_commit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use xx::file::display_path;

use crate::config::Settings;
use crate::file;
use crate::git::Git;

/// [experimental] Generate a git pre-commit hook
///
/// This command generates a git pre-commit hook that runs a mise task like `mise run pre-commit`
/// when you commit changes to your repository.
#[derive(Debug, clap::Args)]
#[clap(verbatim_doc_comment, alias = "pre-commit", after_long_help = AFTER_LONG_HELP)]
pub struct GitPreCommit {
/// Which hook to generate (saves to .git/hooks/$hook)
#[clap(long, default_value = "pre-commit")]
hook: String,
/// The task to run when the pre-commit hook is triggered
#[clap(long, short, default_value = "pre-commit")]
task: String,
/// write to .git/hooks/pre-commit and make it executable
#[clap(long, short)]
write: bool,
}

impl GitPreCommit {
pub fn run(self) -> eyre::Result<()> {
let settings = Settings::get();
settings.ensure_experimental("generate git-pre-commit")?;
let output = self.generate();
if self.write {
let path = Git::get_root()?.join(".git/hooks").join(&self.hook);
file::write(&path, &output)?;
file::make_executable(&path)?;
miseprintln!("Wrote to {}", display_path(&path));
} else {
miseprintln!("{output}");
}
Ok(())
}

fn generate(&self) -> String {
let task = &self.task;
format!(
r#"#!/bin/sh
mise run {task}
"#
)
}
}

static AFTER_LONG_HELP: &str = color_print::cstr!(
r#"<bold><underline>Examples:</underline></bold>
$ <bold>mise generate git-pre-commit --write --task=pre-commit</bold>
$ <bold>git commit -m "feat: add new feature"</bold> <dim># runs `mise run pre-commit`</dim>
"#
);

#[cfg(test)]
mod tests {
use test_log::test;

use crate::file;
use crate::git::Git;
use crate::test::{cleanup, reset, setup_git_repo};

#[test]
fn test_git_pre_commit() {
reset();
assert_cli_snapshot!("generate", "pre-commit", "--task=testing123");
}
#[test]
fn test_git_pre_commit_write() {
reset();
setup_git_repo();
assert_cli_snapshot!("generate", "pre-commit", "-w", "--hook", "testing123");
let path = Git::get_root().unwrap().join(".git/hooks/testing123");
assert_snapshot!(file::read_to_string(&path).unwrap());
assert!(file::is_executable(&path));
cleanup();
}
}
116 changes: 116 additions & 0 deletions src/cli/generate/github_action.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
use xx::file;

use crate::config::Settings;
use crate::file::display_path;
use crate::git::Git;

/// [experimental] Generate a Github Action workflow file
///
/// This command generates a Github Action workflow file that runs a mise task like `mise run ci`
/// when you push changes to your repository.
#[derive(Debug, clap::Args)]
#[clap(verbatim_doc_comment, after_long_help = AFTER_LONG_HELP)]
pub struct GithubAction {
/// the name of the workflow to generate
#[clap(long, short, default_value = "ci")]
name: String,
/// The task to run when the workflow is triggered
#[clap(long, short, default_value = "ci")]
task: String,
/// write to .github/workflows/$name.yml
#[clap(long, short)]
write: bool,
}

impl GithubAction {
pub fn run(self) -> eyre::Result<()> {
let settings = Settings::get();
settings.ensure_experimental("generate github-action")?;
let output = self.generate()?;
if self.write {
let path = Git::get_root()?
.join(".github/workflows")
.join(format!("{}.yml", &self.name));
file::write(&path, &output)?;
miseprintln!("Wrote to {}", display_path(&path));
} else {
miseprintln!("{output}");
}
Ok(())
}

fn generate(&self) -> eyre::Result<String> {
let branch = Git::new(Git::get_root()?).current_branch()?;
let name = &self.name;
let task = &self.task;
Ok(format!(
r#"name: {name}
on:
workflow_dispatch:
pull_request:
push:
tags: ["*"]
branches: ["{branch}"]
concurrency:
group: ${{{{ github.workflow }}}}-${{{{ github.ref }}}}
cancel-in-progress: true
env:
MISE_EXPERIMENTAL: true
jobs:
{name}:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: jdx/mise-action@v2
- run: mise run {task}
"#
))
}
}

static AFTER_LONG_HELP: &str = color_print::cstr!(
r#"<bold><underline>Examples:</underline></bold>
$ <bold>mise generate github-action --write --task=ci</bold>
$ <bold>git commit -m "feat: add new feature"</bold>
$ <bold>git push</bold> <dim># runs `mise run ci` on Github</dim>
"#
);

#[cfg(test)]
mod tests {
use test_log::test;

use crate::file;
use crate::git::Git;
use crate::test::{cleanup, reset, setup_git_repo};

#[test]
fn test_github_action() {
reset();
assert_cli_snapshot!("generate", "github-action");
}
#[test]
fn test_github_action_write() {
reset();
setup_git_repo();
assert_cli_snapshot!(
"generate",
"github-action",
"-w",
"-ttesting123",
"-n=testing123"
);
let path = Git::get_root()
.unwrap()
.join(".github/workflows/testing123.yml");
let contents = file::read_to_string(&path).unwrap();
assert_snapshot!(contents);
cleanup();
}
}
32 changes: 32 additions & 0 deletions src/cli/generate/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use clap::Subcommand;

mod git_pre_commit;
mod github_action;

/// [experimental] Generate files for various tools/services
#[derive(Debug, clap::Args)]
pub struct Generate {
#[clap(subcommand)]
command: Commands,
}

#[derive(Debug, Subcommand)]
enum Commands {
GitPreCommit(git_pre_commit::GitPreCommit),
GithubAction(github_action::GithubAction),
}

impl Commands {
pub fn run(self) -> eyre::Result<()> {
match self {
Self::GitPreCommit(cmd) => cmd.run(),
Self::GithubAction(cmd) => cmd.run(),
}
}
}

impl Generate {
pub fn run(self) -> eyre::Result<()> {
self.command.run()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
source: src/cli/generate/git_pre_commit.rs
expression: output
---
#!/bin/sh
mise run testing123
Loading

0 comments on commit 6b28c8f

Please sign in to comment.