Skip to content

Commit

Permalink
Add a prefix to each package names to adapt to rust-lang/cargo#7959
Browse files Browse the repository at this point in the history
  • Loading branch information
qryxip committed Sep 6, 2020
1 parent 289087e commit e45143d
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 63 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# Changelog

## [Unreleased]

### Added

- [`new`] Added `contest` variable to `new.path`.

### Changed

- [`new`] Package names will be `"contest{}"` to adapt to [rust-lang/cargo#7959](https://github.com/rust-lang/cargo/pull/7959).

Modify `new.path` as following.

```diff
-path = "./{{ package_name }}"
+path = "./{{ contest }}"
```

### Fixed

- [`new`] `new.path` will work correctly.
- [`new`] `new` command for yukicoder will work properly.

## [0.5.1] - 2020-09-04Z

### Added
Expand Down
17 changes: 16 additions & 1 deletion resources/compete.toml.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,23 @@ test-suite = {% raw %}"{{ manifest_dir }}/testcases/{{ problem | kebabcase }}.ym
#open = '["emacsclient", "-n"] + (.paths | map([.src, .test_suite]) | flatten)'

[new]
# Platform
#
# - atcoder
# - codeforces
# - yukicoder
platform = "{{ new_platform }}"
path = {% raw %}"./{{ package_name }}"{% endraw %}
# Path (Liquid template)
#
# Variables:
#
# - `contest`: Contest ID. **May be nil**
# - `package_name`: Package name
{% if new_platform == "yukicoder" -%}
path = {% raw %}"./{{ contest | default: 'problems' }}"{% endraw %}
{%- else -%}
path = {% raw %}"./{{ contest }}"{% endraw %}
{%- endif %}

[new.template]
{% if new_template_lockfile -%}
Expand Down
139 changes: 91 additions & 48 deletions src/commands/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
},
shell::{ColorChoice, Shell},
};
use anyhow::{anyhow, Context as _};
use anyhow::{anyhow, bail, Context as _};
use heck::KebabCase as _;
use itertools::Itertools as _;
use liquid::object;
Expand Down Expand Up @@ -88,12 +88,14 @@ pub fn run(opt: OptCompeteNew, ctx: crate::Context<'_>) -> anyhow::Result<()> {
shell,
)?;

let package_name = outcome
let contest = outcome
.contest
.as_ref()
.map(|RetrieveTestCasesOutcomeContest { id, .. }| id)
.unwrap_or(&contest);

let group = Group::Atcoder(contest);

