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
|
/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
|
||||||
|
];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
76
src/main.rs
76
src/main.rs
|
@ -1,7 +1,7 @@
|
||||||
use ansi_term::{Colour as AnsiColour, Style};
|
use ansi_term::{Colour as AnsiColour, Style};
|
||||||
|
use gethostname::gethostname;
|
||||||
use git2::{Repository, Status as GitStatus};
|
use git2::{Repository, Status as GitStatus};
|
||||||
use std::{fmt::Display, path::PathBuf};
|
use std::{fmt::Display, path::PathBuf};
|
||||||
use gethostname::gethostname;
|
|
||||||
|
|
||||||
struct PromptComponent {
|
struct PromptComponent {
|
||||||
text: String,
|
text: String,
|
||||||
|
@ -21,8 +21,8 @@ enum Colour {
|
||||||
fn from_hex(hex: u32) -> AnsiColour {
|
fn from_hex(hex: u32) -> AnsiColour {
|
||||||
AnsiColour::RGB(
|
AnsiColour::RGB(
|
||||||
(hex >> 16 & 0xff) as u8,
|
(hex >> 16 & 0xff) as u8,
|
||||||
(hex >> 8 & 0xff) as u8,
|
(hex >> 8 & 0xff) as u8,
|
||||||
(hex >> 0 & 0xff) as u8,
|
(hex & 0xff) as u8,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ impl PromptComponent {
|
||||||
space_after: true,
|
space_after: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bold(text: &str, colour: Colour) -> Self {
|
fn bold(text: &str, colour: Colour) -> Self {
|
||||||
Self::new(text, colour.to_ansi().bold())
|
Self::new(text, colour.to_ansi().bold())
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ impl Display for PromptComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
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()
|
status.parse().unwrap()
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
|
@ -84,13 +84,17 @@ fn main() {
|
||||||
|
|
||||||
let mut components = Vec::new();
|
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() {
|
if std::env::var("FSH_NO_HOSTNAME").is_ok() {
|
||||||
components.push(PromptComponent::bold(&user, Colour::Purple));
|
components.push(PromptComponent::bold(&user, Colour::Purple));
|
||||||
} else {
|
} else {
|
||||||
components.push(PromptComponent::bold(&user, Colour::Purple).no_space());
|
components.push(PromptComponent::bold(&user, Colour::Purple).no_space());
|
||||||
components.push(PromptComponent::unstyled("@").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));
|
components.push(PromptComponent::bold(&hostname, Colour::Pink));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +122,10 @@ fn main() {
|
||||||
if last_status == 0 {
|
if last_status == 0 {
|
||||||
components.push(PromptComponent::bold("\u{f061}", Colour::Yellow));
|
components.push(PromptComponent::bold("\u{f061}", Colour::Yellow));
|
||||||
} else {
|
} 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 {
|
for component in components {
|
||||||
|
@ -135,18 +142,18 @@ fn get_git_info(components: &mut Vec<PromptComponent>, repo: &Option<Repository>
|
||||||
Some(repo) => {
|
Some(repo) => {
|
||||||
let head = match repo.head() {
|
let head = match repo.head() {
|
||||||
Ok(head) => Some(head.shorthand().unwrap().to_string()),
|
Ok(head) => Some(head.shorthand().unwrap().to_string()),
|
||||||
Err(ref e) if e.code() == git2::ErrorCode::NotFound => {
|
Err(ref e) if e.code() == git2::ErrorCode::NotFound => None,
|
||||||
None
|
|
||||||
}
|
|
||||||
Err(ref e) if e.code() == git2::ErrorCode::UnbornBranch => {
|
Err(ref e) if e.code() == git2::ErrorCode::UnbornBranch => {
|
||||||
// https://github.com/starship/starship/commit/489838e6a24ea1c08be6abe56d066724a1d59abd#diff-d6346fd7d17270b1282142aeeda9c4bc2b7d8fd0f37b24a1c871a9257f0ed0aaR324-R336
|
// https://github.com/starship/starship/commit/489838e6a24ea1c08be6abe56d066724a1d59abd#diff-d6346fd7d17270b1282142aeeda9c4bc2b7d8fd0f37b24a1c871a9257f0ed0aaR324-R336
|
||||||
let mut head_path = repo.path().to_path_buf();
|
let mut head_path = repo.path().to_path_buf();
|
||||||
head_path.push("HEAD");
|
head_path.push("HEAD");
|
||||||
|
|
||||||
std::fs::read_to_string(&head_path)
|
std::fs::read_to_string(&head_path)
|
||||||
.ok().unwrap()
|
.ok()
|
||||||
|
.unwrap()
|
||||||
.lines()
|
.lines()
|
||||||
.next().unwrap()
|
.next()
|
||||||
|
.unwrap()
|
||||||
.trim()
|
.trim()
|
||||||
.split('/')
|
.split('/')
|
||||||
.last()
|
.last()
|
||||||
|
@ -155,27 +162,50 @@ fn get_git_info(components: &mut Vec<PromptComponent>, repo: &Option<Repository>
|
||||||
Err(e) => Err(e).unwrap(),
|
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 unstaged = false;
|
||||||
let mut staged = false;
|
let mut staged = false;
|
||||||
for status in repo.statuses(None).unwrap().iter() {
|
for status in repo.statuses(None).unwrap().iter() {
|
||||||
let status = status.status();
|
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;
|
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;
|
staged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let action = match repo.state() {
|
let action = match repo.state() {
|
||||||
git2::RepositoryState::Merge => Some(PromptComponent::bold("merge", Colour::Pink)),
|
git2::RepositoryState::Merge => Some(PromptComponent::bold("merge", Colour::Pink)),
|
||||||
git2::RepositoryState::Revert | git2::RepositoryState::RevertSequence => Some(PromptComponent::bold("revert", Colour::Pink)),
|
git2::RepositoryState::Revert | git2::RepositoryState::RevertSequence => {
|
||||||
git2::RepositoryState::CherryPick | git2::RepositoryState::CherryPickSequence => Some(PromptComponent::bold("cherry pick", Colour::Pink)),
|
Some(PromptComponent::bold("revert", Colour::Pink))
|
||||||
git2::RepositoryState::Rebase | git2::RepositoryState::RebaseInteractive | git2::RepositoryState::RebaseMerge => Some(PromptComponent::bold("rebase", 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,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -187,11 +217,11 @@ fn get_git_info(components: &mut Vec<PromptComponent>, repo: &Option<Repository>
|
||||||
if staged {
|
if staged {
|
||||||
components.push(PromptComponent::bold("+", Colour::Green));
|
components.push(PromptComponent::bold("+", Colour::Green));
|
||||||
}
|
}
|
||||||
|
|
||||||
if unstaged {
|
if unstaged {
|
||||||
components.push(PromptComponent::bold("●", Colour::Red));
|
components.push(PromptComponent::bold("●", Colour::Red));
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => { },
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue