Compare commits

..

2 commits

Author SHA1 Message Date
a30cf9a16f
add a nix flake 2026-02-02 13:01:35 +01:00
e85ac6a5e5
generate all the man pages in the manpage xtask 2026-02-02 13:01:16 +01:00
3 changed files with 187 additions and 10 deletions

64
flake.lock generated Normal file
View file

@ -0,0 +1,64 @@
{
"nodes": {
"crane": {
"locked": {
"lastModified": 1769737823,
"narHash": "sha256-DrBaNpZ+sJ4stXm+0nBX7zqZT9t9P22zbk6m5YhQxS4=",
"owner": "ipetkov",
"repo": "crane",
"rev": "b2f45c3830aa96b7456a4c4bc327d04d7a43e1ba",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1769996383,
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1769900590,
"narHash": "sha256-I7Lmgj3owOTBGuauy9FL6qdpeK2umDoe07lM4V+PnyA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "41e216c0ca66c83b12ab7a98cc326b5db01db646",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"crane": "crane",
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

102
flake.nix Normal file
View file

@ -0,0 +1,102 @@
{
description = "manages multiple identities (e.g. personal, work, university, ...) in git repos for you";
inputs = {
crane.url = "github:ipetkov/crane";
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
};
outputs = inputs @ { self, crane, ... }:
inputs.flake-parts.lib.mkFlake { inherit inputs; } ({ lib, ... }: {
systems = [ "x86_64-linux" "aarch64-linux" ];
perSystem = { pkgs, self', system, ... }: let
buildInputs = with pkgs; [
gpgme
pkg-config
];
nativeBuildInputs = with pkgs; [
pkg-config
];
crateSrc = lib.cleanSourceWith {
src = self.outPath;
filter = name: type: builtins.all (f: f name type) [
lib.sources.cleanSourceFilter
(name: type: !(builtins.elem (builtins.baseNameOf name) [ "flake.nix" "flake.lock" ]))
];
};
craneArgs = {
src = crateSrc;
strictDeps = true;
inherit buildInputs nativeBuildInputs;
};
craneLib = crane.mkLib pkgs;
# Build the dependencies with different parameters
cargoArtifacts = craneLib.buildDepsOnly craneArgs;
cargoTOML = builtins.fromTOML (builtins.readFile ./Cargo.toml);
in {
packages.xtask = (craneLib.buildPackage ( craneArgs // {
inherit cargoArtifacts;
cargoExtraArgs = "--package xtask";
meta = {
licences = with lib.licences; [mit asl20];
platforms = [ system ];
mainProgram = "xtask";
};
}));
packages.default = (craneLib.buildPackage ( craneArgs // {
inherit cargoArtifacts;
nativeBuildInputs = craneArgs.nativeBuildInputs ++ [ self'.packages.xtask ];
postInstall = let
manDir = "$out/share/man/man1";
in ''
mkdir -p "${manDir}"
xtask manpage "${manDir}"
find "${manDir}" -type f -exec gzip {} \;
'';
meta = {
licences = with lib.licences; [mit asl20];
platforms = [ system ];
mainProgram = cargoTOML.package.name;
}
// lib.optionalAttrs (lib.attrsets.hasAttrByPath ["package" "description"] cargoTOML) {
inherit (cargoTOML.package) description;
};
}));
apps.default = {
type = "app";
program = let pkg = self'.packages.default; in "${pkg}/bin/${pkg.pname}";
};
devShells.default = craneLib.devShell {
checks = self'.checks;
inherit buildInputs nativeBuildInputs;
packages = with pkgs; [
# Cargo and rustc are provided by default.
];
};
};
});
}

View file

@ -1,25 +1,36 @@
use std::path::PathBuf; use std::path::PathBuf;
use clap::{CommandFactory as _, Parser}; use clap::{CommandFactory as _, Parser};
use git_identity::cli;
/// Render the manpage of git-identity from its clap definition /// Render the manpage of git-identity from its clap definition
#[derive(Parser)] #[derive(Parser)]
pub struct Cli { pub struct Cli {
/// The file in which to write the newly generated manpage /// The directory in which to write the newly generated manpages
/// ///
/// By default, this is "target/git-identity.1" /// By default, this is "./target"
out_file: Option<PathBuf>, out_dir: Option<PathBuf>,
} }
pub fn main(cli: Cli) -> anyhow::Result<()> { pub fn main(cli: Cli) -> anyhow::Result<()> {
let man = clap_mangen::Man::new(git_identity::cli::Cli::command()); let out_dir = cli.out_dir.unwrap_or_else(|| PathBuf::from("./target"));
let mut buffer: Vec<u8> = Default::default();
let render = |name: &'static str, command: clap::Command| -> anyhow::Result<()> {
let man = clap_mangen::Man::new(command.name(name));
let mut buffer = Vec::<u8>::new();
man.render(&mut buffer)?; man.render(&mut buffer)?;
std::fs::write( let mut out_path = out_dir.clone();
cli.out_file.unwrap_or_else(|| "./target/git-identity.1".into()), out_path.push(man.get_filename());
buffer,
)?; std::fs::write(out_path, buffer)?;
Ok(())
};
render("git-identity", cli::Cli::command())?;
render("git-identity-import", cli::ImportCli::command())?;
Ok(()) Ok(())
} }