DevContext (dx)
This repo contains dx (dev_context), a script for managing developer context across repository directories and branches.
Note: this Ruby implementation now lives in
implementations/rubywithin the multi-languagedev_contextmonorepo.
A context is one (repo_dir, branch) pair. Context names can be explicit, or implicit as <repo_basename>:<branch> (stored lowercase), and resolved with exact then FSF-style fuzzy matching.
Installation
gem install -n ~/bin dev_context
Install the gem in the current ruby gem path, with executables installed as:
~/bin/dev_context(launcher, honorsDX_IMPL)~/bin/dev_context-ruby(Ruby implementation entrypoint)
To clone from the github repo:
cd ~/src/github # or wherever you keep github repos
git clone https://github.com/aks/dev_context.git
cd dev_context/implementations/ruby
bundle install
bundle exec rake install
Usage
Current model (authoritative)
- A context is exactly one repo+branch pair (not a multi-repo aggregate).
dx cdanddx activateboth activate the target context and change CWD via shell integration.- Activation attempts branch checkout + pull; on pull failure, CWD remains in the target repo for investigation and the command exits non-zero.
- Defaults:
DX_AUTO_CREATE_LOCAL_BRANCH=trueDX_GIT_REMOTE_NAME=USE-REPO(or explicit likeorigin)
Shell integration
To support cd, dx should be wrapped by a shell function that evaluates shell output for stateful commands.
dx() {
case "$1" in
cd|activate|pushd|popd|pu|po)
local out
out="$(DX_SHELL_WRAPPED=1 command dev_context "$@")" || return $?
case "$out" in
"# DX_SHELL_EVAL"*) eval "$out" ;;
*) printf "%s\n" "$out" ;;
esac
;;
*)
command dev_context "$@"
;;
esac
}
In the descriptions below, the following terms are used consistently:
NAME: the context NAME (which can match a PATH)PATH: the file system path to a single repository directory.URL: a standard http/https/git scheme URL that leads to a git-based repository.CONTEXT: a context name, aPATH, orURLthat identifies one context. Implicit naming uses<repo_basename>:<branch>.
Common Options
These options are currently supported on dx add, dx clone, and dx create:
-c, --context NAME: explicit context name-n, --norun: preview actions without changing state-v, --verbose: print extra command details
Examples:
dx add -c api:main ~/src/github/api
dx clone -n https://github.com/acme/tooling.git
dx create -v feature:abc-123 ~/src/github/dev_context feature/abc-123
Context stack commands
dx pushd [CONTEXT|PATH|URL|+N|-N]: activate/push context, or rotate indexed stack entry to topdx popd [CONTEXT|+N|-N]: pop selected entry; with no args, same asdx popd +0
DX_PATH repo lookup
DX_PATH can be used as a list of parent directories that contain repositories.
- Format: path-separated directories (same separator as shell
PATH) - Example:
export DX_PATH="$HOME/src/github:$HOME/src/work"
dx add dev_context
Lookup behavior for relative repo targets:
- check current directory-relative path
- check each
DX_PATHroot andDX_CLONE_BASE_DIRas<root>/<target> - if needed, run FSF subsequence search across repo directory names in those roots
- if one match is found, use it
- if multiple matches are found, fail and list candidates
Initialization and Adding Directories
dx [init | help]
dx init
dx help
The first thing to do is to initialize dx with one or more repo directories.
They do not need to be added but, they can be discovered automatically with dx
add PATH.
When initialized, a ~/.dxcf file will exist with the current dx settings.
When dx is invoked without any arguments (or options), and ~/.dxcf does
not exist, then dx init is performed. dx init returns exit code 0
(success) when it actually succeeds in performing the initialization; it returns
1 (fail) otherwise.
When dx is invoked without any arguments or options, and ~/.dxcf
already exists, dx defaults to dx status.
| dx command | ~/.dxcf? | action |
|---|---|---|
dx |
no | dx init |
dx |
yes | dx status |
Note: some command examples below were written before the current context model was finalized. The authoritative behavior is defined in the "Current model (authoritative)" section above and in
DESIGN.md.
Command reference (v1)
dx init
dx add PATH|URL ...
dx clone URL [PATH]
dx create NAME [PATH] [BRANCH]
dx remove CONTEXT|PATH
dx active
dx activate CONTEXT|PATH|URL
dx cd CONTEXT|PATH|URL
dx deactivate CONTEXT
dx pushd [CONTEXT|PATH|URL|+N|-N]
dx popd [CONTEXT|+N|-N]
dx status|wip [--all] [--dirty] [-b BRANCHPATTERN] [-p PATHPATTERN]
dx repos [-b BRANCHPATTERN] [-p PATHPATTERN] [PATTERN]
dx stashes [--list] [PATTERN]
dx find [--stashes|--branches|--paths] <pattern>
dx find --all
dx branches|br [CONTEXT|PATTERN]
dx checkout|co [-b] FEATURE [CONTEXT]
dx diff [CONTEXT]
Notes:
dx addaccepts one or morePATH/URLtargets; there is no trailing aggregate context argument.dx add URLbehaves like clone+register for that repo.dx stashes [PATTERN],dx repos [PATTERN], anddx branches [PATTERN]are focused find-style shortcuts.dx <pattern>is shorthand fordx find <pattern>when the first token is not a command.dx wipisdx status --dirtyby default.dx status/dx wipshow stash count ass:<count>when non-zero.
Development
After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/aks/dev_context. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
MIT License — see LICENSE.txt.
Code of Conduct
Please adhere to our code of conduct.