Skip to content

Commit

Permalink
Merge pull request #56 from qryxip/git-workdir
Browse files Browse the repository at this point in the history
Add `git_workdir` variable
  • Loading branch information
qryxip authored Aug 26, 2020
2 parents b8f2e99 + 79d8516 commit 1b5d89e
Show file tree
Hide file tree
Showing 14 changed files with 193 additions and 68 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## [Unreleased]

## Added

- [`new`, `open`] Added `git_workdir` variable.

## Changed

- Updated the default `compete.toml`.

## [0.4.7] - 2020-08-25Z

### Added
Expand Down
99 changes: 99 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ toml = "0.5.6"
toml_edit = "0.2.0"
url = { version = "2.1.1", features = ["serde"] }
which = "4.0.2"
git2 = "0.13.10"

[target.'cfg(windows)'.dependencies]
term_size = "=1.0.0-beta.2"
Expand Down
2 changes: 1 addition & 1 deletion resources/compete.toml.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ test-suite = "{{ "./testcases/{{ contest }}/{{ problem | kebabcase }}.yml" }}"
# Open files with the command (`jq` command)
#
# VSCode:
#open = '["code"] + (.paths | map([.src, .test_suite]) | flatten) + ["-a", .manifest_dir]'
#open = '["code"] + (.paths | map([.src, .test_suite]) | flatten) + ["-a", ([(.git_workdir | select(.)), .manifest_dir] | first)]'
# Emacs:
#open = '["emacsclient", "-n"] + (.paths | map([.src, .test_suite]) | flatten)'

