Code Monkey home page Code Monkey logo

dotfiles's Introduction

Dane MacMillan's dotfiles

These are all the settings you will incrementally set and ultimately forget. dotfiles attempts to work seamlessly between MacOS and most GNU/Linux environments.

Additionally, it strictly adheres to the XDG Base Directory Specification ("XDG" or "XDG spec" or "XDG specification"). This is good for anyone who wants a clean ${HOME}, especially MacOS users who do not natively benefit from the XDG spec.

Package Manager Support

These dotfiles were originally developed with Homebrew support. Starting late 2021, a feature branch to support Home Manager with Nix was developed. As of May 2023, both package managers should be able to operate in parallel, and these dotfiles will essentially continue to work. Note that if the relevant Nix environment variables are detected, they will take precedence when buildling the ${PATH}, which means that packages from Nix will be prioritized over matching packages from Homebrew.

The original intention was to move exclusively to Nix, but given some of the shortcomings related to how desktop applications are discoverable in MacOS' Spotlight search, the conclusion was to modify the dotfiles to ensure as much compatibility between the two package managers (read #25).

Setup

Install

⚠️ Note: The installation will unforgivingly replace all the files in your home directory that match the files in this repo. Back them up if you do not want to lose them.

The install command to use depends on whether the host machine's SSH key has been added to GitHub. If it is a new machine that does not have a key, or this distinction is confusing, go with "No."

SSH Key on GitHub Install Command
Yes cd ~ && curl -sL https://raw.githubusercontent.com/danemacmillan/dotfiles/master/bin/__dotfiles_install | bash -
No cd ~ && curl -sL https://raw.githubusercontent.com/danemacmillan/dotfiles/master/bin/__dotfiles_install | bash -s -- nossh

Update

Just run dotfiles from anywhere. It is in the ${PATH}.

Command Arguments

Several arguments can be used with the dotfiles utility:

  • dotfiles stow: Create all symlinks.
  • dotfiles unstow: Unlinks all symlinks.
  • dotfiles restow: Unlinks and re-links all symlinks. Effective for pruning.
  • dotfiles skippackages: Run command but skip packages installation. This is only recommended once all the packages have been installed at least once.

Check tab completion for all possible arguments.

Customize

Local customizations can be made to dotfiles without actually touching the code. It generates several local config templates at ${XDG_DATA_HOME}/doftiles. That path usually expands to ${HOME}/.local/shared/dotfiles.

${XDG_DATA_HOME}/doftiles/shell.local

This is the second-to-last file sourced by ${HOME}/.bashrc. Write in any local configuration and environment changes here.

${XDG_DATA_HOME}/doftiles/${DOTFILES_HOSTNAME}.shell.local

This is the last file sourced by ${HOME}/.bashrc. This one is even more specific than the previous one, as it includes the hostname of the machine. This is useful when sharing environments across machines, and each machine requires slight changes.

For example, my machine generates a file called macmillanator.local.shell.local. I have a virtual machine that shares the same ${HOME}, so on that machine, dotfiles also generates a vagrant.test.shell.local file. Both of these files co-exist, and do not interfere with each other's respective environments. Putting all local configuration changes in shell.local would mean both environments share the same changes, which is not always desired.

${XDG_DATA_HOME}/doftiles/gitconfig.local

This file is included at the bottom of the global git config. It is typically used to store personal credentials.

Technical Details

These are some features or configuration choices worth highlighting.

πŸ“‘ XDG Base Directory Specification

The XDG Base Directory Specification is created for operating systems that do not support it by default. This is done by creating all the $XDG_* environment variables and their corresponding directories. Strict adherence to the specification has been observed.

Tools that natively support the specification will leverage these environment variables and directories without additional work. If the variables and directories were already available, dotfiles will respect them.

Read the source to see how the XDG spec environment variables and directories are created.

Partial Support

A number of tools do not natively support the specification, so in those instances dotfiles have modified environment variables, aliases, and configurations so that they can emulate support. These tools will be referred to as having partial support.

To see all of the tools adhering to the XDG spec, both with official support and partial workarounds, look in home/.config and home/.local/share.

πŸ“ Repository Organization

dotfiles is organized into a very deliberate, tidy structure. The effort was made to ensure a distinction existed between the canonical dotfiles that comprise all the plain settings and configurations, and the control dotfiles that typically arise from the need to manage the canonical ones. I never liked having them mixed together in the {$HOME} directory.

