mirror of https://github.com/jdx/mise
feat: add devcontainer generator (#4355)
- Add generator to provide a devcontainer compatible with mise - Name / image / mount are customizable - Add "homebrew" path for **wsl** / **linux** in the e2e tests --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
fc70f04ec8
commit
9d69158c1f
|
@ -122,6 +122,9 @@ export const commands: { [key: string]: Command } = {
|
|||
config: {
|
||||
hide: false,
|
||||
},
|
||||
devcontainer: {
|
||||
hide: false,
|
||||
},
|
||||
"git-pre-commit": {
|
||||
hide: false,
|
||||
},
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
- [`mise generate bootstrap [FLAGS]`](/cli/generate/bootstrap.md)
|
||||
- [`mise generate config [-t --tool-versions <TOOL_VERSIONS>] [-o --output <OUTPUT>]`](/cli/generate/config.md)
|
||||
- [`mise generate devcontainer [FLAGS]`](/cli/generate/devcontainer.md)
|
||||
- [`mise generate git-pre-commit [FLAGS]`](/cli/generate/git-pre-commit.md)
|
||||
- [`mise generate github-action [FLAGS]`](/cli/generate/github-action.md)
|
||||
- [`mise generate task-docs [FLAGS]`](/cli/generate/task-docs.md)
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# `mise generate devcontainer`
|
||||
|
||||
- **Usage**: `mise generate devcontainer [FLAGS]`
|
||||
- **Source code**: [`src/cli/generate/devcontainer.rs`](https://github.com/jdx/mise/blob/main/src/cli/generate/devcontainer.rs)
|
||||
|
||||
[experimental] Generate a devcontainer to execute mise
|
||||
|
||||
## Flags
|
||||
|
||||
### `-n --name <NAME>`
|
||||
|
||||
The name of the devcontainer
|
||||
|
||||
### `-i --image <IMAGE>`
|
||||
|
||||
The image to use for the devcontainer
|
||||
|
||||
### `-m --mount-mise-data`
|
||||
|
||||
Bind the mise-data-volume to the devcontainer
|
||||
|
||||
### `-w --write`
|
||||
|
||||
write to .devcontainer/devcontainer.json
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
mise generate devcontainer
|
||||
```
|
|
@ -86,6 +86,7 @@ Can also use `MISE_NO_CONFIG=1`
|
|||
- [`mise generate <SUBCOMMAND>`](/cli/generate.md)
|
||||
- [`mise generate bootstrap [FLAGS]`](/cli/generate/bootstrap.md)
|
||||
- [`mise generate config [-t --tool-versions <TOOL_VERSIONS>] [-o --output <OUTPUT>]`](/cli/generate/config.md)
|
||||
- [`mise generate devcontainer [FLAGS]`](/cli/generate/devcontainer.md)
|
||||
- [`mise generate git-pre-commit [FLAGS]`](/cli/generate/git-pre-commit.md)
|
||||
- [`mise generate github-action [FLAGS]`](/cli/generate/github-action.md)
|
||||
- [`mise generate task-docs [FLAGS]`](/cli/generate/task-docs.md)
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Default devcontainer
|
||||
|
||||
assert_json_partial_object "mise generate devcontainer" "name,description,features,mounts,container_env" "
|
||||
{
|
||||
\"name\": \"mise\",
|
||||
\"image\": \"mcr.microsoft.com/devcontainers/base:ubuntu\",
|
||||
\"features\": {
|
||||
\"ghcr.io/devcontainers-extra/features/mise:1\": {}
|
||||
},
|
||||
\"mounts\": [],
|
||||
\"container_env\": {}
|
||||
}
|
||||
"
|
||||
|
||||
# With custom name and image
|
||||
assert_json_partial_object "mise generate devcontainer --name test --image testimage:latest" "name,description" "
|
||||
{
|
||||
\"name\": \"test\",
|
||||
\"image\": \"testimage:latest\"
|
||||
}
|
||||
"
|
||||
|
||||
# With mount
|
||||
assert_json_partial_object "mise generate devcontainer --mount-mise-data" "name,description,features,mounts,container_env" "
|
||||
{
|
||||
\"name\": \"mise\",
|
||||
\"image\": \"mcr.microsoft.com/devcontainers/base:ubuntu\",
|
||||
\"features\": {
|
||||
\"ghcr.io/devcontainers-extra/features/mise:1\": {}
|
||||
},
|
||||
\"mounts\": [
|
||||
{
|
||||
\"source\": \"mise-data-volume\",
|
||||
\"target\": \"/mnt/mise-data\",
|
||||
\"type\": \"volume\"
|
||||
}
|
||||
],
|
||||
\"container_env\": {
|
||||
\"MISE_DATA_VOLUME\": \"/mnt/mise-data\"
|
||||
}
|
||||
}
|
||||
"
|
|
@ -75,7 +75,7 @@ within_isolated_env() {
|
|||
MISE_TRUSTED_CONFIG_PATHS="$TEST_ISOLATED_DIR" \
|
||||
MISE_USE_VERSIONS_HOST="${MISE_USE_VERSIONS_HOST:-1}" \
|
||||
MISE_YES=1 \
|
||||
PATH="${CARGO_TARGET_DIR:-$ROOT/target}/debug:$HOME/mise/bin:$CARGO_HOME/bin:$TEST_HOME/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin" \
|
||||
PATH="${CARGO_TARGET_DIR:-$ROOT/target}/debug:$HOME/mise/bin:$CARGO_HOME/bin:$TEST_HOME/bin:/opt/homebrew/bin:/home/linuxbrew/.linuxbrew/bin:/usr/local/bin:/usr/bin:/bin" \
|
||||
ROOT="$ROOT" \
|
||||
RUSTUP_HOME="$RUSTUP_HOME" \
|
||||
RUST_BACKTRACE="${RUST_BACKTRACE:-1}" \
|
||||
|
|
|
@ -305,6 +305,17 @@ cmd generate subcommand_required=#true help="[experimental] Generate files for v
|
|||
arg <OUTPUT>
|
||||
}
|
||||
}
|
||||
cmd devcontainer help="[experimental] Generate a devcontainer to execute mise" {
|
||||
after_long_help "Examples:\n\n $ mise generate devcontainer\n"
|
||||
flag "-n --name" help="The name of the devcontainer" {
|
||||
arg <NAME>
|
||||
}
|
||||
flag "-i --image" help="The image to use for the devcontainer" {
|
||||
arg <IMAGE>
|
||||
}
|
||||
flag "-m --mount-mise-data" help="Bind the mise-data-volume to the devcontainer"
|
||||
flag "-w --write" help="write to .devcontainer/devcontainer.json"
|
||||
}
|
||||
cmd git-pre-commit help="[experimental] Generate a git pre-commit hook" {
|
||||
alias pre-commit
|
||||
long_help "[experimental] Generate a git pre-commit hook\n\nThis command generates a git pre-commit hook that runs a mise task like `mise run pre-commit`\nwhen you commit changes to your repository.\n\nStaged files are passed to the task as `STAGED`."
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::{
|
||||
config::SETTINGS,
|
||||
file::{self, display_path},
|
||||
git::Git,
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
||||
/// [experimental] Generate a devcontainer to execute mise
|
||||
#[derive(Debug, clap::Args)]
|
||||
#[clap(verbatim_doc_comment, after_long_help = AFTER_LONG_HELP)]
|
||||
pub struct Devcontainer {
|
||||
/// The name of the devcontainer
|
||||
#[clap(long, short, verbatim_doc_comment)]
|
||||
name: Option<String>,
|
||||
|
||||
/// The image to use for the devcontainer
|
||||
#[clap(long, short, verbatim_doc_comment)]
|
||||
image: Option<String>,
|
||||
|
||||
/// Bind the mise-data-volume to the devcontainer
|
||||
#[clap(long, short, verbatim_doc_comment)]
|
||||
mount_mise_data: bool,
|
||||
|
||||
/// write to .devcontainer/devcontainer.json
|
||||
#[clap(long, short)]
|
||||
write: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct DevcontainerTemplate {
|
||||
name: String,
|
||||
image: String,
|
||||
features: HashMap<String, HashMap<String, String>>,
|
||||
mounts: Vec<DevcontainerMount>,
|
||||
container_env: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct DevcontainerMount {
|
||||
source: String,
|
||||
target: String,
|
||||
#[serde(rename = "type")]
|
||||
type_field: String,
|
||||
}
|
||||
|
||||
impl Devcontainer {
|
||||
pub fn run(self) -> eyre::Result<()> {
|
||||
SETTINGS.ensure_experimental("generate devcontainer")?;
|
||||
let output = self.generate()?;
|
||||
|
||||
if self.write {
|
||||
let path = Git::get_root()?.join(".devcontainer/devcontainer.json");
|
||||
file::write(&path, &output)?;
|
||||
miseprintln!("Wrote to {}", display_path(&path));
|
||||
} else {
|
||||
miseprintln!("{output}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate(&self) -> eyre::Result<String> {
|
||||
let name = self.name.as_deref().unwrap_or("mise");
|
||||
let image = self
|
||||
.image
|
||||
.as_deref()
|
||||
.unwrap_or("mcr.microsoft.com/devcontainers/base:ubuntu");
|
||||
|
||||
let mut mounts = vec![];
|
||||
let mut container_env = HashMap::new();
|
||||
if self.mount_mise_data {
|
||||
mounts.push(DevcontainerMount {
|
||||
source: "mise-data-volume".to_string(),
|
||||
target: "/mnt/mise-data".to_string(),
|
||||
type_field: "volume".to_string(),
|
||||
});
|
||||
container_env.insert("MISE_DATA_VOLUME".to_string(), "/mnt/mise-data".to_string());
|
||||
}
|
||||
|
||||
let mut features = HashMap::new();
|
||||
features.insert(
|
||||
"ghcr.io/devcontainers-extra/features/mise:1".to_string(),
|
||||
HashMap::new(),
|
||||
);
|
||||
|
||||
let template = DevcontainerTemplate {
|
||||
name: name.to_string(),
|
||||
image: image.to_string(),
|
||||
features,
|
||||
mounts,
|
||||
container_env,
|
||||
};
|
||||
|
||||
let output = serde_json::to_string_pretty(&template)?;
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
}
|
||||
|
||||
static AFTER_LONG_HELP: &str = color_print::cstr!(
|
||||
r#"<bold><underline>Examples:</underline></bold>
|
||||
|
||||
$ <bold>mise generate devcontainer</bold>
|
||||
"#
|
||||
);
|
|
@ -2,6 +2,7 @@ use clap::Subcommand;
|
|||
|
||||
mod bootstrap;
|
||||
mod config;
|
||||
mod devcontainer;
|
||||
mod git_pre_commit;
|
||||
mod github_action;
|
||||
mod task_docs;
|
||||
|
@ -19,6 +20,7 @@ pub struct Generate {
|
|||
enum Commands {
|
||||
Bootstrap(bootstrap::Bootstrap),
|
||||
Config(config::Config),
|
||||
Devcontainer(devcontainer::Devcontainer),
|
||||
GitPreCommit(git_pre_commit::GitPreCommit),
|
||||
GithubAction(github_action::GithubAction),
|
||||
TaskDocs(task_docs::TaskDocs),
|
||||
|
@ -30,6 +32,7 @@ impl Commands {
|
|||
match self {
|
||||
Self::Bootstrap(cmd) => cmd.run(),
|
||||
Self::Config(cmd) => cmd.run(),
|
||||
Self::Devcontainer(cmd) => cmd.run(),
|
||||
Self::GitPreCommit(cmd) => cmd.run(),
|
||||
Self::GithubAction(cmd) => cmd.run(),
|
||||
Self::TaskDocs(cmd) => cmd.run(),
|
||||
|
|
|
@ -1060,6 +1060,38 @@ const completionSpec: Fig.Spec = {
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "devcontainer",
|
||||
description: "[experimental] Generate a devcontainer to execute mise",
|
||||
options: [
|
||||
{
|
||||
name: ["-n", "--name"],
|
||||
description: "The name of the devcontainer",
|
||||
isRepeatable: false,
|
||||
args: {
|
||||
name: "name",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: ["-i", "--image"],
|
||||
description: "The image to use for the devcontainer",
|
||||
isRepeatable: false,
|
||||
args: {
|
||||
name: "image",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: ["-m", "--mount-mise-data"],
|
||||
description: "Bind the mise-data-volume to the devcontainer",
|
||||
isRepeatable: false,
|
||||
},
|
||||
{
|
||||
name: ["-w", "--write"],
|
||||
description: "Write to .devcontainer/devcontainer.json",
|
||||
isRepeatable: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: ["git-pre-commit", "pre-commit"],
|
||||
description: "[experimental] Generate a git pre-commit hook",
|
||||
|
|
Loading…
Reference in New Issue