Expand Down
17 changes: 9 additions & 8 deletions src/commands/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
ATCODER_RUST_VERSION, CODEFORCES_RUST_VERSION, YUKICODER_RUST_VERSION,
};
use anyhow::{bail, Context as _};
use git2::Repository;
use snowchains_core::web::PlatformKind;
use std::{
collections::HashSet,
Expand Down Expand Up @@ -37,16 +38,16 @@ pub(crate) fn run(opt: OptCompeteInit, ctx: crate::Context<'_>) -> anyhow::Resul

shell.set_color_choice(color);

let git_repo_root = cwd.ancestors().find(|p| p.join(".git").is_dir());
let git_workdir = Repository::discover(&cwd)
.ok()
.and_then(|r| r.workdir().map(ToOwned::to_owned));

let path = if let Some(path) = path {
cwd.join(path.strip_prefix(".").unwrap_or(&path))
} else {
git_repo_root
.with_context(|| {
"not a Git repository. run `git init` first, or specify a path with CLI arguments"
})?
.to_owned()
git_workdir.clone().with_context(|| {
"not a Git repository. run `git init` first, or specify a path with CLI arguments"
})?
};

if let Some(path) = ["atcoder", "codeforces", "yukicoder"]
Expand Down Expand Up @@ -99,8 +100,8 @@ pub(crate) fn run(opt: OptCompeteInit, ctx: crate::Context<'_>) -> anyhow::Resul
}
}

if let Some(git_repo_root) = git_repo_root {
let gitignore = git_repo_root.join(".gitignore");
if let Some(git_workdir) = git_workdir {
let gitignore = git_workdir.join(".gitignore");
if !gitignore.exists() {
crate::fs::write(
&gitignore,
Expand Down
5 changes: 5 additions & 0 deletions src/open.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::shell::Shell;
use anyhow::{ensure, Context as _};
use git2::Repository;
use serde_json::json;
use std::{borrow::Borrow, path::Path};
use url::Url;
Expand All @@ -25,6 +26,10 @@ pub(crate) fn open(
}

let input = json!({
"git_workdir": Repository::discover(workspace_root)
.ok()
.and_then(|r| r.workdir().map(|p| ensure_utf8(p).map(ToOwned::to_owned)))
.transpose()?,
"manifest_dir": ensure_utf8(pkg_manifest_dir)?,
"paths": paths
.iter()
Expand Down
11 changes: 10 additions & 1 deletion tests/init.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod common;

use duct::cmd;
use git2::Repository;
use ignore::overrides::Override;
use insta::{assert_json_snapshot, assert_snapshot};
use std::str;
Expand Down Expand Up @@ -38,8 +39,16 @@ fn run(input: &'static str) -> anyhow::Result<(String, serde_json::Value)> {
input.as_bytes(),
&["", "compete", "i"],
|workspace_root, output| {
let cwd_canonicalized = Repository::open(workspace_root)
.unwrap()
.workdir()
.unwrap()
.to_str()
.unwrap()
.to_owned();

output
.replace(workspace_root.to_str().unwrap(), "{{ cwd }}")
.replace(&cwd_canonicalized, "{{ cwd_canonicalized }}")
.replace(std::path::MAIN_SEPARATOR, "{{ main_path_separator }}")
},
|_| Ok(Override::empty()),
Expand Down
6 changes: 3 additions & 3 deletions tests/snapshots/init__no_crate_file_tree.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ expression: tree
"main.rs": "use std::io::{self, Read as _};\n\nfn main() {\n let mut input = \"\".to_owned();\n io::stdin().read_to_string(&mut input).unwrap();\n let mut input = input.split_whitespace();\n macro_rules! read(\n ([$tt:tt]) => (read!([$tt; read!(usize)]));\n ([$tt:tt; $n:expr]) => ((0..$n).map(|_| read!($tt)).collect::<Vec<_>>());\n (($($tt:tt),+)) => (($(read!($tt)),*));\n (Usize1) => (read!(usize) - 1);\n (Byte) => (read!(char) as u8);\n (Bytes) => (read!(String).into_bytes());\n ($ty:ty) => (input.next().unwrap().parse::<$ty>().unwrap());\n );\n\n let n = read!(usize);\n}\n"
}
},
"compete.toml": "# How to manage new workspace members (\"include\" | \"exclude\" | \"focus\")\n#\n# - `skip`: Does not modify `[workspace]`\n# - `include`: Adds the package to `workspace.members`\n# - `exclude`: Adds the package to `workspace.exclude` and create a symlink to the `compete.toml`\n# - `focus`: Adds the package to `workspace.members` and remove the other from both of `workspace.{members, exclude}`\nnew-workspace-member = \"include\"\n\n# Path to the test file (Liquid template)\n#\n# Variables:\n#\n# - `manifest_dir`: Package directory\n# - `contest`: Contest ID (e.g. \"abc100\")\n# - `problem`: Problem index (e.g. \"a\", \"b\")\n#\n# Additional filters:\n#\n# - `kebabcase`: Convert to kebab case (by using the `heck` crate)\ntest-suite = \"./testcases/{{ contest }}/{{ problem | kebabcase }}.yml\"\n#test-suite = \"{{ manifest_dir }}/testcases/{{ problem | kebabcase }}.yml\"\n\n# Open files with the command (`jq` command)\n#\n# VSCode:\n#open = '[\"code\"] + (.paths | map([.src, .test_suite]) | flatten) + [\"-a\", .manifest_dir]'\n# Emacs:\n#open = '[\"emacsclient\", \"-n\"] + (.paths | map([.src, .test_suite]) | flatten)'\n\n[template]\nplatform = \"atcoder\"\nmanifest = \"./cargo-compete-template/Cargo.toml\"\nsrc = \"./cargo-compete-template/src/main.rs\"\n\n#[submit-via-binary]\n#target = \"x86_64-unknown-linux-musl\"\n##cross = \"cross\"\n#strip = \"strip\"\n##upx = \"upx\"\n",
"compete.toml": "# How to manage new workspace members (\"include\" | \"exclude\" | \"focus\")\n#\n# - `skip`: Does not modify `[workspace]`\n# - `include`: Adds the package to `workspace.members`\n# - `exclude`: Adds the package to `workspace.exclude` and create a symlink to the `compete.toml`\n# - `focus`: Adds the package to `workspace.members` and remove the other from both of `workspace.{members, exclude}`\nnew-workspace-member = \"include\"\n\n# Path to the test file (Liquid template)\n#\n# Variables:\n#\n# - `manifest_dir`: Package directory\n# - `contest`: Contest ID (e.g. \"abc100\")\n# - `problem`: Problem index (e.g. \"a\", \"b\")\n#\n# Additional filters:\n#\n# - `kebabcase`: Convert to kebab case (by using the `heck` crate)\ntest-suite = \"./testcases/{{ contest }}/{{ problem | kebabcase }}.yml\"\n#test-suite = \"{{ manifest_dir }}/testcases/{{ problem | kebabcase }}.yml\"\n\n# Open files with the command (`jq` command)\n#\n# VSCode:\n#open = '[\"code\"] + (.paths | map([.src, .test_suite]) | flatten) + [\"-a\", ([(.git_workdir | select(.)), .manifest_dir] | first)]'\n# Emacs:\n#open = '[\"emacsclient\", \"-n\"] + (.paths | map([.src, .test_suite]) | flatten)'\n\n[template]\nplatform = \"atcoder\"\nmanifest = \"./cargo-compete-template/Cargo.toml\"\nsrc = \"./cargo-compete-template/src/main.rs\"\n\n#[submit-via-binary]\n#target = \"x86_64-unknown-linux-musl\"\n##cross = \"cross\"\n#strip = \"strip\"\n##upx = \"upx\"\n",
"rust-toolchain": "1.42.0\n"
},
"codeforces": {
Expand All @@ -24,7 +24,7 @@ expression: tree
"main.rs": "use std::io::{self, Read as _};\n\nfn main() {\n let mut input = \"\".to_owned();\n io::stdin().read_to_string(&mut input).unwrap();\n let mut input = input.split_whitespace();\n macro_rules! read(\n ([$tt:tt]) => (read!([$tt; read!(usize)]));\n ([$tt:tt; $n:expr]) => ((0..$n).map(|_| read!($tt)).collect::<Vec<_>>());\n (($($tt:tt),+)) => (($(read!($tt)),*));\n (Usize1) => (read!(usize) - 1);\n (Byte) => (read!(char) as u8);\n (Bytes) => (read!(String).into_bytes());\n ($ty:ty) => (input.next().unwrap().parse::<$ty>().unwrap());\n );\n\n let n = read!(usize);\n}\n"
}
},
"compete.toml": "# How to manage new workspace members (\"include\" | \"exclude\" | \"focus\")\n#\n# - `skip`: Does not modify `[workspace]`\n# - `include`: Adds the package to `workspace.members`\n# - `exclude`: Adds the package to `workspace.exclude` and create a symlink to the `compete.toml`\n# - `focus`: Adds the package to `workspace.members` and remove the other from both of `workspace.{members, exclude}`\nnew-workspace-member = \"include\"\n\n# Path to the test file (Liquid template)\n#\n# Variables:\n#\n# - `manifest_dir`: Package directory\n# - `contest`: Contest ID (e.g. \"abc100\")\n# - `problem`: Problem index (e.g. \"a\", \"b\")\n#\n# Additional filters:\n#\n# - `kebabcase`: Convert to kebab case (by using the `heck` crate)\ntest-suite = \"./testcases/{{ contest }}/{{ problem | kebabcase }}.yml\"\n#test-suite = \"{{ manifest_dir }}/testcases/{{ problem | kebabcase }}.yml\"\n\n# Open files with the command (`jq` command)\n#\n# VSCode:\n#open = '[\"code\"] + (.paths | map([.src, .test_suite]) | flatten) + [\"-a\", .manifest_dir]'\n# Emacs:\n#open = '[\"emacsclient\", \"-n\"] + (.paths | map([.src, .test_suite]) | flatten)'\n\n[template]\nplatform = \"codeforces\"\nmanifest = \"./cargo-compete-template/Cargo.toml\"\nsrc = \"./cargo-compete-template/src/main.rs\"\n\n#[submit-via-binary]\n#target = \"x86_64-unknown-linux-musl\"\n##cross = \"cross\"\n#strip = \"strip\"\n##upx = \"upx\"\n",
"compete.toml": "# How to manage new workspace members (\"include\" | \"exclude\" | \"focus\")\n#\n# - `skip`: Does not modify `[workspace]`\n# - `include`: Adds the package to `workspace.members`\n# - `exclude`: Adds the package to `workspace.exclude` and create a symlink to the `compete.toml`\n# - `focus`: Adds the package to `workspace.members` and remove the other from both of `workspace.{members, exclude}`\nnew-workspace-member = \"include\"\n\n# Path to the test file (Liquid template)\n#\n# Variables:\n#\n# - `manifest_dir`: Package directory\n# - `contest`: Contest ID (e.g. \"abc100\")\n# - `problem`: Problem index (e.g. \"a\", \"b\")\n#\n# Additional filters:\n#\n# - `kebabcase`: Convert to kebab case (by using the `heck` crate)\ntest-suite = \"./testcases/{{ contest }}/{{ problem | kebabcase }}.yml\"\n#test-suite = \"{{ manifest_dir }}/testcases/{{ problem | kebabcase }}.yml\"\n\n# Open files with the command (`jq` command)\n#\n# VSCode:\n#open = '[\"code\"] + (.paths | map([.src, .test_suite]) | flatten) + [\"-a\", ([(.git_workdir | select(.)), .manifest_dir] | first)]'\n# Emacs:\n#open = '[\"emacsclient\", \"-n\"] + (.paths | map([.src, .test_suite]) | flatten)'\n\n[template]\nplatform = \"codeforces\"\nmanifest = \"./cargo-compete-template/Cargo.toml\"\nsrc = \"./cargo-compete-template/src/main.rs\"\n\n#[submit-via-binary]\n#target = \"x86_64-unknown-linux-musl\"\n##cross = \"cross\"\n#strip = \"strip\"\n##upx = \"upx\"\n",
"rust-toolchain": "1.42.0\n"
},
"yukicoder": {
Expand All @@ -36,7 +36,7 @@ expression: tree
"main.rs": "use std::io::{self, Read as _};\n\nfn main() {\n let mut input = \"\".to_owned();\n io::stdin().read_to_string(&mut input).unwrap();\n let mut input = input.split_whitespace();\n macro_rules! read(\n ([$tt:tt]) => (read!([$tt; read!(usize)]));\n ([$tt:tt; $n:expr]) => ((0..$n).map(|_| read!($tt)).collect::<Vec<_>>());\n (($($tt:tt),+)) => (($(read!($tt)),*));\n (Usize1) => (read!(usize) - 1);\n (Byte) => (read!(char) as u8);\n (Bytes) => (read!(String).into_bytes());\n ($ty:ty) => (input.next().unwrap().parse::<$ty>().unwrap());\n );\n\n let n = read!(usize);\n}\n"
}
},
"compete.toml": "# How to manage new workspace members (\"include\" | \"exclude\" | \"focus\")\n#\n# - `skip`: Does not modify `[workspace]`\n# - `include`: Adds the package to `workspace.members`\n# - `exclude`: Adds the package to `workspace.exclude` and create a symlink to the `compete.toml`\n# - `focus`: Adds the package to `workspace.members` and remove the other from both of `workspace.{members, exclude}`\nnew-workspace-member = \"include\"\n\n# Path to the test file (Liquid template)\n#\n# Variables:\n#\n# - `manifest_dir`: Package directory\n# - `contest`: Contest ID (e.g. \"abc100\")\n# - `problem`: Problem index (e.g. \"a\", \"b\")\n#\n# Additional filters:\n#\n# - `kebabcase`: Convert to kebab case (by using the `heck` crate)\ntest-suite = \"./testcases/{{ contest }}/{{ problem | kebabcase }}.yml\"\n#test-suite = \"{{ manifest_dir }}/testcases/{{ problem | kebabcase }}.yml\"\n\n# Open files with the command (`jq` command)\n#\n# VSCode:\n#open = '[\"code\"] + (.paths | map([.src, .test_suite]) | flatten) + [\"-a\", .manifest_dir]'\n# Emacs:\n#open = '[\"emacsclient\", \"-n\"] + (.paths | map([.src, .test_suite]) | flatten)'\n\n[template]\nplatform = \"yukicoder\"\nmanifest = \"./cargo-compete-template/Cargo.toml\"\nsrc = \"./cargo-compete-template/src/main.rs\"\n\n#[submit-via-binary]\n#target = \"x86_64-unknown-linux-musl\"\n##cross = \"cross\"\n#strip = \"strip\"\n##upx = \"upx\"\n",
"compete.toml": "# How to manage new workspace members (\"include\" | \"exclude\" | \"focus\")\n#\n# - `skip`: Does not modify `[workspace]`\n# - `include`: Adds the package to `workspace.members`\n# - `exclude`: Adds the package to `workspace.exclude` and create a symlink to the `compete.toml`\n# - `focus`: Adds the package to `workspace.members` and remove the other from both of `workspace.{members, exclude}`\nnew-workspace-member = \"include\"\n\n# Path to the test file (Liquid template)\n#\n# Variables:\n#\n# - `manifest_dir`: Package directory\n# - `contest`: Contest ID (e.g. \"abc100\")\n# - `problem`: Problem index (e.g. \"a\", \"b\")\n#\n# Additional filters:\n#\n# - `kebabcase`: Convert to kebab case (by using the `heck` crate)\ntest-suite = \"./testcases/{{ contest }}/{{ problem | kebabcase }}.yml\"\n#test-suite = \"{{ manifest_dir }}/testcases/{{ problem | kebabcase }}.yml\"\n\n# Open files with the command (`jq` command)\n#\n# VSCode:\n#open = '[\"code\"] + (.paths | map([.src, .test_suite]) | flatten) + [\"-a\", ([(.git_workdir | select(.)), .manifest_dir] | first)]'\n# Emacs:\n#open = '[\"emacsclient\", \"-n\"] + (.paths | map([.src, .test_suite]) | flatten)'\n\n[template]\nplatform = \"yukicoder\"\nmanifest = \"./cargo-compete-template/Cargo.toml\"\nsrc = \"./cargo-compete-template/src/main.rs\"\n\n#[submit-via-binary]\n#target = \"x86_64-unknown-linux-musl\"\n##cross = \"cross\"\n#strip = \"strip\"\n##upx = \"upx\"\n",
"rust-toolchain": "1.44.1\n"
}
}
Loading

0 comments on commit 1b5d89e

Please sign in to comment.