diff --git a/.idea/jsonSchemas.xml b/.idea/jsonSchemas.xml new file mode 100644 index 0000000..f5ad76c --- /dev/null +++ b/.idea/jsonSchemas.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 17326aa..42323c9 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,43 @@ > "A package manager and builder but like rust." > -- Gandhi (2050) -> ***not even close to done*** :) +> ***Almost to a point you can use it*** :) + +Packager is a simple yet powerful package manager + +## Install a package +pkgr supports fetching packages with a: +- path +- url (http/https) +- package locator + +```shell +# example with path +pkgr install ./foxy/snek.pkg +# example with url +pkgr install https://example.com/doggo.pkg +# example with package locator +pkgr install foo:stable,bar +``` + +## Composing a package +Right now, pkgr does not have a compose/package command. (it's in the works dw!) +You can create a package with `pkg.py`! + +```shell +# Usage: pkg.py [ ...] +# example: +python pkg.py manifest.toml example.pkg root/ source/ scripts/ +# this will create a package with an archive that look like this: +# [header+manifest] +# ... +# [archive: +# root/ +# source/ +# scripts/ +# ] +``` + +It's not perfect, but it'll get the job done :) + -Packager is a simple yet powerful package manager \ No newline at end of file diff --git a/bootpkg/src/prelude.rs b/bootpkg/src/prelude.rs index 9406cdb..b5ec6fe 100644 --- a/bootpkg/src/prelude.rs +++ b/bootpkg/src/prelude.rs @@ -30,12 +30,12 @@ pub fn mani_from_str(s: &str) -> Manifest> { fs: mani.fs, bin: mani.bin, build: mani.build, - pkgr: bmani.pkgr, + ext: bmani.pkgr, } } pub fn run_bootstrap(mani: Manifest>) -> bool { - if let Some(pkgr) = mani.pkgr { + if let Some(pkgr) = mani.ext { if let Some(bootstrap) = pkgr.bootstrap { fn run_command>(s: S) -> i32 { std::process::Command::new("sh") diff --git a/build b/build index 2f69899..c245f7a 100755 --- a/build +++ b/build @@ -3,7 +3,7 @@ build_pkgr() { cd pkgr mkdir -p dist/root/{usr/bin,etc/pkgr} - echo -e "You can't use pkgr to update pkgr because the file will be in use while updating.\nuse bootpkg" > dist/root/etc/pkgr/YOU-CAN-NOT-USE-PKGR-TO-UPDATE-PKGR.txt + echo -e "You can't use pkgr to update pkgr because the file will be in use while updating.\nuse bootpkg" > dist/root/etc/pkgr.d/YOU-CAN-NOT-USE-PKGR-TO-UPDATE-PKGR.txt # for bin cargo build -r diff --git a/docs/README.md b/docs/README.md index 0e9b295..5b84964 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,7 +9,9 @@ pkgr is the main tool for the packager. Because this tool is so feature rich, it has its own [README](./pkgr/README.md). ## bootpkg -bootpkg is a tool primariliy used to bootstrap the packager. +`bootpkg` is a simple pkgr variant. +It doesn't contain anything fancy and is only used to install and update pkgr. +Using it for anything other than pkgr is not recommended. ### Usage @@ -17,4 +19,4 @@ bootpkg is a tool primariliy used to bootstrap the packager. bootpkg strap ./pkgr.pkg ``` -This will extract the pkgfile and read the `[pkgr.bootstrap]` section to bootstrap the packager or any other package. \ No newline at end of file +This will extract the pkgfile and read the `[pkgr.bootstrap]` section to bootstrap the packager or any other package. diff --git a/docs/pkgfiles/current.md b/docs/pkgfiles/current.md index bd0eb22..e5cd8cc 100644 --- a/docs/pkgfiles/current.md +++ b/docs/pkgfiles/current.md @@ -7,7 +7,7 @@ PKGFiles are an all-in-one solution to install a package. ## Overhead -Because pkgfiles include everything, many times you can download more than what is needed. +Because pkgfiles include everything, many times you're downloading more than what is needed. This may seem stupid but pkgfiles are *not* meant to stay on your system. ## Format diff --git a/manifest/src/pkgr.rs b/manifest/src/ext.rs similarity index 80% rename from manifest/src/pkgr.rs rename to manifest/src/ext.rs index 530a37c..b47a60c 100644 --- a/manifest/src/pkgr.rs +++ b/manifest/src/ext.rs @@ -2,9 +2,9 @@ use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct PKGR {} +pub struct Extension {} -impl Display for PKGR { +impl Display for Extension { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "") } diff --git a/manifest/src/lib.rs b/manifest/src/lib.rs index 0d52840..89526f2 100644 --- a/manifest/src/lib.rs +++ b/manifest/src/lib.rs @@ -6,17 +6,17 @@ pub mod bin; pub mod build; pub mod fs; pub mod package; -pub mod pkgr; +pub mod ext; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(default)] -pub struct Manifest> { +pub struct Manifest> { pub package: package::Package, pub dependencies: HashMap, pub fs: fs::FS, pub bin: Option, pub build: Option, - pub pkgr: P, + pub ext: E, } impl Manifest

