diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..93c1e31 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# learn more: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners + +* @lewxdev diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..bdc6346 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,24 @@ +name: 🚀 Create new release on GitHub +on: + push: + +permissions: + contents: write + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v1 + + - run: | + bun install + bun run build + echo "filepath=dist/dotfiles" >> $GITHUB_ENV + echo "version=$(dist/dotfiles --version)" >> $GITHUB_ENV + echo "prerelease=${{ github.ref != 'refs/heads/main' }}" >> $GITHUB_ENV + + - env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh release create v$version $filepath --generate-notes --prerelease=$prerelease --target ${{ github.ref }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..845ab9f --- /dev/null +++ b/.gitignore @@ -0,0 +1,52 @@ +# based on the githhub/node.gitignore template +# see: https://github.com/github/gitignore/blob/main/Node.gitignore + +# builds +dist +out +*.tgz + +# dependencies +node_modules + +# environment +.env +.env.*.local +.env.local + +# logs +logs +*.log +*-debug.log* +*-error.log* + +# miscellaneous +.cache +.temp +.DS_Store + +# runtime +pids +*.pid +*.seed +*.pid.lock + +# eslint cache +.eslintcache + +# npm cache +.npm + +# repl history +.node_repl_history + +# typescript cache +*.tsbuildinfo + +# addons +# see: https://nodejs.org/api/addons.html +build/Release + +# reports +# see: https://nodejs.org/api/report.html +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 0000000..1a71a3c --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,3 @@ +#!/usr/bin/env zsh + +bun run commitlint --edit $1 diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..5cc4db9 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "biomejs.biome", + "github.vscode-github-actions", + "joshbolduc.commitlint", + "yoavbls.pretty-ts-errors" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e34623a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "editor.defaultFormatter": "biomejs.biome", + "editor.codeActionsOnSave": { + "quickfix.biome": "explicit", + "source.organizeImports.biome": "explicit" + } +} diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..87fc95b --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,20 @@ +# The MIT License (MIT) + +Copyright © 2018-Present, [lewxdev](https://github.com/lewxdev) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ddff7e1 --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +``` + __ __ ____ __ + ___/ /__ / /_/ _(_) /__ ___ +/ _ / _ \/ __/ _/ / / -_|_-< +\_,_/\___/\__/_//_/_/\__/___/ +``` + +# @lewxdev/dotfiles + +This repository consists of infrequently updated personal configurations, +dotfiles, and scripts for a macOS-based environment. It provides the following: + +- a CLI as a [single-file executable](https://bun.sh/docs/bundler/executables) + that walks through a configurable installation process +- a one-time installation script that adds the `dotfiles` CLI to the PATH + +Although I cannot guarantee it will work for you, feel free to build on and +learn from this setup. If you have any questions or suggestions, please open an +issue. + +## Usage + +When installing for the first time, run the following command: + +```shell +curl -fsSL https://raw.githubusercontent.com/lewxdev/dotfiles/main/install.zsh | zsh +``` + +After installation, you can run the `dotfiles` CLI to manage your dotfiles: + +```shell +dotfiles --help +``` + +## Development + +```shell +# install dependencies +bun install +``` + +```shell +# invoke the CLI +bun start +``` + +```shell +# build the executable +bun run build +``` + +```shell +# update CLI installation +# note: this may prompt you for your password +bun run update +``` diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..4cf6225 --- /dev/null +++ b/biome.json @@ -0,0 +1,23 @@ +{ + "$schema": "node_modules/@biomejs/biome/configuration_schema.json", + "organizeImports": { + "enabled": true + }, + "files": { + "ignoreUnknown": true + }, + "formatter": { + "indentStyle": "tab" + }, + "linter": { + "rules": { + "recommended": true + } + }, + "vcs": { + "enabled": true, + "clientKind": "git", + "defaultBranch": "main", + "useIgnoreFile": true + } +} diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000..e56384e Binary files /dev/null and b/bun.lockb differ diff --git a/cli.ts b/cli.ts new file mode 100644 index 0000000..4278396 --- /dev/null +++ b/cli.ts @@ -0,0 +1,27 @@ +import { $ } from "bun"; +import { program } from "commander"; + +import packageJson from "@/package.json"; + +const LOCAL_PATH = "~/projects/dotfiles"; +const REMOTE_PATH = packageJson.repository.url; + +program + .name("dotfiles") + .description(`a CLI to manage ${packageJson.description}`) + .version(packageJson.version); + +program + .command("install") + .description("run the configurable installation script") + .action(async () => { + try { + // check if local repository exists + await $`test -d ${LOCAL_PATH}`; + } catch { + // create if local repository is missing + await $`git clone ${REMOTE_PATH} ${LOCAL_PATH}`; + } + }); + +await program.parseAsync(); diff --git a/install.zsh b/install.zsh new file mode 100644 index 0000000..6a85d4e --- /dev/null +++ b/install.zsh @@ -0,0 +1,28 @@ +#!/usr/bin/env zsh + +# get the latest release from GitHub +curl -L -o /usr/local/bin/dotfiles https://github.com/lewxdev/dotfiles/releases/latest/download/dotfiles + +# make the file executable +chmod +x /usr/local/bin/dotfiles + +if ! version=$(dotfiles --version); then + echo "dotfiles CLI was not installed or is not available in the PATH" + exit 1 +fi + +# post installation message +echo <