Skip to content

Commit

Permalink
feat: item display (#11)
Browse files Browse the repository at this point in the history
* feat: item display

* refactor: <🍔> move config to bin pkg

feat: <🍋> support multiple list picker

1. inquire is supported for now.
2. fzf to be implemented.

* feat: added item formatter

* feat: add fzf picker

---------

Co-authored-by: Towry Wang <towry@users.noreply.github.com>
  • Loading branch information
towry and towry authored Aug 2, 2024
1 parent f2cf030 commit 89d3788
Show file tree
Hide file tree
Showing 18 changed files with 346 additions and 37 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ npk sync
- [x] Better package discovery.
- [x] Error message handle.
- [x] Pretty console output.
- [ ] clear terminal after user abort action.

- https://excalidraw.com/#json=7oqX_amJ0GwZaldcHYkHp,hKmYmGQI-AHS2k2AMQFReA
- https://docs.rs/tui/0.19.0/tui/
4 changes: 3 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
naersk.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = {
self,
# self,
nixpkgs,
fenix,
naersk,
Expand Down Expand Up @@ -44,6 +44,7 @@
stable.cargo
stable.rustc
stable.rustfmt
stable.rust-src
stable.clippy
targets.${rustTarget}.stable.rust-std
# targets.wasm32-wasi.stable.rust-std
Expand All @@ -66,6 +67,7 @@
devShells.default = pkgs.mkShell {
buildInputs = buildInputs;
nativeBuildInputs = [pkgs.rust-analyzer-nightly rust-toolchain pkgs.pkg-config];
RUST_SRC_PATH = "${rust-toolchain}/lib/rustlib/src/rust/library";
};
});
}
8 changes: 7 additions & 1 deletion npmpink-bin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "npmpink-bin"
authors = ["Towry Wang <tovvry@gmail.com>"]
version = "0.1.0"
version = "0.1.1"
edition = "2021"

[[bin]]
Expand All @@ -18,3 +18,9 @@ anyhow = "1.0.86"
inquire = "0.7.5"
lazycell = "1.3.0"
regex = "1.10.5"
home = "0.5.9"
lazy_static = "1.5.0"
serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.119"
serde_test = "1.0.176"
thiserror = "1.0.61"
55 changes: 44 additions & 11 deletions npmpink-bin/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
// https://github.com/clap-rs/clap/blob/master/examples/git-derive.rs
// https://docs.rs/clap/latest/clap/_derive/index.html#terminology
use crate::config::{appConfig, Config, HealthCheckError};
use anyhow::{bail, Result};
use clap::{Parser, Subcommand};
use npmpink_core::config::HealthCheckError;
use npmpink_core::item_formatter::PackageItemFormatter;
use npmpink_core::ops::packages::{difference_packages, packages_from_source};
use npmpink_core::package::Package;
use npmpink_core::source::Source;
use npmpink_core::target::Target;
use npmpink_core::{
config::{appConfig, Config},
workspace::Workspace,
};
use npmpink_core::workspace::Workspace;
use npmpink_tui::item::PackageItemDisplay;
use npmpink_tui::select::pick_items;
use npmpink_tui::shell::shell;
use std::cell::{RefCell, RefMut};
use std::path::PathBuf;
use std::process::Command;

use crate::prompts::select_packages;
use std::rc::Rc;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None, arg_required_else_help = true)]
Expand Down Expand Up @@ -302,12 +301,30 @@ fn cmd_handler_package_add(cli: &Cli) -> Result<()> {
lockfile.packages_iter().collect::<Vec<Package>>()
};

let picked = select_packages(difference_packages(&pkgs, &lockfile_pkgs).as_slice())?;
let get_weak_source =
|source_id: &String| config.sources.iter().find(|s| &s.id == source_id).unwrap();

let pkgs_to_pick = difference_packages(&pkgs, &lockfile_pkgs)
.into_iter()
.map(Rc::new);

let picked = pick_items(
pkgs_to_pick
.map(|p| {
let weak_source = get_weak_source(&p.source_id);
PackageItemDisplay::new(PackageItemFormatter::new(Rc::clone(&p), weak_source))
})
.collect::<Vec<PackageItemDisplay>>()
.as_slice(),
Some(Default::default()),
)?;

{
let mut lockfile = target.lockfile_mut()?;

for pkg in picked.iter().cloned() {
lockfile.add_package(pkg.name.clone(), pkg);
let raw = pkg.raw;
lockfile.add_package(raw.inner.name.clone(), Rc::unwrap_or_clone(raw.inner));
}
}
target.flush_lockfile()?;
Expand All @@ -316,20 +333,36 @@ fn cmd_handler_package_add(cli: &Cli) -> Result<()> {
Ok(())
}

