Skip to content

Instantly share code, notes, and snippets.

@M1ke
Last active December 10, 2015 00:15
Show Gist options
  • Save M1ke/906be521dec222668844 to your computer and use it in GitHub Desktop.
Save M1ke/906be521dec222668844 to your computer and use it in GitHub Desktop.
Bower multiple install directories. For those using `bower` but not grunt who want to take advantage of the multiple cwd values described in https://github.com/bower/bower/issues/212
#!/bin/bash
# Install bower `npm -g install bower`
# Create directory in project root:
# bower/
# Then create subdirectories for each bower setup
# bower/public/bower.json
# bower/compiled/bower.json
# The path installed into will be in the same directory as `bower` with the same name as the subdir
# ./public
# ./compiled
# The bower command (e.g. install)
cmd=$1
# If a second argument is added it will just use that version
if [ $# -eq 2 ]; then
cd bower/$2
bower $1 --config.directory="../../${PWD##*/}"
cd -
else
for D in `find ./bower/* -type d`
do
cd $D
bower $1 --config.directory="../../${PWD##*/}"
cd -
done
fi
@M1ke
Copy link
Author

M1ke commented Jul 8, 2014

There's logic as to why this might be preferable to other alternatives (e.g. the grunt-bowercopy plugin). In those alternatives a separate process is still required to ensure that your bower dependencies go where you want. The problems could be as follows:

  • Someone new downloading the repository could miss the requirement and all your bower dependencies end up in one place, then stuff breaks but it's not obvious why.
  • You require one file to track the dependencies and another to list where they go - so you're changing two files for every new dependency, and a newcomer needs to read both to get an idea of project structure.

This method could be packaged as a plugin to make it easier, but even without it a newcomer can see that they have to cd into each bower/ directory and run the command they need, and could likely hack a similar script to do that.

The method could be further improved, as we're already in shell, by removing the .bowerrc file altogether and applying a flag to choose the install directory, e.g.

--config.directory="../../$current_dir_name"

This would ensure that the bower/dir name is always the same name as wherever the dependencies are installed into in the project root.

@M1ke
Copy link
Author

M1ke commented Jul 8, 2014

Rapid iteration! The script will now install to the same name directory in the project root. So for ./bower/public/bower.json the components will be downloaded to ./public/.

For ease of newcomer use (as explained above) the .bowerrc file should be kept even when using this naming scheme, so it can be installed by regular bower users

There are probably ways of neatening up the script, such as using a sub-shell, and making the actual bower command line into a function (as it's used twice). Please feel free to tweak it and let me know the updates.

@sheerun
Copy link

sheerun commented Jul 8, 2014

The trick I find useful when cd'ing in bash script is to enclose it in parenthesis:

if [ $# -eq 2 ]; then
  (
    cd bower/$2
    bower $1  --config.directory="../../${PWD##*/}"
  )
else
    for D in `find ./bower/* -type d`
    do
      (
        cd $D
        bower $1 --config.directory="../../${PWD##*/}"
      )
    done
fi

You can be sure that current path won't be changed even if bower fails.

@sheerun
Copy link

sheerun commented Jul 8, 2014

Also it's easy to parallelize with this setup. Just add & after parenthesis.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment