dodot_lib/commands/
list.rs1use serde::Serialize;
4
5use crate::packs::orchestration::ExecutionContext;
6use crate::Result;
7
8#[derive(Debug, Clone, Serialize)]
9pub struct ListResult {
10 pub packs: Vec<ListPack>,
11}
12
13#[derive(Debug, Clone, Serialize)]
14pub struct ListPack {
15 pub name: String,
16 pub ignored: bool,
17}
18
19pub fn list(ctx: &ExecutionContext) -> Result<ListResult> {
21 let _root_config = ctx.config_manager.root_config()?;
22
23 let entries = ctx.fs.read_dir(ctx.paths.dotfiles_root())?;
25 let mut packs = Vec::new();
26
27 for entry in entries {
28 if !entry.is_dir {
29 continue;
30 }
31 if entry.name.starts_with('.') && entry.name != ".config" {
32 continue;
33 }
34 if !is_valid_pack_name(&entry.name) {
35 continue;
36 }
37
38 let ignored = ctx.fs.exists(&entry.path.join(".dodotignore"));
39 packs.push(ListPack {
40 name: entry.name,
41 ignored,
42 });
43 }
44
45 packs.sort_by(|a, b| a.name.cmp(&b.name));
46
47 Ok(ListResult { packs })
48}
49
50fn is_valid_pack_name(name: &str) -> bool {
51 !name.is_empty()
52 && name
53 .chars()
54 .all(|c| c.is_alphanumeric() || c == '_' || c == '-' || c == '.')
55}