Skip to content

Commit

Permalink
Merge pull request #9 from busticated/chore/cleanups
Browse files Browse the repository at this point in the history
chore/cleanups
  • Loading branch information
busticated committed Oct 29, 2023
2 parents 379ad13 + f0047b6 commit 4e1ba00
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 72 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ jobs:
uses: dtolnay/rust-toolchain@stable
- name: Setup Project
run: cargo xtask setup
- name: Run Linter
run: cargo xtask lint
- name: Run Tests & Coverage
run: cargo xtask coverage
run: cargo xtask ci

17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,21 @@ Run `cargo xtask help` to see any other coverage-related commands that are avail
</p>
</details>

<details id="develop-run-spellcheck">
<summary><b>How to check for spelling errors</b></summary>
<p>

To find spelling mistakes in source code and docs across the workspace, run:

```
cargo xtask spellcheck
```

Run `cargo xtask help` to see any other test-related commands that are available.

</p>
</details>

<details id="develop-build-docs">
<summary><b>How to create docs</b></summary>
<p>
Expand All @@ -135,7 +150,7 @@ Run `cargo xtask help` to see any other docs-related commands that are available

In order to support automated crate changelog updates, you will need to:

* Commit crate changes separately - e.g. run: `git add -p crates/<name>/*` to stage files, then run `git add -p crates/<other-name>/*` and commit
* Commit crate changes separately - e.g. run: `git add -p crates/<name>/*` to stage files, then commit
* Format your commit message like: `[<crate name>] <message>` e.g. `[node-js-release-info] update docs`
* Commit changes to the workspace itself (including the `xtask` crate) separately without prefixing your commit message

