From 8524915c7775fb6e2bc3135c2596119d99eba11d Mon Sep 17 00:00:00 2001 From: Daniel Flanagan Date: Thu, 13 Apr 2023 14:04:29 -0500 Subject: [PATCH] Various improvements --- common/bin/copy-git-forge-url | 8 ++ common/bin/dotfiles-init | 73 ++++++------------- common/bin/dotfiles-setup | 10 +-- common/bin/gitforge-url.ts | 73 +++++++++++++++++++ common/bin/inforge | 3 + common/bin/open-in-git-forge | 8 ++ common/git/config | 11 ++- common/helix/config.toml | 3 +- os/linux/arch/dotfiles-init.d.sh | 3 +- .../arch/provision.d/00-AS_ROOT-add-user.bash | 16 +++- .../provision.d/70-optional-packages.bash | 13 ++++ os/linux/arch/provision.sh | 21 ++++-- 12 files changed, 166 insertions(+), 76 deletions(-) create mode 100755 common/bin/copy-git-forge-url create mode 100755 common/bin/gitforge-url.ts create mode 100644 common/bin/inforge create mode 100755 common/bin/open-in-git-forge mode change 100644 => 100755 os/linux/arch/dotfiles-init.d.sh create mode 100755 os/linux/arch/provision.d/70-optional-packages.bash diff --git a/common/bin/copy-git-forge-url b/common/bin/copy-git-forge-url new file mode 100755 index 0000000..a7a5ae7 --- /dev/null +++ b/common/bin/copy-git-forge-url @@ -0,0 +1,8 @@ +#!/usr/bin/env sh + +url="$(gitforge-url.ts "$1")" +case "$(uname)" in + Linux*) echo "$url" | clip;; + Darwin*) echo "$url" | pbcopy;; + *) echo "OS not supported"; exit 1; +esac \ No newline at end of file diff --git a/common/bin/dotfiles-init b/common/bin/dotfiles-init index e9b8718..fc2bae3 100755 --- a/common/bin/dotfiles-init +++ b/common/bin/dotfiles-init @@ -1,64 +1,37 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash export dfp export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" export ENV_PATH="$XDG_CONFIG_HOME/lytedev-env" export CURDIR +mkdir -p "$ENV_PATH" +mkdir -p "$XDG_CONFIG_HOME" dfp="$(realpath "$(dirname "$0")"/../..)" -detect_os() { - # NixOS - if head /etc/os-release --lines 1 | grep 'NixOS$' > /dev/null 2>&1; then - ln -s "$dfp/os/linux/nix" "$ENV_PATH/os-linux-nix" > /dev/null 2>&1 - return - fi - - # Arch Linux - if head /etc/os-release --lines 1 | grep 'Arch Linux' > /dev/null 2>&1; then - ln -s "$dfp/os/linux/arch" "$ENV_PATH/os-linux-arch" > /dev/null 2>&1 - return - fi - - # Pacman-based - if command -v pacman; then - ln -s "$dfp/os/linux/arch" "$ENV_PATH/os-linux-arch" > /dev/null 2>&1 - return - fi - - # TODO: Debian - - echo "Failed to auto-detect your OS! Please setup your environments and run this script again." - exit 3 -} - -if command -v git > /dev/null 2>&1; then - if [ -f "$dfp/common/envs" ]; then - # TODO: more shared init stuff? - mkdir -p "$ENV_PATH" - detect_os - ls -la -R "$ENV_PATH/*" - find "$ENV_PATH" | while read -r s; do - f="$s/dotfiles-init.d.sh" - if [ -f "$f" ]; then - CURDIR="$s" - . "$f" - fi - done - $dfp/common/bin/dotfiles-setup - else - git clone "https://git.lyte.dev/lytedev/dotfiles.git" "$XDG_CONFIG_HOME/lytedev-dotfiles" - cd "$XDG_CONFIG_HOME/lytedev-dotfiles" || { - echo "Could not cd to dotfiles dir" - exit 2 - } - . ./common/bin/dotfiles-init - fi -else - echo "git not installed" +# may not be running from inside the dotfiles repo, may have been curl'd down solo, so we need to check +if [[ ! -d "$dfp/.git" ]]; then + echo "Not running from inside the dotfiles git repo, so we need to download it first!" exit 1 fi +if head /etc/os-release --lines 1 | grep 'NixOS$' > /dev/null 2>&1; then + ln -s "$dfp/os/linux/nix" "$ENV_PATH/os-linux-nix" > /dev/null 2>&1 +elif head /etc/os-release --lines 1 | grep 'Arch Linux' > /dev/null 2>&1; then + ln -s "$dfp/os/linux/arch" "$ENV_PATH/os-linux-arch" > /dev/null 2>&1 +fi + +for s in "$ENV_PATH"/*; do + f="$s/dotfiles-init.d.sh" + if [ -f "$f" ]; then + echo "dotfiles-init: Running $f..." + CURDIR="$s" "$f" + fi +done + +echo "dotfiles-init: Running setup..." +"$dfp/common/bin/dotfiles-setup" + # TODO: run provision script # run_via_dotfiles_if_necessary() { diff --git a/common/bin/dotfiles-setup b/common/bin/dotfiles-setup index 2f6c538..437dc90 100755 --- a/common/bin/dotfiles-setup +++ b/common/bin/dotfiles-setup @@ -71,11 +71,5 @@ end rm -f $ENV_PATH/empty ln -s $DOTFILES_PATH/common/empty-env $ENV_PATH/empty -# execute the user's shell -if test (uname) = Darwin - set ush (dscl . -read /Users/$USER UserShell | awk '{print $2}') -else - set ush (getent passwd (whoami) | cut -d: -f7) -end -echo "Dotfiles Installed! Don't forget to setup environments!" -exec $ush +echo "Dotfiles Installed! Don't forget to setup environments and change the user's shell as needed!" +exec fish diff --git a/common/bin/gitforge-url.ts b/common/bin/gitforge-url.ts new file mode 100755 index 0000000..fab29dc --- /dev/null +++ b/common/bin/gitforge-url.ts @@ -0,0 +1,73 @@ +#!/usr/bin/env -S deno run --allow-read --allow-run --allow-net + +import * as path from "https://deno.land/std@0.181.0/path/mod.ts"; + +// output the best guess URL for viewing the file at the current git revision in +// the git forge's web interface + +// TODO: --help, -h menu + +const file = Deno.args[0]; + +if (!file) { + console.error("No file argument provided"); + Deno.exit(1); +} + +async function cmdOutput(cmd: string[]) { + return new TextDecoder().decode( + await Deno.run({ + cmd: cmd, + stdout: "piped", + }) + .output(), + ).trim(); +} + +type ForgeType = "gitlab" | "github" | "gitea"; + +function getForgeType(hostname: string): ForgeType { + if (hostname == "git.lyte.dev") { + return "gitea"; + } else if (hostname.endsWith("github.com")) { + return "github"; + } else { + return "gitlab"; + } +} + +function getUrl(repoRoot: string, remote: string, commit: string) { + try { + // try http remote + console.log(new URL(remote)); + throw new Error("HTTP(S) remotes not implemented"); + } catch { + const hostname = remote.split("@").slice(-1)[0].split(":")[0]; + const forgeType = getForgeType(hostname); + let repoPath = remote.split(":")[1]; + if (repoPath.endsWith(".git")) { + repoPath = repoPath.slice(0, -4); + } + let fileRepoPath = path.resolve(file); + if (fileRepoPath.startsWith(repoRoot)) { + fileRepoPath = fileRepoPath.slice(repoRoot.length + 1); // for the trailing slash + } else { + throw new Error(`File ${fileRepoPath} is not in repo at ${repoRoot}`); + } + switch (forgeType) { + case "gitlab": + return `https://${hostname}/${repoPath}/-/blob/${commit}/${fileRepoPath}`; + case "gitea": + return `https://${hostname}/${repoPath}/src/commit/${commit}/${fileRepoPath}`; + case "github": + return `https://${hostname}/${repoPath}/blob/${commit}/${fileRepoPath}`; + } + } +} + +// TODO: cd to dir +const repoRoot = await cmdOutput(["git", "rev-parse", "--show-toplevel"]); +const remote = await cmdOutput(["git", "remote", "get-url", "origin"]); +const commit = await cmdOutput(["git", "rev-parse", "HEAD"]); +const url = getUrl(repoRoot, remote, commit); +console.log(url); diff --git a/common/bin/inforge b/common/bin/inforge new file mode 100644 index 0000000..dcf9579 --- /dev/null +++ b/common/bin/inforge @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +# open the target file in its git-forge in the browser diff --git a/common/bin/open-in-git-forge b/common/bin/open-in-git-forge new file mode 100755 index 0000000..1651240 --- /dev/null +++ b/common/bin/open-in-git-forge @@ -0,0 +1,8 @@ +#!/usr/bin/env sh + +url="$(gitforge-url.ts "$1")" +case "$(uname)" in + Linux*) xdg-open "$url";; + Darwin*) open "$url";; + *) echo "OS not supported"; exit 1; +esac \ No newline at end of file diff --git a/common/git/config b/common/git/config index 58f362e..a90292f 100644 --- a/common/git/config +++ b/common/git/config @@ -79,8 +79,11 @@ # pushOption = merge_request.remove_source_branch # pushOption = merge_request.assign="daniel.flanagan" -[url "git@git-p1ap1.divvy.co:"] - insteadOf = https://git-p1ap1.divvy.co +[url "git@git.hq.bill.com:"] + insteadOf = https://git-p1ap1.divvy.co/ -[url "git@git.hq.bill.com"] - insteadOf = git@git-p1ap1.divvy.co +[url "git@git.hq.bill.com:"] + insteadOf = https://git.hq.bill.com/ + +[url "git@git.hq.bill.com:"] + insteadOf = ssh://git@git-p1ap1.divvy.co/ diff --git a/common/helix/config.toml b/common/helix/config.toml index 14196ab..8029b7f 100644 --- a/common/helix/config.toml +++ b/common/helix/config.toml @@ -34,8 +34,9 @@ D = "kill_to_line_end" "C-h" = "jump_view_left" "C-l" = "jump_view_right" "L" = "repeat_last_motion" -space = { q = ":reflow 80", Q = ":reflow 120" } +space = { q = ":reflow 80", Q = ":reflow 120", v = ":run-shell-command fish -c 'env > /tmp/env'" } [keys.select] space = { q = ":reflow 80", Q = ":reflow 120" } "L" = "repeat_last_motion" + diff --git a/os/linux/arch/dotfiles-init.d.sh b/os/linux/arch/dotfiles-init.d.sh old mode 100644 new mode 100755 index b823ce2..7fb4c6b --- a/os/linux/arch/dotfiles-init.d.sh +++ b/os/linux/arch/dotfiles-init.d.sh @@ -1,4 +1,3 @@ -#!/usr/bin/env sh +#!/usr/bin/env -S sh -i -# this will be run as root "$CURDIR/provision.sh" diff --git a/os/linux/arch/provision.d/00-AS_ROOT-add-user.bash b/os/linux/arch/provision.d/00-AS_ROOT-add-user.bash index bb2524e..7861ded 100755 --- a/os/linux/arch/provision.d/00-AS_ROOT-add-user.bash +++ b/os/linux/arch/provision.d/00-AS_ROOT-add-user.bash @@ -1,12 +1,20 @@ -#!/usr/bin/env bash +#!/usr/bin/env -S bash -i u=daniel ud="/home/$u" -# user exists - we will assume setup has already run -if getent passwd "$u"; then exit 0; fi +if [[ "$EUID" -ne 0 ]]; then + echo "Error: This script must be run as root." + exit 1 +fi -pacman -S --needed --noconfirm sudo +# user exists - we will assume setup has already run +if grep -E "^$u" /etc/passwd; then + echo "User '$u' already exists. Assuming user has been setup already." + exit 0 +fi + +pacman -Sy --needed --noconfirm sudo echo '%admin ALL=(ALL) ALL' >> /etc/sudoers.d/admin-group-sudoers groupadd admin 2>/dev/null mkdir --parents "$ud/.home" "$ud/dl" diff --git a/os/linux/arch/provision.d/70-optional-packages.bash b/os/linux/arch/provision.d/70-optional-packages.bash new file mode 100755 index 0000000..8610cfd --- /dev/null +++ b/os/linux/arch/provision.d/70-optional-packages.bash @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +dir="$(dirname "$(realpath "$0")")" +echo "Inside $dir" + +yn() { + echo "$1 [y/N]" + read -r y + # bash convert to lowercase magic + [[ ${y,,} =~ ^y ]] +} + +yn "Do you want to install UI packages?" && "$dir/optional/ui-packages.bash" diff --git a/os/linux/arch/provision.sh b/os/linux/arch/provision.sh index 488a083..58d6d45 100755 --- a/os/linux/arch/provision.sh +++ b/os/linux/arch/provision.sh @@ -1,23 +1,30 @@ -#!/usr/bin/env sh +#!/usr/bin/env -S sh -i -pacman -Syy -pacman -S --noconfirm --needed fish sudo +pacman -Sy --noconfirm --needed git fish sudo + +echo "## Arch Linux Provisioning ##" is_root="$(test "$(whoami)" == 'root' && echo "1" || echo "0")" -ls -la "$(dirname "$0")" for file in "$(dirname "$0")/provision.d"/*; do test -d "$file" && continue - echo "Runnning $file..." - if grep -q "AS_ROOT" "$file"; then + if echo "$file" | grep -q "AS_ROOT"; then if [ "$is_root" = "1" ]; then + echo "arch/provision.sh: Runnning $file..." "$file" else + echo "arch/provision.sh: Runnning sudo $file..." sudo "$file" fi else if [ "$is_root" = "1" ]; then - sudo -u daniel "$file" + nf="$(mktemp)" + cp "$file" "$nf" + chmod 777 "$nf" + echo "arch/provision.sh: Runnning sudo -u daniel $file via $nf..." + sudo -u daniel "$nf" + rm "$nf" else + echo "arch/provision.sh: Runnning $file..." "$file" fi fi