let problems = outcome
.problems
.iter()
Expand All @@ -105,9 +107,8 @@ pub fn run(opt: OptCompeteNew, ctx: crate::Context<'_>) -> anyhow::Result<()> {
let (manifest_dir, src_paths) = create_new_package(
&cargo_compete_config_path,
&cargo_compete_config,
package_name,
group,
&problems,
false,
shell,
)?;

Expand Down Expand Up @@ -145,12 +146,14 @@ pub fn run(opt: OptCompeteNew, ctx: crate::Context<'_>) -> anyhow::Result<()> {
shell,
)?;

let package_name = outcome
let contest = outcome
.contest
.as_ref()
.map(|RetrieveTestCasesOutcomeContest { id, .. }| id)
.unwrap_or(&contest);

let group = Group::Codeforces(contest);

let problems = outcome
.problems
.iter()
Expand All @@ -162,9 +165,8 @@ pub fn run(opt: OptCompeteNew, ctx: crate::Context<'_>) -> anyhow::Result<()> {
let (manifest_dir, src_paths) = create_new_package(
&cargo_compete_config_path,
&cargo_compete_config,
package_name,
group,
&problems,
false,
shell,
)?;

Expand Down Expand Up @@ -198,13 +200,16 @@ pub fn run(opt: OptCompeteNew, ctx: crate::Context<'_>) -> anyhow::Result<()> {
let outcome =
crate::web::retrieve_testcases::dl_from_yukicoder(contest, problems, full, shell)?;

let package_name = outcome
let contest = outcome
.contest
.as_ref()
.map(|RetrieveTestCasesOutcomeContest { id, .. }| &**id)
.or(contest);
let is_no = package_name.is_none();
let package_name = package_name.unwrap_or("problems");

let group = match contest {
None => Group::YukicoderProblems,
Some(contest) => Group::YukicoderContest(contest),
};

let problems = outcome
.problems
Expand All @@ -217,9 +222,8 @@ pub fn run(opt: OptCompeteNew, ctx: crate::Context<'_>) -> anyhow::Result<()> {
let (manifest_dir, src_paths) = create_new_package(
&cargo_compete_config_path,
&cargo_compete_config,
package_name,
group,
&problems,
is_no,
shell,
)?;

Expand Down Expand Up @@ -254,31 +258,47 @@ fn urls(outcome: &RetrieveTestCasesOutcome) -> Vec<Url> {
outcome.problems.iter().map(|p| p.url.clone()).collect()
}

#[derive(Copy, Clone, Debug)]
enum Group<'a> {
Atcoder(&'a str),
Codeforces(&'a str),
YukicoderProblems,
YukicoderContest(&'a str),
}

impl<'a> Group<'a> {
fn contest(self) -> Option<&'a str> {
match self {
Self::Atcoder(contest)
| Self::Codeforces(contest)
| Self::YukicoderContest(contest) => Some(contest),
Self::YukicoderProblems => None,
}
}

fn package_name(self) -> String {
match self {
Self::Atcoder(contest) => contest.to_owned(),
Self::Codeforces(contest) | Self::YukicoderContest(contest) => {
format!("contest{}", contest)
}
Self::YukicoderProblems => "problems".to_owned(),
}
}
}

fn create_new_package(
cargo_compete_config_path: &Path,
cargo_compete_config: &CargoCompeteConfig,
package_name: &str,
group: Group<'_>,
problems: &BTreeMap<&str, &Url>,
problems_are_yukicoder_no: bool,
shell: &mut Shell,
) -> anyhow::Result<(PathBuf, Vec<PathBuf>)> {
crate::process::process(crate::process::cargo_exe()?)
.args(&[
"new",
"-q",
"--vcs",
"none",
"--name",
package_name,
package_name,
])
.cwd(cargo_compete_config_path.with_file_name(""))
.exec()?;

let cargo_compete_config_dir = cargo_compete_config_path.with_file_name("");

let manifest_dir = cargo_compete_config.new.path.render(&object!({
"package_name": package_name,
"contest": group.contest(),
"package_name": group.package_name(),
}))?;
let manifest_dir = Path::new(&manifest_dir);
let manifest_dir = cargo_compete_config_path
Expand All @@ -287,21 +307,39 @@ fn create_new_package(

let manifest_path = manifest_dir.join("Cargo.toml");

if manifest_dir.exists() {
bail!(
"could not create a new package. `{}` already exists",
manifest_dir.display(),
);
}

crate::process::process(crate::process::cargo_exe()?)
.arg("new")
.arg("-q")
.arg("--vcs")
.arg("none")
.arg("--name")
.arg(group.package_name())
.arg(&manifest_dir)
.cwd(cargo_compete_config_path.with_file_name(""))
.exec()?;

let mut package_metadata_cargo_compete_bin = problems
.keys()
.map(|problem_index| {
format!(
r#"{} = {{ name = "", problem = {{ {} }} }}
"#,
escape_key(&problem_index.to_kebab_case()),
match (cargo_compete_config.new.platform, problems_are_yukicoder_no) {
(PlatformKind::Atcoder, _) | (PlatformKind::Codeforces, _) => {
match group {
Group::Atcoder(_) | Group::Codeforces(_) => {
r#"platform = "", contest = "", index = "", url = """#
}
(PlatformKind::Yukicoder, true) => {
r#"platform = "", kind = "no", no = "", url = """#
Group::YukicoderProblems => {
r#"platform = "", kind = "problem", no = 0, url = """#
}
(PlatformKind::Yukicoder, false) => {
Group::YukicoderContest(_) => {
r#"platform = "", kind = "contest", contest = "", index = "", url = """#
}
}
Expand All @@ -314,34 +352,35 @@ fn create_new_package(
package_metadata_cargo_compete_bin[&problem_index.to_kebab_case()]["name"] =
toml_edit::value(format!(
"{}-{}",
package_name,
group.package_name(),
problem_index.to_kebab_case(),
));

let tbl =
&mut package_metadata_cargo_compete_bin[&problem_index.to_kebab_case()]["problem"];

match cargo_compete_config.new.platform {
PlatformKind::Atcoder => {
match group {
Group::Atcoder(contest) => {
tbl["platform"] = toml_edit::value("atcoder");
tbl["contest"] = toml_edit::value(package_name);
tbl["contest"] = toml_edit::value(contest);
tbl["index"] = toml_edit::value(&**problem_index);
tbl["url"] = toml_edit::value(problem_url.as_str());
}
PlatformKind::Codeforces => {
Group::Codeforces(contest) => {
tbl["platform"] = toml_edit::value("codeforces");
tbl["contest"] = toml_edit::value(package_name);
tbl["contest"] = toml_edit::value(contest);
tbl["index"] = toml_edit::value(&**problem_index);
tbl["url"] = toml_edit::value(problem_url.as_str());
}
PlatformKind::Yukicoder => {
Group::YukicoderProblems => {
tbl["platform"] = toml_edit::value("yukicoder");
if problems_are_yukicoder_no {
tbl["no"] = toml_edit::value(&**problem_index);
} else {
tbl["contest"] = toml_edit::value(package_name);
tbl["index"] = toml_edit::value(&**problem_index);
}
tbl["no"] = toml_edit::value(problem_index.parse::<i64>()?);
tbl["url"] = toml_edit::value(problem_url.as_str());
}
Group::YukicoderContest(contest) => {
tbl["platform"] = toml_edit::value("yukicoder");
tbl["contest"] = toml_edit::value(contest);
tbl["index"] = toml_edit::value(&**problem_index);
tbl["url"] = toml_edit::value(problem_url.as_str());
}
}
Expand All @@ -353,7 +392,7 @@ fn create_new_package(
let mut tbl = toml_edit::Table::new();
tbl["name"] = toml_edit::value(format!(
"{}-{}",
package_name,
group.package_name(),
problem_index.to_kebab_case(),
));
tbl["path"] = toml_edit::value(format!("src/bin/{}.rs", problem_index.to_kebab_case()));
Expand Down Expand Up @@ -461,7 +500,11 @@ fn create_new_package(

shell.status(
"Created",
format!("`{}` package at {}", package_name, manifest_dir.display()),
format!(
"`{}` package at {}",
group.package_name(),
manifest_dir.display(),
),
)?;

Ok((manifest_dir, src_paths))
Expand Down
Loading

0 comments on commit e45143d

Please sign in to comment.