Search code examples
bashterminalaliascompass-sasssass

Bash alias or function to find Compass, and CD into the directory


Often times, my projects have a SCSS+Compass directory deep in the file system.

For example, all my projects live under ~/Web/com.example.subdomain and sometimes the styles directory is ~/Web/com.example.subdomain/trunk/docroot/_assets/locked/styles.

Typing out the entire CD command many times a day is obviously a bit repetitive. I could just create an alias for each project (e.g. alias cd-com.marketo.subdomain-scss="...") but that'd have to be added and maintained for all 25+ projects.

So how could I write a function that effectively allows me to type:

$ cd ~/Web/com.example
$ cd-compass

From here, I imagine cd-compass would:

  1. use some form of find . command which looks for config.rb or .sass-cache/
  2. If both exist in the same directory, then you know it's a compass directory...
  3. If .sass-cache/ does not exist and config.rb does, it'll run compass stats /the/dir
    1. If it's not a compass directory, the output will start with Nothing to compile. If you're trying to start...
    2. If it is a compass directory it'll spit out stats and create the .sass-cache/ directory
  4. Once it successfully finds the directory, it'll CD into the directory.

Bonus points:

Add the ability to include a compass command, so entering cd-compass compile --force would follow the flow above (including cd'ing into the directory), then execute compass compile --force

Maybe in this case, the command would be compass-do or fcompass or lcompass (f = find; l = locate).

Super bonus points:

If multiple Compass installations are found, show a numbered list of options. Entering one of the numbers and pressing enter will continue with that option.

This would essentially allow me to simply type:

$ cd-compass

1. /home/user/Web/git/com.example/trunk/docroot/admin/styles/compass

2. /home/user/Web/git/com.example/trunk/docroot/styles/compass

3. /home/user/Web/svn/com.example.sub/trunk/docroot/_assets/locked/styles

Which one? > __


Solution

  • This doesn't quite do everything you wanted - it doesn't for instance build the .sass-cache if its missing but it should be straightforward to extend it do do so (an exercise for the reader :-). Also it won't work if you have spaces in the directory names.

    Really this is a bit big for a shell alias.

    first of all you need to get all the potential directories into a variable

    dirs=$(find . -name config.rb -o \( -type d -name .sass-cache \) | sed -e 's,/.sass-cache$,,' -e 's,/config\.rb$,,' | sort | uniq -c | grep '^ *2 ' | sed -e 's/^ *2 //')
    

    This bit calls find to find any files called config.rb or directory called .sass-cache. Then it strips off the last part of the path with sed to get directory names, sorts the result and counts the number of easy resulting path. Then extract just those directories that appear twice and strip the count off the start of the directories... And "Hey presto!" we have a list of Compass directories

    then count how many of them there are:

    count=0 ; for i in $dirs ; do : ; count=$((count+1)) ; done
    

    Alternatively you could get the count by echoing the dirs variable and piping it to "wc -w"

    then you go handle the different possible values of count

    if [ $count -eq 0 ] ; then echo no compass directory found; exit ; fi
    
    if [ $count -eq 1 ] ; then cd $dirs ; exit ; fi
    
    if [ $count -gt 1 ] ; then idx=1 ; for i in $dirs ; do echo $idx $i; idx=$((idx+1)) ; done ; fi
    
    while true
    do
        echo -n "enter directory number: "
        read choice
        if [ $choice -gt $count ]
        then
            echo "invalid choice"
        else
            idx=1
            for i in $dir
            do
                if [ $idx -eq $choice ]
                then
                    cd $i ; exit
                fi
                idx=$((idx+1))
            done
        fi
    done