Expand Down
2 changes: 1 addition & 1 deletion crates/node-js-release-info/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ async fn main() -> Result<(), NodeJSRelInfoError> {

## Features

Full `json` serialization + deserialization is avaialable via the `json` feature.
Full `json` serialization + deserialization is available via the `json` feature.

```shell
cargo add node-js-release-info --features json
Expand Down
21 changes: 9 additions & 12 deletions xtask/src/changelog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,28 +64,25 @@ impl Changelog {
lines.join("\n")
}

pub fn update(&mut self, fs: &FS, krate: &Krate, commits: Vec<String>) -> Result<(), DynError> {
if commits.is_empty() {
pub fn update(&mut self, fs: &FS, krate: &Krate, log: Vec<String>) -> Result<(), DynError> {
if log.is_empty() {
return Ok(());
}
self.load()?;
let mut log = format!("{}\n{}\n", MARKER_START, MARKER_END);
log.push_str(format!("## v{}\n\n", &krate.version).as_str());
for msg in commits.iter() {
if msg.is_empty() {
continue;
let mut changes = format!("{}\n{}\n", MARKER_START, MARKER_END);
changes.push_str(format!("## v{}\n\n", &krate.version).as_str());
for msg in log.iter() {
if !msg.is_empty() {
changes.push_str(format!("* {}\n", &msg).as_str());
}
let prefix = format!("[{}]", &krate.name);
let msg = msg.trim().replace(&prefix, "");
log.push_str(format!("* {}\n", &msg).as_str());
}
log.push('\n');
changes.push('\n');
let ptn = format!(r"{}[\s\S]*?{}", MARKER_START, MARKER_END);
let re = RegexBuilder::new(ptn.as_str())
.case_insensitive(true)
.multi_line(true)
.build()?;
let updated = re.replace(&self.text, &log);
let updated = re.replace(&self.text, &changes);
self.text = updated.as_ref().to_owned();
self.save(fs)
}
Expand Down
77 changes: 43 additions & 34 deletions xtask/src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,40 +71,36 @@ impl<'a> Git<'a> {
self.build_args(["commit", "--message", message.as_ref()], arguments)
}

pub fn tag<T, U>(&self, tag: T, arguments: U) -> Expression
pub fn tag<U>(&self, arguments: U) -> Expression
where
T: AsRef<str>,
U: IntoIterator,
U::Item: Into<OsString>,
{
let args = self.tag_params(tag, arguments);
self.exec_unsafe(args, None)
let args = self.tag_params(arguments);
self.exec_safe(args, None)
}

fn tag_params<T, U>(&self, tag: T, arguments: U) -> Vec<OsString>
fn tag_params<U>(&self, arguments: U) -> Vec<OsString>
where
T: AsRef<str>,
U: IntoIterator,
U::Item: Into<OsString>,
{
self.build_args(["tag", tag.as_ref(), "--message", tag.as_ref()], arguments)
self.build_args(["tag"], arguments)
}

pub fn get_tags<U>(&self, arguments: U) -> Expression
pub fn create_tag<T>(&self, tag: T) -> Expression
where
U: IntoIterator,
U::Item: Into<OsString>,
T: AsRef<str>,
{
let args = self.get_tags_params(arguments);
self.exec_safe(args, None)
let args = self.create_tag_params(tag);
self.exec_unsafe(args, None)
}

fn get_tags_params<U>(&self, arguments: U) -> Vec<OsString>
fn create_tag_params<T>(&self, tag: T) -> Vec<OsString>
where
U: IntoIterator,
U::Item: Into<OsString>,
T: AsRef<str>,
{
self.build_args(["tag"], arguments)
self.tag_params([tag.as_ref(), "--message", tag.as_ref()])
}

pub fn todos(&self) -> Expression {
Expand Down Expand Up @@ -137,21 +133,26 @@ impl<'a> Git<'a> {
}

pub fn get_changelog(&self, krate: &Krate) -> Result<Vec<String>, DynError> {
let args = self.get_changelog_params(krate);
let (prefix, args) = self.get_changelog_params(krate);
let history = self.exec_safe(args, None).read()?;
let prefix = format!("[{}]", &krate.name);
Ok(history
.split('\n')
.filter(|x| !x.is_empty())
.map(|x| str::to_string(x.replace(&prefix, "").trim()))
.collect())
Ok(self.fmt_changelog(prefix, history))
}

fn get_changelog_params(&self, krate: &Krate) -> Vec<OsString> {
fn get_changelog_params(&self, krate: &Krate) -> (String, Vec<OsString>) {
let range = format!("{}@{}..HEAD", &krate.name, &krate.version);
let query = format!(r"--grep=\[{}\]", &krate.name);
let fmt = String::from("--pretty=format:%B");
self.build_args(["log"], [range, query, fmt])
let prefix = format!("[{}]", &krate.name);
let args = self.build_args(["log"], [range, query, fmt]);
(prefix, args)
}

fn fmt_changelog(&self, prefix: String, history: String) -> Vec<String> {
history
.split('\n')
.filter(|x| !x.is_empty())
.map(|x| str::to_string(x.replace(&prefix, "").trim()))
.collect()
}
}

Expand Down Expand Up @@ -184,19 +185,16 @@ mod tests {
fn it_builds_args_for_the_tag_subcommand() {
let opts = Options::new(vec![], task_flags! {}).unwrap();
let git = Git::new(&opts);
let args = git.tag_params("my tag", ["--one", "--two"]);
assert_eq!(
args,
["tag", "my tag", "--message", "my tag", "--one", "--two"]
);
let args = git.tag_params(["--points-at", "HEAD"]);
assert_eq!(args, ["tag", "--points-at", "HEAD"]);
}

#[test]
fn it_builds_args_for_getting_tags() {
fn it_builds_args_for_creating_a_tag() {
let opts = Options::new(vec![], task_flags! {}).unwrap();
let git = Git::new(&opts);
let args = git.get_tags_params(["--points-at", "HEAD"]);
assert_eq!(args, ["tag", "--points-at", "HEAD"]);
let args = git.create_tag_params("my-tag");
assert_eq!(args, ["tag", "my-tag", "--message", "my-tag"]);
}

#[test]
Expand Down Expand Up @@ -231,7 +229,8 @@ mod tests {
let opts = Options::new(vec![], task_flags! {}).unwrap();
let krate = Krate::new("lib", "0.1.0", "my-crate", "", path);
let git = Git::new(&opts);
let args = git.get_changelog_params(&krate);
let (prefix, args) = git.get_changelog_params(&krate);
assert_eq!(prefix, "[my-crate]");
assert_eq!(
args,
[
Expand All @@ -242,4 +241,14 @@ mod tests {
]
);
}

#[test]
fn it_formats_changelog() {
let prefix = String::from("[my-crate]");
let history = format!("{prefix} commit 01\n{prefix} commit 02\n");
let opts = Options::new(vec![], task_flags! {}).unwrap();
let git = Git::new(&opts);
let log = git.fmt_changelog(prefix, history);
assert_eq!(log, vec!["commit 01", "commit 02"]);
}
}
2 changes: 1 addition & 1 deletion xtask/src/krate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ impl KrateKind {
pub fn from_path(path: PathBuf) -> Result<KrateKind, DynError> {
let path = path.join(SRC_DIRNAME).join(LIB_FILENAME);

if path.try_exists().is_err() {
if !path.is_file() {
return Ok(KrateKind::Binary);
}

Expand Down
53 changes: 39 additions & 14 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use inquire::required;
use inquire::validator::Validation as InquireValidation;
use inquire::{MultiSelect as InquireMultiSelect, Select as InquireSelect, Text as InquireText};
use regex::RegexBuilder;
use std::collections::HashMap;
use std::collections::BTreeMap;
use std::env;
use std::error::Error;

Expand Down Expand Up @@ -86,14 +86,14 @@ fn init_tasks() -> Tasks {
description: "view changelog entries for the next version of all crates".into(),
flags: task_flags! {},
run: |_opts, fs, git, _cargo, workspace, _tasks| {
println!("::::::::::::::::::::::::::::::::::::");
println!(":::: Viewing Upublished Changes ::::");
println!("::::::::::::::::::::::::::::::::::::");
println!(":::::::::::::::::::::::::::::::::::::");
println!(":::: Viewing Unpublished Changes ::::");
println!(":::::::::::::::::::::::::::::::::::::");
println!();

let mut krates = workspace.krates(&fs)?;
let tags_text = git.get_tags(["--list", "--sort=v:refname"]).read()?;
let mut tags: HashMap<String, String> = HashMap::new();
let krates = workspace.krates(&fs)?;
let tags_text = git.tag(["--list", "--sort=v:refname"]).read()?;
let mut tags: BTreeMap<String, String> = BTreeMap::new();

for tag in tags_text.lines() {
let (name, version) = match tag.split_once('@') {
Expand All @@ -105,14 +105,17 @@ fn init_tasks() -> Tasks {
}

for (name, _version) in tags.iter() {
let krate = krates.get_mut(name).unwrap_or_else(|| panic!("Could Not Find Crate: `{}`!", name));
let krate = krates.get(name).unwrap_or_else(|| panic!("Could Not Find Crate: `{}`!", name));
let log = git.get_changelog(krate)?;

println!(":::: {} [changes: {}]", &krate.name, log.len());

if log.is_empty() {
println!("\t--- n/a ---");
println!();
continue;
}

println!(":::: {}", &krate.name);

for l in log.iter() {
println!("* {}", l);
Expand All @@ -136,6 +139,10 @@ fn init_tasks() -> Tasks {
println!(":::::::::::::::::::::::::::::::::");
println!();

tasks
.get("spellcheck")
.unwrap()
.exec(vec![], tasks)?;
tasks
.get("lint")
.unwrap()
Expand Down Expand Up @@ -226,8 +233,8 @@ fn init_tasks() -> Tasks {
cmd!("open", &report).run()?;
}

println!(":::: Done!");
println!(":::: Report: {}", report);
println!(":::: Done!");
println!();
Ok(())
},
Expand Down Expand Up @@ -319,7 +326,7 @@ fn init_tasks() -> Tasks {
println!();

let krates = workspace.krates(&fs)?;
let tag_text = git.get_tags(["--points-at", "HEAD"]).read()?;
let tag_text = git.tag(["--points-at", "HEAD"]).read()?;
let mut tags = vec![];

for line in tag_text.lines() {
Expand Down Expand Up @@ -351,7 +358,7 @@ fn init_tasks() -> Tasks {
},
Task {
name: "crate:release".into(),
description: "prepate crates for publishing".into(),
description: "prepare crates for publishing".into(),
flags: task_flags! {
"dry-run" => "run thru steps but do not save changes"
},
Expand Down Expand Up @@ -394,7 +401,7 @@ fn init_tasks() -> Tasks {
git.commit(message, [""]).run()?;

for tag in tags {
git.tag(tag, [""]).run()?;
git.create_tag(tag).run()?;
}

println!(":::: Done!");
Expand All @@ -415,8 +422,8 @@ fn init_tasks() -> Tasks {
let dist_dir = workspace.path().join("target/release");
cargo.build(["--release"]).run()?;

println!(":::: Done!");
println!(":::: Artifacts: {}", dist_dir.display());
println!(":::: Done!");
println!();
Ok(())
},
Expand Down Expand Up @@ -505,6 +512,24 @@ fn init_tasks() -> Tasks {
cmd!("rustup", "component", "add", "clippy").run()?;
cmd!("rustup", "component", "add", "llvm-tools-preview").run()?;
cargo.install(["grcov"]).run()?;
cargo.install(["typos-cli"]).run()?;

println!(":::: Done!");
println!();
Ok(())
},
},
Task {
name: "spellcheck".into(),
description: "finds spelling mistakes in source code and docs".into(),
flags: task_flags! {},
run: |_opts, _fs, _git, _cargo, _workspace, _tasks| {
println!(":::::::::::::::::::::::::::");
println!(":::: Checking Spelling ::::");
println!(":::::::::::::::::::::::::::");
println!();

cmd!("typos").run()?;

println!(":::: Done!");
println!();
Expand Down
12 changes: 6 additions & 6 deletions xtask/src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ impl Workspace {

pub fn add_krate(&self, fs: &FS, cargo: &Cargo, mut krate: Krate) -> Result<Krate, DynError> {
let kind = krate.kind.to_string();
cargo
.create(&krate.path, ["--name", &krate.name, &kind])
.run()?;
krate.changelog.create(fs, &krate.clone())?;
krate.readme.create(fs, &krate.clone())?;
krate.toml.create(fs, &krate.clone())?;
let args = ["--name", &krate.name, &kind];
let krate_copy = krate.clone(); // TODO (mirande): deal w/ "cannot borrow as mutable because it is also borrowed as immutable" errors
cargo.create(&krate.path, args).run()?;
krate.changelog.create(fs, &krate_copy)?;
krate.readme.create(fs, &krate_copy)?;
krate.toml.create(fs, &krate_copy)?;
Ok(krate)
}

Expand Down

0 comments on commit 4e1ba00

Please sign in to comment.