With fw
you have a JSON file describing your workspace.
It takes care of cloning projects and can run commands across your entire workspace.
You can start working on any project quickly, even if it’s not in your flat structured workspace (better than CDPATH
!).
It also “sets up” your environment when you start working on a project (compile stuff, run make
, activate virtualenv
or nvm
, fire up sbt
shell, etc.)
Here’s an example configuration that should be easy to grasp:
{
"projects": {
"pybuilder": {
"name": "pybuilder",
"git": "[email protected]:pybuilder/pybuilder.git",
"after_clone": "virtualenv venv && source venv/bin/activate && ./build.py install_dependencies",
"after_workon": "source venv/bin/activate"
},
"fw": {
"name": "fw",
"git": "[email protected]:brocode/fw.git",
"after_clone": "cargo build",
"tags": ["git", "rust", "brocode"]
},
"docker": {
"name": "docker",
"git": "[email protected]:docker/docker.git",
"override_path": "/home/brocode/go/src/github.com/docker/docker"
}
},
"settings": {
"shell": ["/usr/bin/zsh", "-c"],
"workspace": "~/workspace",
"github_token": "onhrefhprqrfovgrf",
"default_tags": [
"git"
],
"tags": {
"git": {
"after_workon": "git remote update --prune",
"priority": 0 // lowest priority tags run first
},
"js": {
"after_workon": "source ~/.nvm/nvm.sh"
},
"rust": {
"after_clone": "cargo build",
"after_workon": "cargo test && rustup run nightly cargo clippy"
},
"fkbr": {
"after_workon": "echo fkbr"
},
"brocode": {
"priority": 100, // highest priority tag wins workspace resolution
"workspace": "~/workspace/brocode/"
},
}
}
}
Per default projects are cloned into ${settings.workspace}/${project.name}
but you can override that by setting an override_path
attribute as seen above.
fw
is a tool I wrote to do my bidding. It might not work for you if your workflow differs a lot from mine or might require adjustments.
Here are the assumptions:
- only git repositories
- only ssh clone (easily resolveable by putting more work in the git2 bindings usage)
ssh-agent
based authentication
- workspace persistence (I can
rm -rf
my entire workspace and have it back in a few minutes) - ZERO overhead project switching with the
workon
function (need to activatenvm
? Runsbt
? Set LCD brightness to 100%?fw
will do all that for you) - zsh completions on the project names for
workon
- generate projectile configuration for all your project (no need to
projectile-add-known-project
every time you clone some shit, it will just work)
The best way to install fw is the rust tool cargo.
cargo install fw
If you are using `OSX` rustup is recommended but you should be able to use brew too.
If you need a deb or rpm package have a look at fw releases
Another thing that will make you much more productive is to use the zsh
completions (if you’re not using the zsh
I guess
you would get a bigger productivity boost by switching to zsh
first).
Since we integrate with fzf it is recommended to use that for the best possible experience (workon
and nworkon
will be helm-style fuzzy finders).
Make sure fzf
is installed and then add this to your zsh
configuration:
if [[ -x "$(command -v fw)" ]];
then
if [[ -x "$(command -v fzf)" ]];
then
eval $(fw print-zsh-setup -f 2>/dev/null);
else
eval $(fw print-zsh-setup 2>/dev/null);
fi;
fi;
If you don’t want fzf
integration:
if [[ -x "$(command -v fw)" ]];
then
eval $(fw print-zsh-setup 2>/dev/null);
fi;
In this case workon
and nworkon
will require an argument (the project) and will provide simple prefix-based autocompletion.
You should really use the fzf
integration instead it’s much better!
Just set the environment variable FW_CONFIG_PATH
. This is also honored by fw setup
and fw org-import
so you can create more than one config file this way and switch at will.
Initial setup is done with
fw setup DIR
This will look through DIR
(flat structure!) and inspect all git repositories, then write .fw.json
in your home.
You can edit that file manually to add stuff. If you have repositories elsewhere you will need to add them manually and set the override_path
property.
The fw.json
file is portable as long as you change the workspace
attribute, so you can share the file with your colleagues (projects with override_path
set won’t be portable obviously.
You can also add shell code to the after_clone
and after_workon
fields on a per-project basis.
after_clone
will be executed after cloning the project (interpreter is sh
) and after_workon
will be executed each time you workon
into the project.
If you want to pull in all projects from a GitHub organization there’s fw org-import <NAME>
for that (note that you need a minimal config first).
From now on you can
fw sync
which will clone all missing projects that are described by .fw.json
but not present in your workspace.
There is also
fw foreach 'git remote update --prune'
which will run the command in all your projects using sh
.
Instead of cloning new projects you want to work on, I suggest
adding a new project to your .fw.json
. This can be done using the tool with
fw add [email protected]:brocode/fw.git
(you should run fw
sync afterwards!)
In case you don’t like the computed project name (the above case would be fw
) you can override this (like with git clone
semantics):
fw add [email protected]:brocode/fw.git my-fw-clone
If you’re an emacs user you should always run
fw projectile
after a sync
. This will overwrite your projectile bookmarks so that all your fw
managed projects are known.
Some examples:
- Override project clone path by setting a tag (note the priority of 100 (max) so that tag is applied last)
"my-go-tag": { "after_clone": null, "after_workon": "make test", "priority": 100, "workspace": "~/go/src/github.com/mriehl/" },
- Override workspace globally
"settings": { "workspace": "~/workspace", ... }
- Export env variables in
after_workon
or source new ones (it works because it’seval
‘ed by your shell!)"python": { "after_workon": "source .venv/bin/activate" }
Just
workon
It will open a fuzzy finder which you can use to select a project. Press <enter> on a selection and it will drop you into the project folder and execute all the hooks.
If you’re in a pinch and just want to check something real quick, then you can use
nworkon
as that will no execute any post-workon hooks and simply drop you into the project folder.
In case you’re not using fzf
integration (see above) you will need to pass an argument to workon
/ nworkon
(the project name).
It comes with simple prefix-based autocompletion.