From 8a4d32def288ee7a00993990c38e06301412ed7a Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Tue, 24 Aug 2021 17:43:04 +0300 Subject: [PATCH 1/2] feat(bud): implement a 'cfg' command for managing profiles --- bud/cfg.bash | 166 ++++++++++++++++++++++++++++++++++++++++++++++++ bud/default.nix | 6 ++ 2 files changed, 172 insertions(+) create mode 100644 bud/cfg.bash diff --git a/bud/cfg.bash b/bud/cfg.bash new file mode 100644 index 000000000..d05479569 --- /dev/null +++ b/bud/cfg.bash @@ -0,0 +1,166 @@ +#!/usr/bin/env bash + +set -e -o pipefail + +function echo () { + printf "$1\n" +} + +# Turns an attr path specified like "nixos.profiles.profile" into +# it's proper devos structured filesystem path +function parse_attrpath () { + attr_origpath="$1" + + if [[ $attr_origpath == "nixos."* ]]; then + attr_path="${attr_origpath/nixos./}" + attr_path="${attr_path//./\/}" + elif [[ $attr_origpath == "hm."* ]]; then + attr_path="${attr_origpath/hm./}" + attr_path="users/${attr_path//./\/}" + else + echo "Please make sure your profile path starts with either 'nixos.' or 'hm.'!" + exit 1 + fi + + printf "$attr_path" +} + +# Parses source URLs like "owner/repo" or "gitlab:owner/repo" +# and turns them into a proper URL +function parse_sourceurl () { + url="$1" + + if [[ $url == "github:"* ]]; then + url="${url/"github:"/}" + url="https://github.com/$url" + elif [[ $url == "gitlab:"* ]]; then + url="${url/"gitlab:"/}" + url="https://gitlab.com/$url" + elif [[ $url != "http"* ]]; then + url="https://github.com/$url" + fi + + printf "$url" +} + +# Creates a repository path in the cache from an URL +function make_repo_path () { + url="$1" + + repo_name="${url##*/}" + repo_tmp="${url/\/$repo_name/}" + repo_owner="${repo_tmp##*/}" + + printf "$GIT_CACHE/$repo_owner-$repo_name" +} + +# Clones a repository into cache if it does not exist +# otherwise update the repository +function fetch_repo () { + url="$1" + repo_path="$2" + + mkdir -p "$repo_path" + git clone --depth 1 "$url" "$repo_path" \ + || git --git-dir "$repo_path/.git" --work-tree "$repo_path" pull + + if [[ $? != 0 ]]; then + echo "Failed to fetch '$url' with git, error code: $?" + exit 2 + fi +} + +function print_source_help () { + echo "'source' can be either a git repository URL, 'github:owner/repo' or 'gitlab:owner/repo'" + echo "if 'source' is given as 'owner/repo', it will default to 'github:owner/repo'" +} + +GIT_CACHE="$HOME/.cache/bud/git" + +case "$1" in + "show") + shift 1 + + url="$1" + + if [[ -z "$url" ]]; then + echo "Show profiles available in the specified source\n" + echo "Usage: show source\n" + print_source_help + echo "if 'source' is '.', it will show your own profiles" + exit 1 + fi + + if [[ "$url" == "." ]]; then + repo_path="." + else + url=$(parse_sourceurl "$url") + repo_path=$(make_repo_path "$url") + + fetch_repo "$url" "$repo_path" || exit $? + fi + + echo "nixos profiles:" + exa -Th "$repo_path/profiles" | grep -v "default.nix" | tail -n +2 || echo "no nixos profiles found" + echo "home-manager profiles:" + exa -Th "$repo_path/users/profiles" | grep -v "default.nix" | tail -n +2 || echo "no home-manager profiles found" + ;; + "remove") + shift 1 + + attr_origpath=$1 + + if [[ -z "$attr_origpath" ]]; then + echo "Remove a profile from your config\n" + echo "Usage: remove (nixos|hm).profiles.[PROFILE]" + exit 1 + fi + + attr_path=$(parse_attrpath "$attr_origpath") || exit $? + + if [[ -e "$attr_path" ]]; then + rm -r "$attr_path" + echo "deleted cfg '$attr_origpath'" + else + echo "cfg '$attr_origpath' does not exist in your config" + exit 1 + fi + ;; + "add") + shift 1 + + url=$1 + attr_origpath=$2 + + if [[ -z "$url" || -z "$attr_origpath" ]]; then + echo "Add a profile from the specified source\n" + echo "Usage: add source (nixos|hm).profiles.[PROFILE]\n" + print_source_help + exit 1 + fi + + attr_path=$(parse_attrpath "$attr_origpath") || exit $? + url=$(parse_sourceurl "$url") + repo_path=$(make_repo_path "$url") + repo_attr_path="$repo_path/$attr_path" + + fetch_repo "$url" "$repo_path" || exit $? + + if [[ -e "$repo_attr_path" ]]; then + mkdir -p "$attr_path" + cp -r "$repo_attr_path"/* "$attr_path/" + echo "Added profile '$attr_origpath'!" + else + echo "Profile '$attr_origpath' does not exist in user repository!" + exit 3 + fi + ;; + *) + echo "Available subcommands are:" + echo " - 'add': Add a profile from the specified source" + echo " - 'show': Show profiles available in the specified source" + echo " - 'remove': Remove a profile from your config\n" + echo "run 'bud cfg command' for more info about a command" + exit 1 + ;; +esac \ No newline at end of file diff --git a/bud/default.nix b/bud/default.nix index c486636bd..19ec9f906 100644 --- a/bud/default.nix +++ b/bud/default.nix @@ -6,5 +6,11 @@ help = "Copy the desired template to DEST"; script = ./get.bash; }; + cfg = { + writer = budUtils.writeBashWithPaths [ git coreutils exa gnugrep ]; + synopsis = "cfg [SUBCOMMAND]"; + help = "Manage profiles (add, remove, etc.) for your configuration"; + script = ./cfg.bash; + }; }; } From 68d0eb5fdc530f2fd1ecf8f4794f799e203dcea9 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Thu, 26 Aug 2021 18:40:07 +0300 Subject: [PATCH 2/2] feat(bud): allow configuring hosts, users and modules in 'cfg' --- bud/cfg.bash | 52 ++++++++++++++++++++++++++++++++++++------------- bud/default.nix | 2 +- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/bud/cfg.bash b/bud/cfg.bash index d05479569..99d78b1ad 100644 --- a/bud/cfg.bash +++ b/bud/cfg.bash @@ -75,6 +75,10 @@ function print_source_help () { echo "if 'source' is given as 'owner/repo', it will default to 'github:owner/repo'" } +function show_tree_without_default () { + exa ${3} -Th "$1" | rg -v "(default\.nix|profiles|modules)" | tail -n +1 || echo "$2" +} + GIT_CACHE="$HOME/.cache/bud/git" case "$1" in @@ -82,12 +86,14 @@ case "$1" in shift 1 url="$1" + ty="$2" if [[ -z "$url" ]]; then - echo "Show profiles available in the specified source\n" - echo "Usage: show source\n" + echo "Show profiles / modules / users / hosts available in the specified source\n" + echo "Usage: show source (profiles|users|hosts|modules)\n" print_source_help - echo "if 'source' is '.', it will show your own profiles" + echo "if 'source' is '.', it will show your own profiles / users / hosts / modules\n" + echo "if none of 'profiles', 'users', 'hosts' or 'modules' are specified, it will default to 'profiles'" exit 1 fi @@ -100,10 +106,28 @@ case "$1" in fetch_repo "$url" "$repo_path" || exit $? fi - echo "nixos profiles:" - exa -Th "$repo_path/profiles" | grep -v "default.nix" | tail -n +2 || echo "no nixos profiles found" - echo "home-manager profiles:" - exa -Th "$repo_path/users/profiles" | grep -v "default.nix" | tail -n +2 || echo "no home-manager profiles found" + case "$ty" in + "users") + echo "users:" + show_tree_without_default "$repo_path/users" "no users found" "--level=1" + ;; + "hosts") + echo "hosts:" + show_tree_without_default "$repo_path/hosts" "no hosts found" "--level=1" + ;; + "modules") + echo "nixos modules:" + show_tree_without_default "$repo_path/modules" "no nixos profiles found" + echo "home-manager modules:" + show_tree_without_default "$repo_path/users/modules" "no home-manager profiles found" + ;; + *) + echo "nixos profiles:" + show_tree_without_default "$repo_path/profiles" "no nixos profiles found" + echo "home-manager profiles:" + show_tree_without_default "$repo_path/users/profiles" "no home-manager profiles found" + ;; + esac ;; "remove") shift 1 @@ -111,8 +135,8 @@ case "$1" in attr_origpath=$1 if [[ -z "$attr_origpath" ]]; then - echo "Remove a profile from your config\n" - echo "Usage: remove (nixos|hm).profiles.[PROFILE]" + echo "Remove a profile / user / host / module from your config\n" + echo "Usage: remove nixos.(profiles|users|hosts|modules).[NAME] / add source hm.(profiles|modules).[NAME]" exit 1 fi @@ -133,8 +157,8 @@ case "$1" in attr_origpath=$2 if [[ -z "$url" || -z "$attr_origpath" ]]; then - echo "Add a profile from the specified source\n" - echo "Usage: add source (nixos|hm).profiles.[PROFILE]\n" + echo "Add a profile / user / host / module from the specified source\n" + echo "Usage: add source nixos.(profiles|users|hosts|modules).[NAME] / add source hm.(profiles|modules).[NAME]\n" print_source_help exit 1 fi @@ -157,9 +181,9 @@ case "$1" in ;; *) echo "Available subcommands are:" - echo " - 'add': Add a profile from the specified source" - echo " - 'show': Show profiles available in the specified source" - echo " - 'remove': Remove a profile from your config\n" + echo " - 'add': Add a profile / user / host / module from the specified source" + echo " - 'show': Show profiles / users / hosts / modules available in the specified source" + echo " - 'remove': Remove a profile / user / host / module from your config\n" echo "run 'bud cfg command' for more info about a command" exit 1 ;; diff --git a/bud/default.nix b/bud/default.nix index 19ec9f906..5c7f56b9b 100644 --- a/bud/default.nix +++ b/bud/default.nix @@ -7,7 +7,7 @@ script = ./get.bash; }; cfg = { - writer = budUtils.writeBashWithPaths [ git coreutils exa gnugrep ]; + writer = budUtils.writeBashWithPaths [ git coreutils exa ripgrep ]; synopsis = "cfg [SUBCOMMAND]"; help = "Manage profiles (add, remove, etc.) for your configuration"; script = ./cfg.bash;