mirror of https://github.com/ashhhleyyy/fsh.git
feat: add nix flake
This commit is contained in:
parent
5a49125331
commit
9831e738ab
|
@ -1 +1,2 @@
|
|||
/target
|
||||
/result
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
{
|
||||
"nodes": {
|
||||
"crane": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"rust-overlay": "rust-overlay"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1668993159,
|
||||
"narHash": "sha256-9BVTtPFrHRh0HbeEm2bmXsoIWRj1tKM6Nvfl7VMK/X8=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "c61d98aaea5667607a36bafe5a6fa87fe5bb2c7e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1650374568,
|
||||
"narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "b4a34015c698c7793d592d66adbab377907a2be8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1667395993,
|
||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"locked": {
|
||||
"lastModified": 1667395993,
|
||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1669029319,
|
||||
"narHash": "sha256-EdTqXZ/xBk7xjSCPGNbL0WnoWHEkYjwe78C6gZoUC0E=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "79bb815a1cdc789f6b036d2047e217ab3e989fff",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"crane": "crane",
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"crane",
|
||||
"flake-utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"crane",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1667487142,
|
||||
"narHash": "sha256-bVuzLs1ZVggJAbJmEDVO9G6p8BH3HRaolK70KXvnWnU=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "cf668f737ac986c0a89e83b6b2e3c5ddbd8cf33b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
crane.url = "github:ipetkov/crane";
|
||||
crane.inputs.nixpkgs.follows = "nixpkgs";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, crane, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
system = system;
|
||||
};
|
||||
inherit (pkgs) lib;
|
||||
|
||||
craneLib = crane.lib.${system};
|
||||
|
||||
src = craneLib.cleanCargoSource ./.;
|
||||
|
||||
buildInputs = [
|
||||
pkgs.pkg-config pkgs.openssl
|
||||
] ++ lib.optionals pkgs.stdenv.isDarwin [
|
||||
# Additional darwin specific inputs can be set here
|
||||
pkgs.libiconv
|
||||
];
|
||||
|
||||
cargoArtifacts = craneLib.buildDepsOnly {
|
||||
inherit src buildInputs;
|
||||
};
|
||||
|
||||
# Build the actual crate itself, reusing the dependency
|
||||
# artifacts from above.
|
||||
fsh = craneLib.buildPackage {
|
||||
inherit cargoArtifacts src buildInputs;
|
||||
};
|
||||
in
|
||||
{
|
||||
checks = {
|
||||
# Build the crate as part of `nix flake check` for convenience
|
||||
inherit fsh;
|
||||
|
||||
# Run clippy (and deny all warnings) on the crate source,
|
||||
# again, resuing the dependency artifacts from above.
|
||||
#
|
||||
# Note that this is done as a separate derivation so that
|
||||
# we can block the CI if there are issues here, but not
|
||||
# prevent downstream consumers from building our crate by itself.
|
||||
fsh-clippy = craneLib.cargoClippy {
|
||||
inherit cargoArtifacts src buildInputs;
|
||||
cargoClippyExtraArgs = "--all-targets -- --deny warnings";
|
||||
};
|
||||
|
||||
# Check formatting
|
||||
fsh-fmt = craneLib.cargoFmt {
|
||||
inherit src;
|
||||
};
|
||||
};
|
||||
|
||||
packages.default = fsh;
|
||||
|
||||
apps.default = flake-utils.lib.mkApp {
|
||||
drv = fsh;
|
||||
};
|
||||
|
||||
devShells.default = pkgs.mkShell {
|
||||
inputsFrom = builtins.attrValues self.checks;
|
||||
|
||||
# Extra inputs can be added here
|
||||
nativeBuildInputs = with pkgs; [
|
||||
cargo
|
||||
rustc
|
||||
rustfmt
|
||||
pkg-config
|
||||
openssl
|
||||
];
|
||||
};
|
||||
});
|
||||
}
|
70
src/main.rs
70
src/main.rs
|
@ -1,7 +1,7 @@
|
|||
use ansi_term::{Colour as AnsiColour, Style};
|
||||
use gethostname::gethostname;
|
||||
use git2::{Repository, Status as GitStatus};
|
||||
use std::{fmt::Display, path::PathBuf};
|
||||
use gethostname::gethostname;
|
||||
|
||||
struct PromptComponent {
|
||||
text: String,
|
||||
|
@ -22,7 +22,7 @@ fn from_hex(hex: u32) -> AnsiColour {
|
|||
AnsiColour::RGB(
|
||||
(hex >> 16 & 0xff) as u8,
|
||||
(hex >> 8 & 0xff) as u8,
|
||||
(hex >> 0 & 0xff) as u8,
|
||||
(hex & 0xff) as u8,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ impl Display for PromptComponent {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
let last_status = if let Some(status) = std::env::args().into_iter().skip(1).next() {
|
||||
let last_status = if let Some(status) = std::env::args().into_iter().nth(1) {
|
||||
status.parse().unwrap()
|
||||
} else {
|
||||
0
|
||||
|
@ -84,13 +84,17 @@ fn main() {
|
|||
|
||||
let mut components = Vec::new();
|
||||
|
||||
let user = users::get_current_username().map(|s| s.to_string_lossy().into_owned()).unwrap_or_else(|| "unknown".to_string());
|
||||
let user = users::get_current_username()
|
||||
.map(|s| s.to_string_lossy().into_owned())
|
||||
.unwrap_or_else(|| "unknown".to_string());
|
||||
if std::env::var("FSH_NO_HOSTNAME").is_ok() {
|
||||
components.push(PromptComponent::bold(&user, Colour::Purple));
|
||||
} else {
|
||||
components.push(PromptComponent::bold(&user, Colour::Purple).no_space());
|
||||
components.push(PromptComponent::unstyled("@").no_space());
|
||||
let hostname = gethostname().into_string().unwrap_or_else(|e |format!("{:?}", e));
|
||||
let hostname = gethostname()
|
||||
.into_string()
|
||||
.unwrap_or_else(|e| format!("{:?}", e));
|
||||
components.push(PromptComponent::bold(&hostname, Colour::Pink));
|
||||
}
|
||||
|
||||
|
@ -118,7 +122,10 @@ fn main() {
|
|||
if last_status == 0 {
|
||||
components.push(PromptComponent::bold("\u{f061}", Colour::Yellow));
|
||||
} else {
|
||||
components.push(PromptComponent::bold(&format!("{} \u{f061}", last_status), Colour::Red));
|
||||
components.push(PromptComponent::bold(
|
||||
&format!("{} \u{f061}", last_status),
|
||||
Colour::Red,
|
||||
));
|
||||
}
|
||||
|
||||
for component in components {
|
||||
|
@ -135,18 +142,18 @@ fn get_git_info(components: &mut Vec<PromptComponent>, repo: &Option<Repository>
|
|||
Some(repo) => {
|
||||
let head = match repo.head() {
|
||||
Ok(head) => Some(head.shorthand().unwrap().to_string()),
|
||||
Err(ref e) if e.code() == git2::ErrorCode::NotFound => {
|
||||
None
|
||||
}
|
||||
Err(ref e) if e.code() == git2::ErrorCode::NotFound => None,
|
||||
Err(ref e) if e.code() == git2::ErrorCode::UnbornBranch => {
|
||||
// https://github.com/starship/starship/commit/489838e6a24ea1c08be6abe56d066724a1d59abd#diff-d6346fd7d17270b1282142aeeda9c4bc2b7d8fd0f37b24a1c871a9257f0ed0aaR324-R336
|
||||
let mut head_path = repo.path().to_path_buf();
|
||||
head_path.push("HEAD");
|
||||
|
||||
std::fs::read_to_string(&head_path)
|
||||
.ok().unwrap()
|
||||
.ok()
|
||||
.unwrap()
|
||||
.lines()
|
||||
.next().unwrap()
|
||||
.next()
|
||||
.unwrap()
|
||||
.trim()
|
||||
.split('/')
|
||||
.last()
|
||||
|
@ -155,27 +162,50 @@ fn get_git_info(components: &mut Vec<PromptComponent>, repo: &Option<Repository>
|
|||
Err(e) => Err(e).unwrap(),
|
||||
};
|
||||
|
||||
let head = head.unwrap_or("(no HEAD)".to_string());
|
||||
let head = head.unwrap_or_else(|| "(no HEAD)".to_string());
|
||||
|
||||
components.push(PromptComponent::bold(&format!("\u{e725} {}", head), Colour::Blue));
|
||||
components.push(PromptComponent::bold(
|
||||
&format!("\u{e725} {}", head),
|
||||
Colour::Blue,
|
||||
));
|
||||
|
||||
let mut unstaged = false;
|
||||
let mut staged = false;
|
||||
for status in repo.statuses(None).unwrap().iter() {
|
||||
let status = status.status();
|
||||
if status.intersects(GitStatus::WT_DELETED | GitStatus::WT_MODIFIED | GitStatus::WT_NEW | GitStatus::WT_RENAMED | GitStatus::WT_TYPECHANGE) {
|
||||
if status.intersects(
|
||||
GitStatus::WT_DELETED
|
||||
| GitStatus::WT_MODIFIED
|
||||
| GitStatus::WT_NEW
|
||||
| GitStatus::WT_RENAMED
|
||||
| GitStatus::WT_TYPECHANGE,
|
||||
) {
|
||||
unstaged = true;
|
||||
}
|
||||
if status.intersects(GitStatus::INDEX_DELETED | GitStatus::INDEX_MODIFIED | GitStatus::INDEX_NEW | GitStatus::INDEX_RENAMED | GitStatus::INDEX_TYPECHANGE) {
|
||||
if status.intersects(
|
||||
GitStatus::INDEX_DELETED
|
||||
| GitStatus::INDEX_MODIFIED
|
||||
| GitStatus::INDEX_NEW
|
||||
| GitStatus::INDEX_RENAMED
|
||||
| GitStatus::INDEX_TYPECHANGE,
|
||||
) {
|
||||
staged = true;
|
||||
}
|
||||
}
|
||||
|
||||
let action = match repo.state() {
|
||||
git2::RepositoryState::Merge => Some(PromptComponent::bold("merge", Colour::Pink)),
|
||||
git2::RepositoryState::Revert | git2::RepositoryState::RevertSequence => Some(PromptComponent::bold("revert", Colour::Pink)),
|
||||
git2::RepositoryState::CherryPick | git2::RepositoryState::CherryPickSequence => Some(PromptComponent::bold("cherry pick", Colour::Pink)),
|
||||
git2::RepositoryState::Rebase | git2::RepositoryState::RebaseInteractive | git2::RepositoryState::RebaseMerge => Some(PromptComponent::bold("rebase", Colour::Pink)),
|
||||
git2::RepositoryState::Revert | git2::RepositoryState::RevertSequence => {
|
||||
Some(PromptComponent::bold("revert", Colour::Pink))
|
||||
}
|
||||
git2::RepositoryState::CherryPick | git2::RepositoryState::CherryPickSequence => {
|
||||
Some(PromptComponent::bold("cherry pick", Colour::Pink))
|
||||
}
|
||||
git2::RepositoryState::Rebase
|
||||
| git2::RepositoryState::RebaseInteractive
|
||||
| git2::RepositoryState::RebaseMerge => {
|
||||
Some(PromptComponent::bold("rebase", Colour::Pink))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
@ -191,7 +221,7 @@ fn get_git_info(components: &mut Vec<PromptComponent>, repo: &Option<Repository>
|
|||
if unstaged {
|
||||
components.push(PromptComponent::bold("●", Colour::Red));
|
||||
}
|
||||
},
|
||||
None => { },
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue