Skip to content

Commit 8a4d32d

Browse files
committed
feat(bud): implement a 'cfg' command for managing profiles
1 parent 079adc4 commit 8a4d32d

File tree

2 files changed

+172
-0
lines changed

2 files changed

+172
-0
lines changed

bud/cfg.bash

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#!/usr/bin/env bash
2+
3+
set -e -o pipefail
4+
5+
function echo () {
6+
printf "$1\n"
7+
}
8+
9+
# Turns an attr path specified like "nixos.profiles.profile" into
10+
# it's proper devos structured filesystem path
11+
function parse_attrpath () {
12+
attr_origpath="$1"
13+
14+
if [[ $attr_origpath == "nixos."* ]]; then
15+
attr_path="${attr_origpath/nixos./}"
16+
attr_path="${attr_path//./\/}"
17+
elif [[ $attr_origpath == "hm."* ]]; then
18+
attr_path="${attr_origpath/hm./}"
19+
attr_path="users/${attr_path//./\/}"
20+
else
21+
echo "Please make sure your profile path starts with either 'nixos.' or 'hm.'!"
22+
exit 1
23+
fi
24+
25+
printf "$attr_path"
26+
}
27+
28+
# Parses source URLs like "owner/repo" or "gitlab:owner/repo"
29+
# and turns them into a proper URL
30+
function parse_sourceurl () {
31+
url="$1"
32+
33+
if [[ $url == "github:"* ]]; then
34+
url="${url/"github:"/}"
35+
url="https://github.com/$url"
36+
elif [[ $url == "gitlab:"* ]]; then
37+
url="${url/"gitlab:"/}"
38+
url="https://gitlab.com/$url"
39+
elif [[ $url != "http"* ]]; then
40+
url="https://github.com/$url"
41+
fi
42+
43+
printf "$url"
44+
}
45+
46+
# Creates a repository path in the cache from an URL
47+
function make_repo_path () {
48+
url="$1"
49+
50+
repo_name="${url##*/}"
51+
repo_tmp="${url/\/$repo_name/}"
52+
repo_owner="${repo_tmp##*/}"
53+
54+
printf "$GIT_CACHE/$repo_owner-$repo_name"
55+
}
56+
57+
# Clones a repository into cache if it does not exist
58+
# otherwise update the repository
59+
function fetch_repo () {
60+
url="$1"
61+
repo_path="$2"
62+
63+
mkdir -p "$repo_path"
64+
git clone --depth 1 "$url" "$repo_path" \
65+
|| git --git-dir "$repo_path/.git" --work-tree "$repo_path" pull
66+
67+
if [[ $? != 0 ]]; then
68+
echo "Failed to fetch '$url' with git, error code: $?"
69+
exit 2
70+
fi
71+
}
72+
73+
function print_source_help () {
74+
echo "'source' can be either a git repository URL, 'github:owner/repo' or 'gitlab:owner/repo'"
75+
echo "if 'source' is given as 'owner/repo', it will default to 'github:owner/repo'"
76+
}
77+
78+
GIT_CACHE="$HOME/.cache/bud/git"
79+
80+
case "$1" in
81+
"show")
82+
shift 1
83+
84+
url="$1"
85+
86+
if [[ -z "$url" ]]; then
87+
echo "Show profiles available in the specified source\n"
88+
echo "Usage: show source\n"
89+
print_source_help
90+
echo "if 'source' is '.', it will show your own profiles"
91+
exit 1
92+
fi
93+
94+
if [[ "$url" == "." ]]; then
95+
repo_path="."
96+
else
97+
url=$(parse_sourceurl "$url")
98+
repo_path=$(make_repo_path "$url")
99+
100+
fetch_repo "$url" "$repo_path" || exit $?
101+
fi
102+
103+
echo "nixos profiles:"
104+
exa -Th "$repo_path/profiles" | grep -v "default.nix" | tail -n +2 || echo "no nixos profiles found"
105+
echo "home-manager profiles:"
106+
exa -Th "$repo_path/users/profiles" | grep -v "default.nix" | tail -n +2 || echo "no home-manager profiles found"
107+
;;
108+
"remove")
109+
shift 1
110+
111+
attr_origpath=$1
112+
113+
if [[ -z "$attr_origpath" ]]; then
114+
echo "Remove a profile from your config\n"
115+
echo "Usage: remove (nixos|hm).profiles.[PROFILE]"
116+
exit 1
117+
fi
118+
119+
attr_path=$(parse_attrpath "$attr_origpath") || exit $?
120+
121+
if [[ -e "$attr_path" ]]; then
122+
rm -r "$attr_path"
123+
echo "deleted cfg '$attr_origpath'"
124+
else
125+
echo "cfg '$attr_origpath' does not exist in your config"
126+
exit 1
127+
fi
128+
;;
129+
"add")
130+
shift 1
131+
132+
url=$1
133+
attr_origpath=$2
134+
135+
if [[ -z "$url" || -z "$attr_origpath" ]]; then
136+
echo "Add a profile from the specified source\n"
137+
echo "Usage: add source (nixos|hm).profiles.[PROFILE]\n"
138+
print_source_help
139+
exit 1
140+
fi
141+
142+
attr_path=$(parse_attrpath "$attr_origpath") || exit $?
143+
url=$(parse_sourceurl "$url")
144+
repo_path=$(make_repo_path "$url")
145+
repo_attr_path="$repo_path/$attr_path"
146+
147+
fetch_repo "$url" "$repo_path" || exit $?
148+
149+
if [[ -e "$repo_attr_path" ]]; then
150+
mkdir -p "$attr_path"
151+
cp -r "$repo_attr_path"/* "$attr_path/"
152+
echo "Added profile '$attr_origpath'!"
153+
else
154+
echo "Profile '$attr_origpath' does not exist in user repository!"
155+
exit 3
156+
fi
157+
;;
158+
*)
159+
echo "Available subcommands are:"
160+
echo " - 'add': Add a profile from the specified source"
161+
echo " - 'show': Show profiles available in the specified source"
162+
echo " - 'remove': Remove a profile from your config\n"
163+
echo "run 'bud cfg command' for more info about a command"
164+
exit 1
165+
;;
166+
esac

bud/default.nix

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,11 @@
66
help = "Copy the desired template to DEST";
77
script = ./get.bash;
88
};
9+
cfg = {
10+
writer = budUtils.writeBashWithPaths [ git coreutils exa gnugrep ];
11+
synopsis = "cfg [SUBCOMMAND]";
12+
help = "Manage profiles (add, remove, etc.) for your configuration";
13+
script = ./cfg.bash;
14+
};
915
};
1016
}

0 commit comments

Comments
 (0)