// TODO: package and source existence check
fn cmd_handler_package_remove(cli: &Cli) -> Result<()> {
let config = appConfig.lock().unwrap();
let target = cli.target();

let lockfile_pkgs = {
let lockfile = target.lockfile()?;
lockfile.packages_iter().collect::<Vec<Package>>()
};

let picked = select_packages(lockfile_pkgs.as_slice())?;
let get_weak_source =
|source_id: &String| config.sources.iter().find(|s| &s.id == source_id).unwrap();

let pkgs_to_pick = lockfile_pkgs
.into_iter()
.map(Rc::new)
.map(|p| {
PackageItemDisplay::new(PackageItemFormatter::new(
Rc::clone(&p),
get_weak_source(&p.source_id),
))
})
.collect::<Vec<PackageItemDisplay>>();

let picked = pick_items(pkgs_to_pick.as_slice(), Some(Default::default()))?;
{
let mut lockfile = target.lockfile_mut()?;

for pkg in picked.iter().cloned() {
lockfile.remove_package(pkg.name.clone());
lockfile.remove_package(pkg.raw.inner.name.clone());
}
}
target.flush_lockfile()?;
Expand Down
2 changes: 1 addition & 1 deletion npmpink-core/src/config.rs → npmpink-bin/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::source::Source;
use anyhow::Result;
#[allow(unused_imports)]
use home::home_dir as crate_home_dir;
use lazy_static::lazy_static;
use npmpink_core::source::Source;
use serde::{Deserialize, Serialize};
use std::fs;
use std::io::prelude::*;
Expand Down
2 changes: 1 addition & 1 deletion npmpink-bin/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod cli;
mod prompts;
mod config;

use cli::*;
use npmpink_tui::shell::shell;
Expand Down
1 change: 0 additions & 1 deletion npmpink-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ edition = "2021"

[dependencies]
anyhow = "1.0.86"
home = "0.5.9"
ignore = "0.4.22"
lazy_static = "1.5.0"
lazycell = "1.3.0"
Expand Down
12 changes: 12 additions & 0 deletions npmpink-core/src/item_display.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/// |package_name|source_dir_tail|source_id|
#[derive(Clone)]
pub struct PackageItemDisplay {
pub title: String,
pub source_label: String,
pub source_id: String,
}

#[derive(Clone)]
pub struct SourceItemDisplay {
pub title: String,
}
43 changes: 43 additions & 0 deletions npmpink-core/src/item_formatter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use crate::item_display::PackageItemDisplay;
use crate::package::Package;
use crate::source::Source;
use std::rc::Rc;

struct SourceItemFormatter {}

#[derive(Clone)]
pub struct PackageItemFormatter<'a> {
pub inner: Rc<Package>,
pub source: &'a Source,
}

impl<'a> PackageItemFormatter<'a> {
pub fn new(package: Rc<Package>, source: &'a Source) -> PackageItemFormatter<'a> {
PackageItemFormatter {
inner: package,
source,
}
}
}

impl<'a> From<PackageItemFormatter<'a>> for PackageItemDisplay {
fn from(val: PackageItemFormatter<'a>) -> Self {
PackageItemDisplay {
title: val.inner.name.clone(),
source_label: source_label(val.source).unwrap_or("<unkown source>".to_owned()),
source_id: source_id(val.source).unwrap_or("<unkown source id>".to_owned()),
}
}
}

fn source_label(source: &Source) -> Option<String> {
source
.path
.to_owned()
.file_stem()
.and_then(|p| p.to_os_string().into_string().ok())
}

fn source_id(source: &Source) -> Option<String> {
Some(source.id.clone())
}
3 changes: 2 additions & 1 deletion npmpink-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod config;
pub mod item_display;
pub mod item_formatter;
pub mod lockfile;
pub mod ops;
pub mod package;
Expand Down
2 changes: 0 additions & 2 deletions npmpink-core/src/lockfile.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![allow(dead_code)]

use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
Expand Down
8 changes: 8 additions & 0 deletions npmpink-core/src/package.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
use std::fmt;
use std::hash::{Hash, Hasher};

#[derive(PartialEq, Default, Serialize, Deserialize, Debug, Clone, Eq)]
Expand All @@ -24,6 +25,13 @@ impl Package {
}
}

// TODO: better format this package for different pickers.
impl fmt::Display for Package {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} - {}", self.dir, self.source_id)
}
}

#[cfg(test)]
impl Package {
pub(super) fn test_new() -> Self {
Expand Down
3 changes: 3 additions & 0 deletions npmpink-tui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ anyhow = "1.0.86"
ratatui = "0.27.0"
lazy_static = "1.5.0"
anstyle = "1.0.8"
inquire = "0.7.5"
serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.119"
35 changes: 35 additions & 0 deletions npmpink-tui/src/item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use anstyle::{AnsiColor, Style};
use std::fmt;

use npmpink_core::{
item_display::PackageItemDisplay as PackageItemDisplayInner,
item_formatter::PackageItemFormatter,
};

#[derive(Clone)]
pub struct PackageItemDisplay<'a> {
pub inner: PackageItemDisplayInner,
pub raw: PackageItemFormatter<'a>,
}

impl<'a> PackageItemDisplay<'a> {
pub fn new(formatter: PackageItemFormatter<'a>) -> PackageItemDisplay {
PackageItemDisplay {
inner: formatter.clone().into(),
raw: formatter,
}
}
}

impl<'a> fmt::Display for PackageItemDisplay<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let source_label_style = Style::new().fg_color(Some(AnsiColor::Blue.into())).bold();

// TODO: apply style here
write!(
f,
"{} {source_label_style}{}{source_label_style:#}",
self.inner.title, self.inner.source_label
)
}
}
2 changes: 2 additions & 0 deletions npmpink-tui/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod color;
pub mod item;
mod run;
pub mod select;
pub mod shell;
Loading

0 comments on commit 89d3788

Please sign in to comment.