dotfiles
β”œβ”€β”€ /bin          -> Essential executable scripts for dotfiles. Available in $PATH.
β”œβ”€β”€ /dpm          -> Dotfiles package manager ("dpm"): TODO EXPLAIN
β”œβ”€β”€ /home         -> Canonical dotfiles that mirror ${HOME}. Symlink targets.
β”‚   β”œβ”€β”€ /.config  -> ${XDG_CONFIG_HOME}
β”‚   β”œβ”€β”€ /.local   -> ${XDG_DATA_HOME}
β”‚   └── /bin      -> Miscellaneous executable scripts. Available in $PATH.
└── /source       -> Core scripts sourced by dotfiles.
    └──bootstap   -> Bootstrap file that connects everything.

dotfiles/home

These are the files that contain all of the configurations for a new environment, from all variety of tools and utilities. This is what I refer to as canonical dotfiles.

The contents of this directory are what appears in a user's ${HOME} directory. Note that there are very few files at the root. That means that the ${HOME} directory itself will also be kept clean, aside from a few culprits that have not been able to be coerced into adhering to the XDG spec. The contents of this directory and its subdirectories are symlinked into ${HOME}.

Traditionally, and by most dotfiles' standards, these files are the ones at the root of a repository, as they are also traditionally at the root of a user's ${HOME} directory. dotfiles tidies things up and places them in their own directory, in order to serve as a clean reference to what actually symlinks into ${HOME}. This is achieved because of dotfiles's strict adherence to the XDG spec. This is the only directory that will have contents symlinked. All other files are either sourced internally, or available in the ${PATH}.

⚑ Packages (dpm)

dotfiles include a package management-like script for handling dependencies from a wide array of package manager types. This is what enables it to create environments across a variety of MacOS and GNU/Linux operating systems. bin/dpm is the tool used for this. It will eventually become its own repository.

TODO: explain how this works.

Symlinks via stow

As of November 16, 2021, these dotfiles replaced manual symlink creation with the stow command. Everything under dotfiles/home will be symlinked using stow.

☁️ iCloud Drive

There is a technique in use for users of iCloud Drive, that will also symlink any files that are found at: /Users/${USER}/Library/Mobile Documents/com~apple~CloudDocs/${USER}. This is useful for any sensitive config files that usually co-exist with config files that are symlinked from these dotfiles. For example, if a /Users/${USER}/Library/Mobile Documents/com~apple~CloudDocs/${USER}/.ssh directory exists, it will be symlinked to ${HOME}/.ssh alongside the non-sensitive config files that are stored in this repository.

Author

Dane MacMillan

dotfiles's People

Contributors

danemacmillan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

dotfiles's Issues

Refactor dotfiles to do less by default

At the moment, dotfiles will install tonnes of things in addition to its files. This has become a problem on production servers that should be as barebones as possible. Often, the dotfiles dependencies will install far more than is needed.

What should it do now?

Dotfiles should only install the bare minimum required utilities that are needed in order for the dotfiles to be useful. Anything beyond that, like installing a language interpreter, compilers, etc, are superfluous. In other words, if not a single dotfile requires that one of those installs are required to function, it should not install by default.

What needs to be changed?

The dpm utility should have categories of installations. By default, without options provided to it, it will install the necessarty utilities for the dotfiles to function. If the machine requires more, pass a flag, like --development, and it will install all the additional developer tools, or --localmachine, and it will install all the extra tools like weechat.

Brew git does not install on fresh MacOS

Due to the logic in dpm, it checks if the command exists before installing it, and Apple ships with its own version. A different type of check would need to be run to ensure the Brew version does get installed.

Note that if the version of git from brew does not install, that means the __git_ps1 function is unavailable, which means that the entire PS1 string will not load due to a new condition that checks for it.

A fresh install will not work

For some reason as of now, dpm --install will not work on a fresh install. It suddenly starts working if brew is installed, but of course, that should be part of the install, and not an initial step. This used to work. Look at pre-installation and includes to see if they are calling brew before it's available.

Also, check that __git_ps1 is available before attempting to use it in .bash_prompt.

Use short hostname for bash history file name

Bash history is stored in ${XDG_DATA_HOME}/bash/${DOTFILES_HOSTNAME}.${USER}.history. The ${DOTFILES_HOSTNAME} environment variable is assigned using hostname -f. Depending on the network connected to, this domain information can change quite often, so use the short version, hostname -s, which includes only the name of the host. Consider making the change backwards-compatible.

