Thursday, 22 March 2012

Rsync only specific files and directories

We recently decided that when deploying projects, it was safer to define includes rather than excludes i.e. define only the files/dirs that we want to copy and exclude everything else. Probably more work, but much safer because it means any new files (inc hidden files) will NOT be included by default - you have to manually add an include statement for them.

This turned out to be harder than I expected, but the best solution I found was the following 3 step process:

Step 1

Include the entire directory structure (but no files yet):
--include=*/

Step 2

Include the specific files / contents of specific dirs you need:
--include=/index.php
--include=/css/build/*
etc.

Step 3

Exclude everything else
--exclude=*


Explanation

The reason we start by including the entire directory structure is to greatly simplify our include statements in part (2). Without it, we would need to have separate include statements for every parent directory of every file we wanted to include e.g.
--include=/css
--include=/css/build
--include=/css/build/*
Instead of just:
--include=/css/build/*
This is because the final exclude-all-else statement is very powerful, and if you just saying you want to include the files inside /css/build/ isn't enough - because the exclude-all will encounter /css, won't find a matching include statement and so will exclude it!

You may however, not want to include hidden directories e.g. .git/ or .svn/. To do this, we insert this statement right at the beginning:
--exclude=.*/

Final template

rsync -av
--exclude=.*/
--include=*/ 
<!-- START CUSTOM INCLUDES -->
--include=/index.php
--include=/.htaccess
--include=/favicon.ico
--include=/img/*
--include=/css/build/*
--include=/js/build/*
<!-- END CUSTOM INCLUDES -->
--exclude=*
src/
dest/


Addition

There may be situations where you need to just recirsively include all files and subdirs within a directory. To do that, you can use this:
--include=css/**

Tuesday, 13 March 2012

Ubuntu 11.10 - Cannot add new item when editing main menu

I still use the old school "Main Menu" editor AKA Alacarte to create new application launchers. Unfortunately, there is a bug that means that alacarte doesn't know about all of it's dependencies. This means that if you just install alacarte, and run "Main Menu", most of the buttons (including New Item) don't work. The solution is to manually install gnome-panel as well e.g.
sudo apt-get install alacarte gnome-panel