Compare commits

..

No commits in common. "main" and "v0.4.1" have entirely different histories.
main ... v0.4.1

21 changed files with 429 additions and 790 deletions

View File

@ -1,16 +0,0 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "weekly"

View File

@ -6,14 +6,17 @@ jobs:
build_deb:
name: Build .deb package
runs-on: ubuntu-latest
env:
RUSTFLAGS: "-C strip=debuginfo"
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- run: cargo install cargo-deb
- run: cargo build --release
- run: ./build-manpages.sh
- run: cargo deb
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v2
with:
path: target/debian/*.deb

View File

@ -1,6 +1,4 @@
on:
- push
- workflow_dispatch
on: push
name: CI
@ -9,12 +7,17 @@ jobs:
name: lint and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: clippy, rustfmt
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-features -- -D warnings
- uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features -- -D warnings
- run: cargo check --workspace --all-features
- run: cargo test --all-targets
- run: cargo fmt --all -- --check
@ -23,31 +26,24 @@ jobs:
needs: lint_and_test
if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/build-') }}
name: Build package
env:
RUSTFLAGS: "-C strip=debuginfo"
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
# - windows-latest
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
- uses: Swatinem/rust-cache@v2
override: true
- run: cargo install mdsh mandown
- run: cargo build --release
- name: prepare release artifact
shell: bash
run: |
mkdir -p target/{bin,man}
cp target/release/*.1 target/man
cp target/release/git-{mob,solo,{add,edit,delete}-coauthor} target/bin
- uses: actions/upload-artifact@v4
- run: ./build-manpages.sh
- uses: actions/upload-artifact@v2
with:
name: git-mob-${{ matrix.os }}
path: |
target/bin
target/release/git-*
target/man
!target/release/*.d

779
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
[package]
name = "git-mob"
version = "0.6.0"
authors = [ "Martin Frost <martin@frost.ws>" ]
name = "git_mob"
version = "0.4.1"
authors = ["Martin Frost <martin@frost.ws>"]
edition = "2018"
description = "A CLI tool for social coding."
license = "MIT"
@ -9,18 +9,14 @@ homepage = "https://github.com/Frost/git-mob"
repository = "https://github.com/Frost/git-mob"
readme = "README.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
git2 = { version = "0.19", default-features = false }
dirs = "2.0"
git2 = { version = "0.13", default-features = false }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
clap = { version = "~4.5", features = ["derive"] }
clap_mangen = "~0.2"
env_home = "0.1.0"
[build-dependencies]
clap_mangen = "~0.2"
clap = { version = "~4.5", features = ["derive"]}
clap_complete = "~4.5"
clap = { version = "3.0.0-rc.4", features = ["derive"] }
[package.metadata.deb]
name = "git-mob"
@ -35,10 +31,10 @@ assets = [
["target/release/git-add-coauthor", "usr/bin/", "755"],
["target/release/git-edit-coauthor", "usr/bin/", "755"],
["target/release/git-delete-coauthor", "usr/bin/", "755"],
["target/release/git-mob.1", "usr/share/man/man1/", "644"],
["target/release/git-solo.1", "usr/share/man/man1/", "644"],
["target/release/git-add-coauthor.1", "usr/share/man/man1/", "644"],
["target/release/git-edit-coauthor.1", "usr/share/man/man1/", "644"],
["target/release/git-delete-coauthor.1", "usr/share/man/man1/", "644"],
["target/man/git-mob.1.gz", "usr/share/man/man1/", "644"],
["target/man/git-solo.1.gz", "usr/share/man/man1/", "644"],
["target/man/git-add-coauthor.1.gz", "usr/share/man/man1/", "644"],
["target/man/git-edit-coauthor.1.gz", "usr/share/man/man1/", "644"],
["target/man/git-delete-coauthor.1.gz", "usr/share/man/man1/", "644"],
["README.md", "usr/share/doc/git-mob/README", "644"],
]

10
build-manpages.sh Executable file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -e
mkdir -p target/man
for page in git-{mob,solo,{add,edit,delete}-coauthor}; do
mdsh --work_dir . -o - -i docs/$page.md | \
mandown - "$(echo $page | tr '[:lower:]' '[:upper:]')" 1 | \
gzip > target/man/$page.1.gz
done

View File

@ -1,31 +0,0 @@
use clap::CommandFactory;
use clap_mangen::Man;
use std::env;
use std::path::Path;
#[path = "src/cli.rs"]
mod cli;
macro_rules! generate_manpage {
($struct:ident) => {
let target_dir = env::var("CARGO_TARGET_DIR").unwrap_or("target".to_string());
let output_dir = Path::new(&target_dir).join(env::var("PROFILE").unwrap());
let cmd = cli::$struct::command();
let cmd_name = format!("{}.1", cmd.get_name());
let man = Man::new(cmd);
let mut buffer: Vec<u8> = Default::default();
man.render(&mut buffer)?;
std::fs::write(output_dir.join(cmd_name), buffer)?;
};
}
fn main() -> std::io::Result<()> {
generate_manpage!(GitMob);
generate_manpage!(GitSolo);
generate_manpage!(GitAddCoauthor);
generate_manpage!(GitEditCoauthor);
generate_manpage!(GitDeleteCoauthor);
Ok(())
}

3
docs/git-add-coauthor.md Normal file
View File

@ -0,0 +1,3 @@
# git-add-coauthor
<!-- `$ cargo run --bin git-add-coauthor -- --help` -->

View File

@ -0,0 +1,3 @@
# git-delete-coauthor
<!-- `$ cargo run --bin git-delete-coauthor -- --help` -->

View File

@ -0,0 +1,3 @@
# git-edit-coauthor
<!-- `$ cargo run --bin git-edit-coauthor -- --help` -->

3
docs/git-mob.md Normal file
View File

@ -0,0 +1,3 @@
# git-mob
<!-- `$ cargo run --bin git-mob -- --help` -->

3
docs/git-solo.md Normal file
View File

@ -0,0 +1,3 @@
# git-solo
<!-- `$ cargo run --bin git-solo -- --help` -->

View File

@ -1,75 +0,0 @@
{
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1678901627,
"narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"naersk": {
"inputs": {
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1671096816,
"narHash": "sha256-ezQCsNgmpUHdZANDCILm3RvtO1xH8uujk/+EqNvzIOg=",
"owner": "nix-community",
"repo": "naersk",
"rev": "d998160d6a076cfe8f9741e56aeec7e267e3e114",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "naersk",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1670507980,
"narHash": "sha256-riNZa0xzM1it3pzxciwALeMs+0CsBMWIW2FqulzK8vM=",
"path": "/nix/store/2i8zqmz2cqa0grjagw94z7g47199db9k-source",
"rev": "2787fc7d1e51404678614bf0fe92fc296746eec0",
"type": "path"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1678875422,
"narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"naersk": "naersk",
"nixpkgs": "nixpkgs_2"
}
}
},
"root": "root",
"version": 7
}

View File

@ -1,24 +0,0 @@
{
inputs = {
flake-utils.url = "github:numtide/flake-utils";
naersk.url = "github:nix-community/naersk";
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
};
outputs = { self, flake-utils, naersk, nixpkgs }:
{
overlays.default = (final: prev:
let naersk' = final.callPackage naersk { };
in { git-mob = naersk'.buildPackage { src = ./.; }; });
} // flake-utils.lib.eachDefaultSystem (system:
let
pkgs = (import nixpkgs) {
inherit system;
overlays = [ self.overlays.default ];
};
in rec {
defaultPackage = pkgs.git-mob;
devShell =
pkgs.mkShell { nativeBuildInputs = with pkgs; [ rustc cargo ]; };
});
}

View File

@ -1,8 +1,20 @@
use clap::Parser;
use git_mob::{cli, parse_coauthors_file, write_coauthors_file, Author};
use git_mob::{parse_coauthors_file, write_coauthors_file, Author};
#[derive(Parser, Debug)]
#[clap(name = "git-add-coauthor", version)]
/// Add a co-author to your git mob.
struct Opt {
/// Co-author initials
initials: String,
/// The name of the co-author, in quotes, e.g. "Foo Bar"
name: String,
/// The email of the co-author
email: String,
}
fn main() {
let opt = cli::GitAddCoauthor::parse();
let opt = Opt::parse();
let mut authors = parse_coauthors_file().unwrap_or_default();
let new_author = Author {
name: opt.name,

View File

@ -1,8 +1,16 @@
use clap::Parser;
use git_mob::{cli, get_available_coauthors, write_coauthors_file};
use git_mob::{get_available_coauthors, write_coauthors_file};
#[derive(Parser, Debug)]
#[clap(name = "git-delete-coauthor", version)]
/// Delete a co-author from your .git-coauthors file
struct Opt {
/// Initials of the co-author to delete
initials: String,
}
fn main() {
let opt = cli::GitDeleteCoauthor::parse();
let opt = Opt::parse();
let mut authors = get_available_coauthors();
authors.remove(&opt.initials);
write_coauthors_file(authors);

View File

@ -1,22 +1,43 @@
use clap::Parser;
use git_mob::{cli, get_available_coauthors, write_coauthors_file, Author};
use git_mob::{get_available_coauthors, write_coauthors_file, Author};
use std::process;
#[derive(Parser, Debug)]
#[clap(name = "git-edit-coauthor", version)]
/// Edit a co-author in your .git-coauthors template
struct Opt {
/// Co-author initials
initials: String,
/// The name of the co-author, in quotes, e.g. "Foo Bar"
#[clap(long, required_unless_present("email"))]
name: Option<String>,
/// The email of the co-author
#[clap(long, required_unless_present("name"))]
email: Option<String>,
}
fn main() {
let opt = cli::GitDeleteCoauthor::parse();
let opt = Opt::parse();
let mut authors = get_available_coauthors();
let mut updated_author: Author;
if let Some(author) = authors.get(&opt.initials) {
let mut updated_author: Author = author.clone();
updated_author.name = opt.name;
updated_author.email = opt.email;
authors.insert(opt.initials, updated_author);
write_coauthors_file(authors);
updated_author = author.clone();
} else {
eprintln!("No author found with initials {}", &opt.initials);
process::exit(1);
};
}
if let Some(name) = opt.name {
updated_author.name = name;
}
if let Some(email) = opt.email {
updated_author.email = email;
}
authors.insert(opt.initials, updated_author);
write_coauthors_file(authors);
}

View File

@ -1,14 +1,27 @@
use clap::Parser;
use git_mob::{
cli, ensure_commit_template_is_set, get_available_coauthors, get_main_author, set_main_author,
ensure_commit_template_is_set, get_available_coauthors, get_main_author, set_main_author,
with_gitmessage_template_path_or_exit, Author,
};
use std::fmt::Write;
use std::fs;
use std::process;
#[derive(Parser, Debug)]
#[clap(version, name = "git-mob")]
/// Assemble a group of co-authors to help you on your coding quest
struct Opt {
/// Prints list of available co-authors
#[clap(short, long)]
list: bool,
/// Overwrite the main author
#[clap(short, long)]
overwrite: Option<String>,
/// A list of co-author initials
coauthors: Vec<String>,
}
fn main() {
let args = cli::GitMob::parse();
let args = Opt::parse();
if args.list {
list_coauthors();
@ -25,7 +38,7 @@ fn main() {
fn list_coauthors() {
for (abbrev, author) in &get_available_coauthors() {
println!("{abbrev}\t{author}");
println!("{}\t{}", abbrev, author);
}
}
@ -34,7 +47,7 @@ fn override_main_author(initials: &str) {
match all_authors.get(initials) {
Some(new_main_author) => set_main_author(new_main_author),
None => {
eprintln!("Error: author with initials {initials} not found");
eprintln!("Error: author with initials {} not found", initials);
process::exit(1);
}
}
@ -44,18 +57,18 @@ fn write_coauthors_to_gitmessage_file(coauthor_initials: &[String]) {
let coauthors = select_coauthors(coauthor_initials);
let mut content = String::from("\n\n");
for author in &coauthors {
_ = writeln!(content, "Co-authored-by: {}", &author.to_string());
content.push_str(&format!("Co-authored-by: {}\n", &author.to_string()));
}
with_gitmessage_template_path_or_exit(|path| match fs::write(path, content) {
Ok(_) => {
println!("{}", get_main_author());
for author in &coauthors {
println!("{author}");
println!("{}", author);
}
}
Err(e) => {
eprintln!("Error writing to .gitmessage template: {e}");
eprintln!("Error writing to .gitmessage template: {}", e);
process::exit(1);
}
});
@ -69,7 +82,7 @@ fn select_coauthors(coauthor_initials: &[String]) -> Vec<Author> {
match all_coauthors.get(initial) {
Some(coauthor) => coauthors.push(coauthor.clone()),
None => {
eprintln!("Error: author with initials {initial} not found");
eprintln!("Error: atuhor with initials {} not found", initial);
process::exit(1);
}
}

View File

@ -1,13 +1,18 @@
use clap::Parser;
use git_mob::{
cli, ensure_commit_template_is_set, get_main_author, with_gitmessage_template_path_or_exit,
ensure_commit_template_is_set, get_main_author, with_gitmessage_template_path_or_exit,
};
use std::fs::File;
#[derive(Parser, Debug)]
#[clap(name = "git-solo", version)]
/// Disband the mob and continue working solo.
struct Opt {}
fn main() {
let _opt = cli::GitSolo::parse();
let _opt = Opt::parse();
let main_author = get_main_author();
println!("{main_author}");
println!("{}", main_author);
with_gitmessage_template_path_or_exit(|path| {
let _template = File::create(path);

View File

@ -1,56 +0,0 @@
use clap::Parser;
#[derive(Parser, Debug)]
#[clap(version, name = "git-mob")]
/// Assemble a group of co-authors to help you on your coding quest
pub struct GitMob {
/// Prints list of available co-authors
#[clap(short, long)]
pub list: bool,
/// Overwrite the main author
#[clap(short, long)]
pub overwrite: Option<String>,
/// A list of co-author initials
pub coauthors: Vec<String>,
}
#[derive(Parser, Debug)]
#[clap(name = "git-add-coauthor", version)]
/// Add a co-author to your list of available co-authors
pub struct GitAddCoauthor {
/// Co-author initials
pub initials: String,
/// The name of the co-author, in quotes, e.g. "Foo Bar"
pub name: String,
/// The email of the co-author
pub email: String,
}
#[derive(Parser, Debug)]
#[clap(name = "git-edit-coauthor", version)]
/// Edit a co-author in your list of available co-authors
pub struct GitEditCoauthor {
/// Co-author initials
pub initials: String,
/// The name of the co-author, in quotes, e.g. "Foo Bar"
pub name: String,
/// The email of the co-author
pub email: String,
}
#[derive(Parser, Debug)]
#[clap(name = "git-delete-coauthor", version)]
/// Delete a co-author from your list of available co-authors
pub struct GitDeleteCoauthor {
/// Co-author initials
pub initials: String,
/// The name of the co-author, in quotes, e.g. "Foo Bar"
pub name: String,
/// The email of the co-author
pub email: String,
}
#[derive(Parser, Debug)]
#[clap(name = "git-solo", version)]
/// Disband the mob and continue working solo.
pub struct GitSolo {}

View File

@ -1,4 +1,4 @@
use env_home::env_home_dir as home_dir;
use dirs::home_dir;
use git2::{Config, Repository};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
@ -11,8 +11,6 @@ use std::io::BufReader;
use std::process;
use std::string::String;
pub mod cli;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Author {
pub name: String,
@ -51,10 +49,9 @@ pub fn set_main_author(author: &Author) {
pub fn ensure_commit_template_is_set() {
with_git_repo_or_exit(|repo| {
let mut config = repo.config().unwrap();
let template_path = repo.path().join(".gitmessage");
if let Some(template_path) = template_path.to_str() {
config.set_str("commit.template", template_path).unwrap();
}
config
.set_str("commit.template", ".git/.gitmessage")
.unwrap();
})
}
@ -62,7 +59,7 @@ pub fn get_available_coauthors() -> BTreeMap<String, Author> {
match parse_coauthors_file() {
Ok(coauthors) => coauthors,
Err(e) => {
eprintln!("{e:?}");
eprintln!("{}", e);
BTreeMap::new()
}
}
@ -107,7 +104,7 @@ pub fn write_coauthors_file(authors: BTreeMap<String, Author>) {
match fs::write(coauthors_file_path(), json_data) {
Ok(_) => {}
Err(e) => {
eprintln!("Error writing git-coauthors file: {e:?}");
eprintln!("Error writing git-coauthors file: {:?}", e);
process::exit(1);
}
}