Reconsider Brew vs Nix

Since November 2021, these dotfiles intended to migrate away to Nix for package management.

Numerous changes were made to the relevant feature branch that allowed the dotfiles to work, but they were not merged back to the master branch.

Given time constraints, it may be worthwhile to attempt to merge all the changes that went into the nix branch and attempt to maintain cross-compatibility.

This issue will attempt to consolidate that.

First step:

  • Create PR and review diff between the nix home manager approach, and master.
  • Merge in as much as possible to master. Perhaps interactively rebase all the necessary commits, while allowing the nix branch to exist a while longer.

Notes

Review install notes:

Warning: /opt/homebrew/bin is not in your PATH.
  Instructions on how to configure your shell for Homebrew
  can be found in the 'Next steps' section below.
==> Installation successful!

==> Homebrew has enabled anonymous aggregate formulae and cask analytics.
Read the analytics documentation (and how to opt-out) here:
  https://docs.brew.sh/Analytics
No analytics data has been sent yet (nor will any be during this install run).

==> Homebrew is run entirely by unpaid volunteers. Please consider donating:
  https://github.com/Homebrew/brew#donations

==> Next steps:
- Run these two commands in your terminal to add Homebrew to your PATH:
    (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/danemacmillan/.profile
    eval "$(/opt/homebrew/bin/brew shellenv)"
- Run brew help to get started
- Further documentation:
    https://docs.brew.sh
/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin

bash-completion.d is no longer compatible directory on pre-m1. see update.

fzf paths for keybindings are different

Things lost in new machine

When starting fresh on a new machine, these are things I have lost:

Important

  • MySQL (SequelPro) saved server connections and auths.
  • PhpStorm settings.
  • Firefox bookmarks (sync did not sync them).

Consider using https://github.com/lra/mackup for backing up many of these GUI tools' settings.

Somewhat important

Nice to have

  • Code repositories, though they are all up in Git. It would be nice, though, to have a backup in iCloud (could be bad given the number of small files), so a new machine can just bring it in.
  • Virtual machines (not that bad).
  • Firefox containers (all of the work of designating what domains for what containers).
  • Symlink to Mobile Documents at ~/iCloud
  • Replace native bash version with homebrew version. etc/shells and chsh.
  • Safari Extensions: XDebugToggle.app and Dark Reader for Safari.app
  • stts uptime tool, from App Store.

Everything else is backed up or automated.

#21

Note that to setup xdebug, configs in dotfiles use port 9001, so modify phpstorm to use that. Consider just going back to socket.

Also, xdebug's RC became 3+, so the configuration needs to be changed. See:

Edit Nov 9, 2021:

  • Integrate iCloud Drive technique for quicker uptime. This will ensure compatible calls to ln that are POSIX-compliant (not using -r option). This will also ensure some links like .ssh directory are made properly.
  • Consider replacing whole linking technique with stow at the very end.

Ensure that $PATH includes some paths before beginning install

Example:

  • Root user installs dotfiles, which installs tools like tmux and rclone to /usr/local/bin.
  • Regular user then installs dotfiles for first time; their environment variables will be minimal on a new machine, which includes a basic $PATH; this path on CentOS, at least, does not contain /usr/local/bin, which means this user will then compile tmux and rclone again, unnecessarily.

Ensure that the PATH looks in these places for the install script.

Update to support M-series processors

While trying to install the dotfiles on a M1 Mac, there were a few things I had to tinker with. It's a fresh Monterey install on M1 Mac, 2022-10-13:

brew

My own commit was a quick-and-dirty test to make it work on the M1 Mac but the better solution would account for the hardware properly and still work for Intel, so I did not make a PR and instead just use it as reference: silpheel@9d21f5b
To detect M-series or Intel it should be enough to check if uname -m returns arm64 or x86_64 respectively.

Rosetta

We can install Rosetta automatically, which will be handy because something at this stage surely will need it.
sudo softwareupdate --install-rosetta --agree-to-license
As above, this should only be done on arm64

stow

It seems that stow is used as part of the install process but before brew has a chance to install packages. This would work as an update, but not an an initial install.
For my needs, I had brew installed by the time it failed, so I installed the package and restarted the installation process.

Create good fzf + rg integration

I was most of the way there, but having issues following a symlink to ignored directories. For example, the M2 codebase I work on has releases/2020... and then a symlink to one of the dated releases. Ignoring releases works, but then the current symlink cannot search the path.

Examples:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.