{ @@ -50,7 +50,7 @@ impl Default for Manifest { fs: fs::FS::default(), bin: None, build: None, - pkgr: None, + ext: None, } } } diff --git a/package.example.toml b/package.example.toml index c99108d..c20aabb 100644 --- a/package.example.toml +++ b/package.example.toml @@ -84,16 +84,16 @@ install_script = "scripts/install" # relative to pkg [build.dependencies] base = "latest,stable" # selected by default -## pkgr.* +## ext.* # packager is the official client but you may use other clients supporting the "pkgr v1 spec". -# other clients may offer extra functionality this must be put under "pkgr.*" -[pkgr] +# other clients may offer extra functionality this must be put under "ext.*" +[ext] -## pkgr.bootstrap +## ext.bootstrap # This section is used for bootpkg. An edition of packager that bootstraps the full version. # This exists so that packager is easy to install on anything! # and only 1 release channel for pkgr -[pkgr.bootstrap] +[ext.bootstrap] ## any non-zero = installed check_installed_commands = [ "sh scripts/check_installed" diff --git a/pkgr/Cargo.toml b/pkgr/Cargo.toml index d6b098f..e43b436 100644 --- a/pkgr/Cargo.toml +++ b/pkgr/Cargo.toml @@ -25,3 +25,5 @@ reqwest = { version = "0.11.18", features = ["blocking"] } tar = "0.4.39" humantime = "2.1.0" expanduser = "1.2.2" +url = { version = "2.4.0", features = ["serde"] } +dns-lookup = "2.0.3" diff --git a/pkgr/package.toml b/pkgr/package.toml index 723ebed..fa95cd9 100644 --- a/pkgr/package.toml +++ b/pkgr/package.toml @@ -1,66 +1,32 @@ [package] -name = "packager" #* -description = "A package installation tool" #* -version = 1 # this can automatically be incremented when publishing by running `pkgr publish -i ...` +name = "packager" +description = "A package installation tool" +version = 1 tags = [ "prod", "pkgr-spec-1" ] type = "application" +arch = "x86_64" -arch = "x86_64" # this is automatically filled by `pkgr publish ...` - -## dependencies -# you may use the following syntax -# "" or ",,..." [dependencies] -## bin -# Used for systems that don't want to build pkgs. -[bin] # binary files root +[bin] +root = "/root" -## bin.root -# ** RELATIVE TO PACKAGE ROOT ** -# bin.root specifies the root of the installed tree. -# anything in here will be overlayed on top of the system. -root = "/root" #* - -## bin.checksums -# ** KEYS are relative to BIN.ROOT ** -# ** VALUES are relative to PKG ROOT ** -# checksums is used to perform checksums before install -# values may be paths or a uri. You may include variables. -# supported variables: -# - @name -# - @version -# - @display_version [bin.checksums] "/usr/bin/pkgr" = "https://ixvd.net/checksums/packager/@version" -## build -# Scripts will be copied to a custom root. -# After the pacakge is built, the install script is ran. -# After the install script the build directory will be deleted and an CTREE (changed tree) will be generated. -# Then the CTREE will be used to copy the files over. [build] -build_script = "scripts/build" # relative to pkg -install_script = "scripts/install" # relative to pkg +build_script = "scripts/build" +install_script = "scripts/install" [build.dependencies] -## pkgr.* -# packager is the official client but you may use other clients supporting the "pkgr v1 spec". -# other clients may offer extra functionality this must be put under "pkgr.*" -[pkgr] +[ext] -## pkgr.bootstrap -# This section is used for bootpkg. An edition of packager that bootstraps the full version. -# This exists so that packager is easy to install on anything! -# and only 1 release channel for pkgr -[pkgr.bootstrap] -## any non-zero = installed +[ext.bootstrap] check_installed_commands = [ "file /usr/bin/pkgr" ] -# any non-zero = fail commands = [ "cp root/usr/bin/pkgr /usr/bin/pkgr" ] diff --git a/pkgr/skel/etc/pkgr.d/repos.toml b/pkgr/skel/etc/pkgr.d/repos.toml new file mode 100644 index 0000000..2723e7b --- /dev/null +++ b/pkgr/skel/etc/pkgr.d/repos.toml @@ -0,0 +1,4 @@ +[repo.main] +name = "Main" +url = "tcp://pkgs.ixvd.net:1050" + diff --git a/pkgr/skel/etc/pkgr.toml b/pkgr/skel/etc/pkgr.toml new file mode 100644 index 0000000..2ee5004 --- /dev/null +++ b/pkgr/skel/etc/pkgr.toml @@ -0,0 +1,7 @@ +build_by_default = false +tmp_dir = "/tmp/pkgr" + +[storage] +repo_file = "/etc/pkgr.d/repos.toml" +data_dir = "/var/lib/pkgr/packages" +index_dir = "/var/lib/pkgr/indexes" \ No newline at end of file diff --git a/pkgr/skel/var/lib/pkgr/indexes/repo.toml b/pkgr/skel/var/lib/pkgr/indexes/repo.toml new file mode 100644 index 0000000..47fa234 --- /dev/null +++ b/pkgr/skel/var/lib/pkgr/indexes/repo.toml @@ -0,0 +1,20 @@ +[index.main] +last_update = "1610219288" +[index.main.packager] +versions = [1, 2, 3] +tags = ["tag"] + +## rust +# IndexedPackage +# - name -> packager +# - origin_repo -> main +# - versions -> [1,2,3] +# - tags -> ["tag"] +# - get_package() -> Package + +## rust +# Repo +# - name -> main +# - last_update -> 1610219288 +# - update_repo() -> io::Result<()> +# - searchIndex(p: PackageIdentifier) -> IndexedPackage \ No newline at end of file diff --git a/pkgr/src/api/client.rs b/pkgr/src/api/client.rs new file mode 100644 index 0000000..e69de29 diff --git a/pkgr/src/api/mod.rs b/pkgr/src/api/mod.rs index 3cec172..1ed3d70 100644 --- a/pkgr/src/api/mod.rs +++ b/pkgr/src/api/mod.rs @@ -1,27 +1,63 @@ -use reqwest::blocking::Response; +use std::collections::HashMap; +use serde; +use serde::{Deserialize, Serialize}; -pub struct APITransaction { - /// Query made to API. - query: String, //TODO: enum - /// Response struct from abstracted library - _response: Option -} +pub mod client; -impl APITransaction { - pub fn new(_response: Option) -> Self { - APITransaction { - query: String::default(), - _response - } +#[derive(Serialize, Deserialize)] +pub enum Query { + #[serde(rename = "pull")] + Pull { + name: String, + version: Option, + tags: Vec + }, + #[serde(rename = "push")] + Push { + // todo: review me pls + _data: Vec + }, + #[serde(rename = "index")] + Index { + request_update: bool, + fetch: bool } } -pub struct API { - base_url: String, +#[derive(Serialize, Deserialize)] +pub struct Request { + version: u32, + id: String, token: Option, - history: Vec + query: HashMap } -impl API { +#[derive(Serialize, Deserialize)] +pub struct DataErrorDetails { + actor: String, + detailed_cause: String, + recovery_options: Vec, +} +#[derive(Serialize, Deserialize)] +pub struct DataError { + name: String, + cause: Option, + details: Option +} + +#[derive(Serialize, Deserialize)] +pub enum Data { + Pull { + _data: Option>, + } +} + +#[derive(Serialize, Deserialize)] +pub struct Response { + version: u32, + id: String, + reply_to: String, + errors: HashMap, + data: HashMap } \ No newline at end of file diff --git a/pkgr/src/commands.rs b/pkgr/src/commands.rs index 869e961..80e9448 100644 --- a/pkgr/src/commands.rs +++ b/pkgr/src/commands.rs @@ -1,16 +1,17 @@ use std::process::exit; use clap::{Parser, Subcommand}; +use colored::Colorize; use log::{debug, error, info, trace, warn}; -use colored::Colorize; use manifest::package::PackageType; -use crate::CONFIG; + use crate::package::identifier::PackageIdentifier; use crate::package::Package; use crate::package::queue::PackageQueue; use crate::process::Process; use crate::types::fetch::TryFetch; +use crate::util::prompts::prompt_bool; #[derive(Parser, Debug)] #[clap(name = "pkgr", version)] @@ -25,6 +26,8 @@ pub enum Command { Install { #[arg(short, long, default_value_t = false)] build: bool, + #[arg(short, long, default_value_t = false)] + ask: bool, package_identifier: PackageIdentifier, }, /// Remove a package from the system @@ -57,6 +60,7 @@ impl Command { match self { Command::Install { build, + ask, package_identifier, } => { warn!("Installer does not run in isolation."); @@ -80,6 +84,15 @@ impl Command { let mut queue = PackageQueue::new(); queue.add_package(pkg, *build); trace!("Installing queue..."); + { + if *ask { + info!("Install following packages?"); + info!(target: "item", "{}", queue); + if !prompt_bool("Continue?", false) { + return; + } + } + } queue.install(*build); let end = std::time::Instant::now(); diff --git a/pkgr/src/config.rs b/pkgr/src/config/mod.rs similarity index 78% rename from pkgr/src/config.rs rename to pkgr/src/config/mod.rs index 9a932d2..4c6876e 100644 --- a/pkgr/src/config.rs +++ b/pkgr/src/config/mod.rs @@ -1,4 +1,8 @@ use serde::{Deserialize, Serialize}; +use storage::Storage; + +mod storage; +pub mod repos; #[derive(Debug, Serialize, Deserialize)] pub struct Config { @@ -6,13 +10,16 @@ pub struct Config { pub build_by_default: bool, #[serde(default)] pub tmp_dir: Option, + #[serde(default)] + pub storage: Storage } impl Default for Config { fn default() -> Config { Config { build_by_default: false, - tmp_dir: Some(String::from("/tmp/pkgr")) + tmp_dir: Some(String::from("/tmp/pkgr")), + storage: Storage::default() } } } diff --git a/pkgr/src/config/repos.rs b/pkgr/src/config/repos.rs new file mode 100644 index 0000000..8594a25 --- /dev/null +++ b/pkgr/src/config/repos.rs @@ -0,0 +1,37 @@ +use std::collections::HashMap; +use std::str::FromStr; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Serialize, Deserialize)] +pub struct Repo { + #[serde(default)] + pub name: String, + pub uri: Url +} + +impl Default for Repo { + fn default() -> Self { + Repo { + name: String::from("Repo"), + uri: Url::parse("tcp://0.0.0.0:0000").unwrap() + } + } +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct RepoFile { + pub repos: HashMap +} + +impl RepoFile { + pub fn from_path(path: &str) -> Result { + match std::fs::read_to_string(path) { + Ok(s) => match toml::from_str(&s) { + Ok(c) => Ok(c), + Err(e) => Err(format!("failed to parse config: {}", e)), + }, + Err(e) => Err(format!("failed to read config: {}", e)), + } + } +} \ No newline at end of file diff --git a/pkgr/src/config/storage.rs b/pkgr/src/config/storage.rs new file mode 100644 index 0000000..5fa8fa1 --- /dev/null +++ b/pkgr/src/config/storage.rs @@ -0,0 +1,24 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Storage { + /// Where the repositories are defined. + #[serde(default)] + pub repo_file: String, + /// Where to store pkgs data + #[serde(default)] + pub data_dir: String, + /// Where to store repo indexes + #[serde(default)] + pub index_dir: String, +} + +impl Default for Storage { + fn default() -> Self { + Storage { + repo_file: String::from("/etc/pkgr.d/repos.toml"), + data_dir: String::from("/var/lib/pkgr/packages"), + index_dir: String::from("/var/lib/pkgr/indexes"), + } + } +} diff --git a/pkgr/src/main.rs b/pkgr/src/main.rs index 798eb1d..3aff896 100644 --- a/pkgr/src/main.rs +++ b/pkgr/src/main.rs @@ -9,6 +9,8 @@ mod commands; mod logging; /// Package and helpers. mod package; +/// Repo and helpers +mod repo; /// Process wrapper with logging wrapper. mod process; /// tmpfs wrapper. diff --git a/pkgr/src/package/installer/mod.rs b/pkgr/src/package/installer/mod.rs index da37f1b..4dbeab0 100644 --- a/pkgr/src/package/installer/mod.rs +++ b/pkgr/src/package/installer/mod.rs @@ -1,22 +1,17 @@ +use std::io; use std::fs::remove_dir_all; use std::path::Path; -use std::process::exit; -use std::{io, thread}; -use libc::SIGINT; -use log::{debug, error, info, trace}; +use log::{debug, trace}; use errors::{BinError, BuildError, InstallError}; use manifest::Manifest; use pkgfile::PKGFile; - use crate::CONFIG; -use crate::package::identifier::{PackageIdentifier, PackageLocator}; -use crate::package::Package; + use crate::tmpfs::TempDir; use crate::types::fetch::TryFetch; -use crate::util::fs::{copy_recursively, visit_dirs}; -use crate::util::prompts::{is_noninteractive, prompt_bool}; +use crate::util::fs::copy_recursively; pub mod errors; @@ -114,11 +109,17 @@ impl PackageInstaller { } } - match self.install_type { + let r = match self.install_type { InstallType::Bin => self.bin() .map_err(|e| InstallError::BinError(e)), InstallType::Build => self.build() .map_err(|e| InstallError::BuildError(e)), + }; + + if let Err(e) = r { + return Err(e); } + + Ok(()) } } diff --git a/pkgr/src/package/queue.rs b/pkgr/src/package/queue.rs index 16a7b95..601d8da 100644 --- a/pkgr/src/package/queue.rs +++ b/pkgr/src/package/queue.rs @@ -1,8 +1,11 @@ +use std::fmt::{Display, Formatter}; + use log::trace; + use crate::package::Package; pub struct PackageQueue { - packages: Vec + packages: Vec, } impl PackageQueue { @@ -17,7 +20,7 @@ impl PackageQueue { for dependency in dependencies { trace!("Checking package: {}", &dependency.identifier); if self.packages.contains(&dependency) { - continue + continue; } trace!("Adding package: {}", &dependency.identifier); self.packages.push(dependency); @@ -31,7 +34,18 @@ impl PackageQueue { self.packages .iter_mut() .for_each(|pkg| { - pkg.install(build); + pkg.install(build).expect("TODO: panic message"); }); } } + +impl Display for PackageQueue { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + for pkg in &self.packages { + if let Err(e) = write!(f, "{}", pkg.identifier) { + return Err(e); + } + } + write!(f, "") + } +} \ No newline at end of file diff --git a/pkgr/src/repo/index/index_package.rs b/pkgr/src/repo/index/index_package.rs new file mode 100644 index 0000000..ca60160 --- /dev/null +++ b/pkgr/src/repo/index/index_package.rs @@ -0,0 +1,18 @@ +use std::io; +use std::path::Path; +use serde::{Deserialize, Serialize}; +use url::Url; +use pkgfile::PKGFile; +use crate::api::Query; +use crate::CONFIG; +use crate::package::Package; +use crate::repo::index::RepoIndex; + +/// This struct solely exists for indexing and has no real functionality. +#[derive(Serialize, Deserialize)] +pub struct IndexPackage { + name: String, + versions: Vec, + tags: Vec, + uri: Url +} \ No newline at end of file diff --git a/pkgr/src/repo/index/mod.rs b/pkgr/src/repo/index/mod.rs new file mode 100644 index 0000000..fc516b6 --- /dev/null +++ b/pkgr/src/repo/index/mod.rs @@ -0,0 +1,58 @@ +use std::collections::HashMap; +use std::io; +use std::path::Path; +use serde::{Deserialize, Serialize}; +use crate::api::Request; +use crate::CONFIG; +use crate::repo::index::index_package::IndexPackage; +use crate::repo::Repo; +use crate::types::fetch::{Fetch, TryFetch}; +use crate::util::create_uuid; + +pub mod index_package; + +#[derive(Serialize, Deserialize)] +pub struct RepoIndex { + origin_repo: String, + packages: HashMap +} + +impl RepoIndex { + // /// Fetch existing index or create a new one. + // pub fn from_repo(repo: Repo) -> Self { + // + // } + // + // /// Create new index. + // pub fn create_with_repo(repo: Repo) -> Self { + // } + + /// Get repo + pub fn get_repo(&self) -> io::Result { + Ok(Repo::from_name(&self.origin_repo)?) + } + + pub fn from_path(path: &str) -> Result { + match std::fs::read_to_string(path) { + Ok(s) => match toml::from_str(&s) { + Ok(c) => Ok(c), + Err(e) => Err(format!("failed to parse config: {}", e)), + }, + Err(e) => Err(format!("failed to read config: {}", e)), + } + } +} + +impl TryFetch for RepoIndex { + type Error = (); + /// Fetch + fn try_fetch(query: Repo) -> Result { + let path = CONFIG.with(|c| c.storage.index_dir.clone()) + query.uri.as_str() + ".toml"; + if Path::new(path.as_str()).exists() { + RepoIndex::from_path(path.as_str()) + .map_err(|_| ()) + } else { + Err(()) + } + } +} \ No newline at end of file diff --git a/pkgr/src/repo/mod.rs b/pkgr/src/repo/mod.rs new file mode 100644 index 0000000..d0c3e88 --- /dev/null +++ b/pkgr/src/repo/mod.rs @@ -0,0 +1,42 @@ +use std::io; +use std::io::{Error, ErrorKind}; +use std::path::Path; +use url::Url; +use crate::CONFIG; +use crate::config::repos::RepoFile; + +/// Indexed repos +pub mod index; + +pub struct Repo { + name: String, + uri: Url, +} + +impl Repo { + pub fn from_name(name: &String) -> io::Result { + let r = RepoFile::from_path(CONFIG.with(|c| c.storage.repo_file.clone()).as_str()) + .map_err(|e| Error::new(ErrorKind::Other, e))?; + let r = r + .repos + .get(name) + .ok_or(Error::new(ErrorKind::InvalidData, "Could not get repo"))?; + Ok(Repo { + name: r.name.clone(), + uri: r.uri.clone() + }) + } + + pub fn get_name(&self) -> String { + self.name.clone() + } + + pub fn get_uri(&self) -> Url { + self.uri.clone() + } + + /// Fetch indexed repo + pub fn get_index(&self) { + + } +} \ No newline at end of file diff --git a/pkgr/src/tmpfs.rs b/pkgr/src/tmpfs.rs index e83b860..7d68892 100644 --- a/pkgr/src/tmpfs.rs +++ b/pkgr/src/tmpfs.rs @@ -1,4 +1,4 @@ -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use crate::CONFIG; diff --git a/pkgr/src/util/fs.rs b/pkgr/src/util/fs.rs index 03b5cb2..815b950 100644 --- a/pkgr/src/util/fs.rs +++ b/pkgr/src/util/fs.rs @@ -1,6 +1,7 @@ -use std::path::Path; -use std::fs::DirEntry; use std::{fs, io}; +use std::fs::DirEntry; +use std::path::Path; + use log::trace; pub fn visit_dirs(dir: &Path, cb: &dyn Fn(&DirEntry)) -> std::io::Result<()> { diff --git a/pkgr/src/util/mod.rs b/pkgr/src/util/mod.rs index c239775..25c313c 100644 --- a/pkgr/src/util/mod.rs +++ b/pkgr/src/util/mod.rs @@ -1,2 +1,9 @@ pub mod prompts; -pub mod fs; \ No newline at end of file +/// Helpers for fs +pub mod fs; + +/// Create a UUID +pub fn create_uuid() -> String { + // TODO + String::from("rand") +} \ No newline at end of file diff --git a/pkgr/src/util/prompts.rs b/pkgr/src/util/prompts.rs index 6c3e11a..9dcae5d 100644 --- a/pkgr/src/util/prompts.rs +++ b/pkgr/src/util/prompts.rs @@ -1,4 +1,5 @@ use std::io::Write; + use log::trace; pub fn is_noninteractive() -> bool {