Moved cli binary and bootstrapper into separate crate
This commit is contained in:
parent
026e8599a5
commit
1160730e1f
89
Cargo.lock
generated
89
Cargo.lock
generated
@ -99,57 +99,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c911b090850d79fc64fe9ea01e28e465f65e821e08813ced95bced72f7a8a9b"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap_lex",
|
||||
"is-terminal",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37686beaba5ac9f3ab01ee3172f792fc6ffdd685bfb9e63cfef02c0571a4e8e1"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete_nushell"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7fa41f5e6aa83bd151b70fd0ceaee703d68cd669522795dc812df9edad1252c"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"clap_complete",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "033f6b7a4acb1f358c742aaca805c939ee73b4c6209ae4318ec7aca81c42e646"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_mangen"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4237e29de9c6949982ba87d51709204504fb8ed2fd38232fcb1e5bf7d4ba48c8"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"roff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.11.1"
|
||||
@ -534,9 +483,7 @@ name = "hpk"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"deku",
|
||||
"package-bootstrap",
|
||||
"rayon",
|
||||
"reqwest",
|
||||
"ron",
|
||||
@ -695,18 +642,6 @@ version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146"
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.6"
|
||||
@ -898,24 +833,6 @@ dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267"
|
||||
|
||||
[[package]]
|
||||
name = "package-bootstrap"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e99c0257afd97e84d5b56d8cfd9f3c551047119db7664652b544a1061622b2e9"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_complete_nushell",
|
||||
"clap_mangen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.2.0"
|
||||
@ -1042,12 +959,6 @@ dependencies = [
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roff"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316"
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.8.0"
|
||||
|
14
Cargo.toml
14
Cargo.toml
@ -9,20 +9,10 @@ license = "GPL-3.0-only"
|
||||
[workspace]
|
||||
members = [ "tar" ]
|
||||
|
||||
[[bin]]
|
||||
name = "hpk"
|
||||
path = "src/hpk.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "bootstrap"
|
||||
path = "src/bootstrap.rs"
|
||||
|
||||
[workspace.dependencies]
|
||||
clap = "4.1"
|
||||
deku = "0.16"
|
||||
|
||||
[dependencies]
|
||||
clap.workspace = true
|
||||
deku.workspace = true
|
||||
rayon = "1.7"
|
||||
ron = "0.8"
|
||||
@ -35,10 +25,6 @@ zstd = "0.12"
|
||||
version = "0.4"
|
||||
features = ["serde"]
|
||||
|
||||
[dependencies.package-bootstrap]
|
||||
version = "0.1.0"
|
||||
features = ["mangen"]
|
||||
|
||||
[dependencies.reqwest]
|
||||
version = "0.11"
|
||||
features = ["blocking"]
|
||||
|
@ -65,9 +65,8 @@ allowing for creation of alternate frontends to be written in the future. The va
|
||||
majority of the data is exported rather than having secret, private API's that
|
||||
are not exposed in the library.
|
||||
|
||||
While the hpk source distribution will only include a command line client, provision
|
||||
is made for some nice modern features for a future graphical client. As an example,
|
||||
the *package.ron* file has an optional field to link to an
|
||||
Provision is made for some nice modern features for a future graphical client. As
|
||||
an example, the *package.ron* file has an optional field to link to an
|
||||
[AppStream](https://www.freedesktop.org/wiki/Distributions/AppStream/) metadata
|
||||
file, allowing for nice things such as screenshots in a mode *App Store* like
|
||||
presentation.
|
||||
|
@ -1,30 +0,0 @@
|
||||
use {
|
||||
clap::{Arg, Command},
|
||||
hpk::cli,
|
||||
package_bootstrap::Bootstrap,
|
||||
std::{error::Error, path::PathBuf},
|
||||
};
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let matches = Command::new("bootstrap")
|
||||
.about("install the software")
|
||||
.author("Nathan Fisher")
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.args([
|
||||
Arg::new("arch")
|
||||
.help("the architecture of the binary to be installed")
|
||||
.short('a')
|
||||
.long("arch")
|
||||
.num_args(1),
|
||||
Arg::new("output")
|
||||
.help("the output directory for the installation")
|
||||
.required(true)
|
||||
.num_args(1),
|
||||
])
|
||||
.get_matches();
|
||||
let outdir = matches.get_one::<String>("output").unwrap().to_string();
|
||||
let outdir = PathBuf::from(&outdir);
|
||||
let arch = matches.get_one::<String>("arch").map(|x| x.to_string());
|
||||
Bootstrap::new("hpk", cli::cli()).install(&outdir, arch, 1)?;
|
||||
Ok(())
|
||||
}
|
159
src/cli/mod.rs
159
src/cli/mod.rs
@ -1,159 +0,0 @@
|
||||
use clap::{value_parser, Arg, ArgAction, Command, ValueHint};
|
||||
|
||||
pub fn cli() -> Command {
|
||||
Command::new("hpk")
|
||||
.about("A package manager for HitchHiker Linux")
|
||||
.author("Nathan Fisher")
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.propagate_version(true)
|
||||
.arg_required_else_help(true)
|
||||
.subcommands([
|
||||
create(),
|
||||
init(),
|
||||
search(),
|
||||
info(),
|
||||
install(),
|
||||
remove(),
|
||||
upgrade(),
|
||||
])
|
||||
}
|
||||
|
||||
fn create() -> Command {
|
||||
Command::new("create")
|
||||
.about("Create a new package from a directory of files")
|
||||
.args([
|
||||
Arg::new("directory")
|
||||
.help("the directory where the files are located")
|
||||
.required(true)
|
||||
.num_args(1),
|
||||
Arg::new("output")
|
||||
.help("the location to save the package archive and package.ron [default: current working directory]")
|
||||
.short('o')
|
||||
.long("output")
|
||||
.value_name("directory")
|
||||
.value_hint(ValueHint::DirPath)
|
||||
.num_args(1),
|
||||
Arg::new("specs")
|
||||
.help("path to the package specs file in `ron` format")
|
||||
.short('s')
|
||||
.long("specs")
|
||||
.conflicts_with_all(["name", "package-version", "release", "dependencies"])
|
||||
.num_args(1),
|
||||
Arg::new("name")
|
||||
.help("package name")
|
||||
.short('n')
|
||||
.long("name")
|
||||
.num_args(1)
|
||||
.required_unless_present("specs"),
|
||||
Arg::new("package-version")
|
||||
.help("package version")
|
||||
.short('v')
|
||||
.long("package-version")
|
||||
.num_args(1)
|
||||
.required_unless_present("specs"),
|
||||
Arg::new("release")
|
||||
.help("release number")
|
||||
.short('r')
|
||||
.long("release")
|
||||
.default_value("1")
|
||||
.value_parser(value_parser!(u8)),
|
||||
Arg::new("dependencies")
|
||||
.help("a comma separated list of dependencies")
|
||||
.short('d')
|
||||
.long("dependencies")
|
||||
.value_delimiter(',')
|
||||
.num_args(1..),
|
||||
])
|
||||
}
|
||||
|
||||
fn init() -> Command {
|
||||
Command::new("init")
|
||||
.about("Initialize a package `specs.ron` file in the current directory")
|
||||
.args([
|
||||
Arg::new("name")
|
||||
.help("package name")
|
||||
.short('n')
|
||||
.long("name")
|
||||
.num_args(1),
|
||||
Arg::new("package-version")
|
||||
.help("package version")
|
||||
.short('v')
|
||||
.long("package-version")
|
||||
.num_args(1),
|
||||
Arg::new("release")
|
||||
.help("release number")
|
||||
.short('r')
|
||||
.long("release")
|
||||
.default_value("1")
|
||||
.value_parser(value_parser!(usize)),
|
||||
Arg::new("dependencies")
|
||||
.help("a comma separated list of dependencies")
|
||||
.short('d')
|
||||
.long("dependencies")
|
||||
.value_delimiter(',')
|
||||
.num_args(1..),
|
||||
])
|
||||
}
|
||||
|
||||
fn search() -> Command {
|
||||
Command::new("search")
|
||||
.about("Search for packages")
|
||||
.visible_alias("se")
|
||||
.args([
|
||||
Arg::new("installed")
|
||||
.help("only list installed packages")
|
||||
.short('i')
|
||||
.long("installed")
|
||||
.action(ArgAction::SetTrue),
|
||||
Arg::new("remote")
|
||||
.help("do not list installed packages")
|
||||
.short('r')
|
||||
.long("remote")
|
||||
.conflicts_with("installed")
|
||||
.action(ArgAction::SetTrue),
|
||||
Arg::new("names")
|
||||
.help("only search in package names, not descriptions")
|
||||
.short('n')
|
||||
.long("names")
|
||||
.action(ArgAction::SetTrue),
|
||||
Arg::new("query").use_value_delimiter(false).required(true),
|
||||
])
|
||||
}
|
||||
|
||||
fn info() -> Command {
|
||||
Command::new("info")
|
||||
.about("Display information about a specific package")
|
||||
.arg(Arg::new("name").required(true))
|
||||
}
|
||||
|
||||
fn install() -> Command {
|
||||
Command::new("install")
|
||||
.about("Install packages")
|
||||
.visible_aliases(["in", "add"])
|
||||
.args([
|
||||
Arg::new("package")
|
||||
.required_unless_present("local")
|
||||
.conflicts_with("local")
|
||||
.num_args(1..),
|
||||
Arg::new("local")
|
||||
.help("install a package from the filesystem")
|
||||
.short('l')
|
||||
.long("local")
|
||||
.value_name("package")
|
||||
.value_hint(ValueHint::FilePath)
|
||||
.num_args(1..),
|
||||
])
|
||||
}
|
||||
|
||||
fn remove() -> Command {
|
||||
Command::new("remove")
|
||||
.about("Remove packages")
|
||||
.visible_aliases(["rm", "del"])
|
||||
.arg(Arg::new("package").required(true).num_args(1..))
|
||||
}
|
||||
|
||||
fn upgrade() -> Command {
|
||||
Command::new("upgrade")
|
||||
.about("Upgrade packages")
|
||||
.visible_aliases(["update", "up", "sync"])
|
||||
}
|
97
src/hpk.rs
97
src/hpk.rs
@ -1,97 +0,0 @@
|
||||
use {
|
||||
clap::ArgMatches,
|
||||
hpk::{cli::cli, Creator, Dependency, Message, Specs, Version},
|
||||
ron::ser::{to_writer_pretty, PrettyConfig},
|
||||
std::{env, error::Error, fs::File, io::{BufWriter, self}, path::PathBuf, sync::mpsc},
|
||||
};
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let matches = cli().get_matches();
|
||||
match matches.subcommand() {
|
||||
Some(("create", matches)) => create(matches)?,
|
||||
Some(("init", matches)) => {
|
||||
let specsfile = init(matches)?;
|
||||
println!("Created specsfile {}", specsfile.display());
|
||||
}
|
||||
Some(("search", matches)) => search(matches)?,
|
||||
Some(("install", matches)) => install(matches)?,
|
||||
Some(("remove", matches)) => remove(matches)?,
|
||||
Some(("upgrade", _)) => upgrade()?,
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create(matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
|
||||
let dir = PathBuf::from(matches.get_one::<String>("directory").unwrap().to_string());
|
||||
let outdir = if let Some(d) = matches.get_one::<String>("output") {
|
||||
PathBuf::from(&d.to_string())
|
||||
} else {
|
||||
env::current_dir()?
|
||||
};
|
||||
let mut specs = if let Some(s) = matches.get_one::<String>("specs") {
|
||||
let path = PathBuf::from(s.to_string());
|
||||
let fd = File::open(path)?;
|
||||
ron::de::from_reader(fd)?
|
||||
} else {
|
||||
Specs::default()
|
||||
};
|
||||
if let Some(n) = matches.get_one::<String>("name") {
|
||||
specs.name = n.to_string();
|
||||
}
|
||||
if let Some(v) = matches.get_one::<String>("package-version") {
|
||||
specs.version = v.to_string().parse::<Version>()?;
|
||||
}
|
||||
if let Some(r) = matches.get_one::<u8>("release") {
|
||||
specs.release = *r;
|
||||
}
|
||||
if let Some(deps) = matches.get_many::<String>("dependencies") {
|
||||
for d in deps {
|
||||
let d = Dependency {
|
||||
name: d.to_string(),
|
||||
version: (None, None),
|
||||
};
|
||||
specs.dependencies.push(d);
|
||||
}
|
||||
}
|
||||
let creator = Creator::new(&dir, specs)?;
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
creator.create(&outdir, sender)?;
|
||||
for msg in receiver.iter() {
|
||||
match msg {
|
||||
Message::MemberAdded(_s) => {}
|
||||
Message::Success(s) => println!("{s}"),
|
||||
Message::Failure(s) => {
|
||||
eprint!("{s}");
|
||||
return Err(io::Error::new(io::ErrorKind::Other, s).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn init(matches: &ArgMatches) -> Result<PathBuf, Box<dyn Error>> {
|
||||
let specsfile = PathBuf::from("package.specs");
|
||||
let cfg = PrettyConfig::new().struct_names(true);
|
||||
let buf = File::create(&specsfile)?;
|
||||
let writer = BufWriter::new(buf);
|
||||
let specs = Specs::try_from(matches)?;
|
||||
to_writer_pretty(writer, &specs, cfg)?;
|
||||
Ok(specsfile)
|
||||
}
|
||||
|
||||
fn search(_matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn install(_matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove(_matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn upgrade() -> Result<(), Box<dyn Error>> {
|
||||
unimplemented!();
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
#![warn(clippy::all, clippy::pedantic)]
|
||||
pub mod cli;
|
||||
mod creator;
|
||||
mod db;
|
||||
mod hooks;
|
||||
|
@ -1,9 +1,7 @@
|
||||
use {
|
||||
super::{Group, User},
|
||||
crate::{Dependency, Version},
|
||||
clap::ArgMatches,
|
||||
serde::{Deserialize, Serialize},
|
||||
std::{env, error::Error, ffi::OsStr},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
|
||||
@ -31,46 +29,3 @@ pub struct Specs {
|
||||
/// an optional post installation shell script to be run
|
||||
pub post_install: Option<String>,
|
||||
}
|
||||
|
||||
impl TryFrom<&ArgMatches> for Specs {
|
||||
type Error = Box<dyn Error>;
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
fn try_from(matches: &ArgMatches) -> Result<Self, Self::Error> {
|
||||
let mut specs = Specs::default();
|
||||
let mut name: Option<String> = None;
|
||||
let mut version: Option<Version> = None;
|
||||
let cwd = env::current_dir()?;
|
||||
if let Some(dir) = cwd.file_name().and_then(OsStr::to_str) {
|
||||
if let Some((n, v)) = dir.split_once('-') {
|
||||
name = Some(n.to_string());
|
||||
if let Ok(v) = v.parse() {
|
||||
version = Some(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(name) = matches.get_one::<String>("name") {
|
||||
specs.name = name.to_string();
|
||||
} else if let Some(n) = name {
|
||||
specs.name = n;
|
||||
}
|
||||
if let Some(version) = matches.get_one::<String>("package-version") {
|
||||
specs.version = version.parse()?;
|
||||
} else if let Some(v) = version {
|
||||
specs.version = v;
|
||||
}
|
||||
if let Some(release) = matches.get_one::<usize>("release") {
|
||||
specs.release = *release as u8;
|
||||
}
|
||||
if let Some(deps) = matches.get_many::<String>("dependencies") {
|
||||
let deps = deps
|
||||
.map(|d| Dependency {
|
||||
name: d.to_string(),
|
||||
version: (None, None),
|
||||
})
|
||||
.collect::<Vec<Dependency>>();
|
||||
specs.dependencies = deps;
|
||||
}
|
||||
Ok(specs)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user