Skip to content

Commit

Permalink
feat: Adding SCM option for init command (prefix-dev#2342)
Browse files Browse the repository at this point in the history
  • Loading branch information
alvgaona authored Oct 26, 2024
1 parent fb85c0b commit c79cb70
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 8 deletions.
7 changes: 4 additions & 3 deletions docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ It also supports the [`pyproject.toml`](../advanced/pyproject_toml.md) file, if

##### Options

- `--channel <CHANNEL> (-c)`: specify a channel that the project uses. Defaults to `conda-forge`. (Allowed to be used more than once)
- `--platform <PLATFORM> (-p)`: specify a platform that the project supports. (Allowed to be used more than once)
- `--channel <CHANNEL> (-c)`: Specify a channel that the project uses. Defaults to `conda-forge`. (Allowed to be used more than once)
- `--platform <PLATFORM> (-p)`: Specify a platform that the project supports. (Allowed to be used more than once)
- `--import <ENV_FILE> (-i)`: Import an existing conda environment file, e.g. `environment.yml`.
- `--format <FORMAT>`: Specify the format of the project file, either `pyproject` or `pixi`. [default: `pixi`]
- `--scm <SCM>`: Specify the SCM used to manage the project with. Possible values: github, gitlab, codeberg. [default: `github`]

!!! info "Importing an environment.yml"
When importing an environment, the `pixi.toml` will be created with the dependencies from the environment file.
Expand All @@ -46,7 +47,7 @@ pixi init --channel conda-forge --channel bioconda myproject
pixi init --platform osx-64 --platform linux-64 myproject
pixi init --import environment.yml
pixi init --format pyproject
pixi init --format pixi
pixi init --format pixi --scm gitlab
```

## `add`
Expand Down
86 changes: 82 additions & 4 deletions src/cli/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,17 @@ pub struct Args {
pub env_file: Option<PathBuf>,

/// The manifest format to create.
#[arg(long, conflicts_with_all = ["env_file", "pyproject_toml"],)]
#[arg(long, conflicts_with_all = ["env_file", "pyproject_toml"], ignore_case = true)]
pub format: Option<ManifestFormat>,

/// Create a pyproject.toml manifest instead of a pixi.toml manifest
// BREAK (0.27.0): Remove this option from the cli in favor of the `format` option.
#[arg(long, conflicts_with_all = ["env_file", "format"], alias = "pyproject", hide = true)]
pub pyproject_toml: bool,

/// Source Control Management used for this project
#[arg(short = 's', long = "scm", ignore_case = true)]
pub scm: Option<GitAttributes>,
}

/// The pixi.toml template
Expand Down Expand Up @@ -149,9 +153,29 @@ const GITIGNORE_TEMPLATE: &str = r#"
*.egg-info
"#;

const GITATTRIBUTES_TEMPLATE: &str = r#"# GitHub syntax highlighting
#[derive(Parser, Debug, Clone, PartialEq, ValueEnum)]
pub enum GitAttributes {
Github,
Gitlab,
Codeberg,
}

impl GitAttributes {
fn template(&self) -> &'static str {
match self {
GitAttributes::Github | GitAttributes::Codeberg => {
r#"# SCM syntax highlighting
pixi.lock linguist-language=YAML linguist-generated=true
"#;
"#
}
GitAttributes::Gitlab => {
r#"# GitLab syntax highlighting
pixi.lock gitlab-language=yaml gitlab-generated=true
"#
}
}
}
}

pub async fn execute(args: Args) -> miette::Result<()> {
let env = Environment::new();
Expand Down Expand Up @@ -412,8 +436,10 @@ pub async fn execute(args: Args) -> miette::Result<()> {
);
}

let git_attributes = args.scm.unwrap_or(GitAttributes::Github);

// create a .gitattributes if one is missing
if let Err(e) = create_or_append_file(&gitattributes_path, GITATTRIBUTES_TEMPLATE) {
if let Err(e) = create_or_append_file(&gitattributes_path, git_attributes.template()) {
tracing::warn!(
"Warning, couldn't update '{}' because of: {}",
gitattributes_path.to_string_lossy(),
Expand Down Expand Up @@ -579,4 +605,56 @@ mod tests {

dir.close().unwrap();
}

#[test]
fn test_multiple_format_values() {
let test_cases = vec![
("pixi", ManifestFormat::Pixi),
("PiXi", ManifestFormat::Pixi),
("PIXI", ManifestFormat::Pixi),
("pyproject", ManifestFormat::Pyproject),
("PyPrOjEcT", ManifestFormat::Pyproject),
("PYPROJECT", ManifestFormat::Pyproject),
];

for (input, expected) in test_cases {
let args = Args::try_parse_from(["init", "--format", input]).unwrap();
assert_eq!(args.format, Some(expected));
}
}

#[test]
fn test_multiple_scm_values() {
let test_cases = vec![
("github", GitAttributes::Github),
("GiThUb", GitAttributes::Github),
("GITHUB", GitAttributes::Github),
("Github", GitAttributes::Github),
("gitlab", GitAttributes::Gitlab),
("GiTlAb", GitAttributes::Gitlab),
("GITLAB", GitAttributes::Gitlab),
("codeberg", GitAttributes::Codeberg),
("CoDeBeRg", GitAttributes::Codeberg),
("CODEBERG", GitAttributes::Codeberg),
];

for (input, expected) in test_cases {
let args = Args::try_parse_from(["init", "--scm", input]).unwrap();
assert_eq!(args.scm, Some(expected));
}
}

#[test]
fn test_invalid_scm_values() {
let invalid_values = vec!["invalid", "", "git", "bitbucket", "mercurial", "svn"];

for value in invalid_values {
let result = Args::try_parse_from(["init", "--scm", value]);
assert!(
result.is_err(),
"Expected error for invalid SCM value '{}', but got success",
value
);
}
}
}
4 changes: 3 additions & 1 deletion tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use pixi::{
cli::{
add,
cli_config::{PrefixUpdateConfig, ProjectConfig},
init,
init::{self, GitAttributes},
install::Args,
project, remove, run,
task::{self, AddArgs, AliasArgs},
Expand Down Expand Up @@ -261,6 +261,7 @@ impl PixiControl {
env_file: None,
format: None,
pyproject_toml: false,
scm: Some(GitAttributes::Github),
},
}
}
Expand All @@ -278,6 +279,7 @@ impl PixiControl {
env_file: None,
format: None,
pyproject_toml: false,
scm: Some(GitAttributes::Github),
},
}
}
Expand Down

0 comments on commit c79cb70

Please sign in to comment.