aboutsummaryrefslogtreecommitdiff
path: root/mingling_cli/src/pkg_mgr/cmd_internal_loadpkgs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'mingling_cli/src/pkg_mgr/cmd_internal_loadpkgs.rs')
-rw-r--r--mingling_cli/src/pkg_mgr/cmd_internal_loadpkgs.rs104
1 files changed, 104 insertions, 0 deletions
diff --git a/mingling_cli/src/pkg_mgr/cmd_internal_loadpkgs.rs b/mingling_cli/src/pkg_mgr/cmd_internal_loadpkgs.rs
new file mode 100644
index 0000000..b4928ce
--- /dev/null
+++ b/mingling_cli/src/pkg_mgr/cmd_internal_loadpkgs.rs
@@ -0,0 +1,104 @@
+use std::{
+ fs, io,
+ path::{Path, PathBuf},
+};
+
+use mingling::{
+ Routable,
+ macros::{buffer, command, pack, r_println, renderer, routeify},
+};
+
+use crate::{
+ Next,
+ pkg_mgr::{ErrorNoDataDirectory, ResPackagesDir},
+};
+
+// Version directory paths of every enabled package.
+pack!(ResultLoadPkgsPaths = Vec<PathBuf>);
+
+// Completion script paths of every enabled package.
+pack!(ResultLoadPkgsComps = Vec<PathBuf>);
+
+#[command(node = "__loadpkgs_path", routeify)]
+pub fn load_packages_paths(packages_dir: &ResPackagesDir) -> Next {
+ let packages_dir = &packages_dir.path;
+ if packages_dir.as_os_str().is_empty() {
+ return ErrorNoDataDirectory::default().to_chain();
+ }
+ let paths = enabled_version_dirs(packages_dir).map_err(|e| {
+ io::Error::new(
+ e.kind(),
+ format!("failed to read {}: {e}", packages_dir.display()),
+ )
+ })?;
+ ResultLoadPkgsPaths::new(paths).to_chain()
+}
+
+#[command(node = "__loadpkgs_comp_scripts", routeify)]
+pub fn load_packages_comp_scripts(packages_dir: &ResPackagesDir) -> Next {
+ let packages_dir = &packages_dir.path;
+ if packages_dir.as_os_str().is_empty() {
+ return ErrorNoDataDirectory::default().to_chain();
+ }
+ let scripts = comp_scripts(packages_dir).map_err(|e| {
+ io::Error::new(
+ e.kind(),
+ format!("failed to read {}: {e}", packages_dir.display()),
+ )
+ })?;
+ ResultLoadPkgsComps::new(scripts).to_chain()
+}
+
+#[renderer(buffer)]
+pub fn render_result_load_pkgs_paths(r: ResultLoadPkgsPaths) {
+ for path in r.inner {
+ r_println!("{}", path.display());
+ }
+}
+
+#[renderer(buffer)]
+pub fn render_result_load_pkgs_comps(r: ResultLoadPkgsComps) {
+ for path in r.inner {
+ r_println!("{}", path.display());
+ }
+}
+
+/// Version directories of every enabled package.
+///
+/// An enable file is a `name` file (no `@`) whose content is the enabled version.
+fn enabled_version_dirs(packages_dir: &Path) -> Result<Vec<PathBuf>, io::Error> {
+ let mut dirs = Vec::new();
+ for entry in fs::read_dir(packages_dir)? {
+ let entry = entry?;
+ if !entry.file_type().is_ok_and(|t| t.is_file()) {
+ continue;
+ }
+ let name = entry.file_name().to_string_lossy().into_owned();
+ if name.contains('@') {
+ continue;
+ }
+ let version = fs::read_to_string(entry.path())?;
+ dirs.push(packages_dir.join(format!("{name}@{}", version.trim())));
+ }
+ dirs.sort();
+ Ok(dirs)
+}
+
+/// Completion scripts inside every enabled version directory.
+fn comp_scripts(packages_dir: &Path) -> Result<Vec<PathBuf>, io::Error> {
+ let mut scripts = Vec::new();
+ for dir in enabled_version_dirs(packages_dir)? {
+ if !dir.is_dir() {
+ continue;
+ }
+ for entry in fs::read_dir(&dir)? {
+ let entry = entry?;
+ let name = entry.file_name().to_string_lossy().into_owned();
+ if name.contains("_comp") {
+ scripts.push(entry.path());
+ }
+ }
+ }
+ scripts.sort();
+ Ok(scripts)
+}