Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I would like to start giving unique names to "cache-able" files - i.e. *.css and *.js - in order to prevent caching, without requiring changes to the web-server settings (as is currently done in IIS).

For instance, let's I have a JavaScript file called global.js. Going forward I would like it to have the name global.123.js when revision 123 is checked in. This would also require the following:

  • The previous version of the file - perhaps it was global.115.js - is removed when the file is deployed.
  • All references to the file are updated with the new file name

How do I go about doing this? What concerns do I need to consider?

share|improve this question
3  
There are much better ways to do this -- I'd look at pulling a version string into the query string. No need to muck with filenames. –  Wyatt Barnett Sep 25 '12 at 17:04
    
Hi @Wyatt, I'd love to investigate what you're talking about. Could you elaborate and post a link? Thanks. –  Eric Belair Sep 26 '12 at 16:02
    
I just added an answer elaborating how to do this. –  Wyatt Barnett Sep 26 '12 at 20:00
add comment

3 Answers

This is a lot of work to get around caching issues. Would it be simpler to reset the cache whenever new files are uploaded, such as touching the web.config file for a .Net web site or using iisreset for IIS?

If you must, on the committing computer:

  1. Determine the HEAD (most recent) revision of the repository by parsing the output of svn info <url>.
  2. Obtain a list of files that are cachable.
  3. For each cachable file:
    1. Determine the new name (such as using regular expressions to parse and replace the version number).
    2. Rename the file using svn move <old> <new>.
    3. Search for any references to the old file through the project and change them, by doing a simple search and replace, perhaps using PowerShell commands.
  4. Commit the changes using svn commit

On the staging or deployment server, do an svn update. This will remove the old files, add the new ones and, of course, update to the HEAD revision.

share|improve this answer
add comment
  1. If you use TSVN, you have SubWCRev
  2. SubWCRev can handle both directories and separate files inside Working Copy
  3. SubWCRev replaces own keywords in "template" files by dynamic data in output files

1-3 means, that:

  • You can use $WCREV$ keyword as placeholder for revision number (you can't use subversion keyword $Revision$ without additional post-processing of keyword)
  • You have to replace all files in repo, which have references to files with changeable names by template-files (good plain global.js will be global.$WCREV$.js)
  • When you'll want to get ready-to-use snapshot of your code from WC, you have to perform additional action: get copy of WC, which reflect current state. I.e - you A) build bat-file from template, which: 1. get revision of every non-cacheable file 2. write every non-cacheable file with new filename 3. Write new files with references using current filenames B) Run this bat/powershell/? file

It may look scary, but it's doable

PS: some pieces from one of my hooks

SubWCRev.exe e:\Projs\CustomLocations e:\Projs\Builder.tpl z:\Builder.bat

...

call z:\Builder.bat

(I use path to repo in order to get global revision, you'll have to use path to separate files)

Relevant part of Builder.tpl

svn export e:\Projs\CustomLocations\trunk z:\trunk$WCDATE=%Y%m%d$-r$WCREV$

and I have changeable directory-name as result with revision as part of name

You have to do almost the same, only with individual files

share|improve this answer
add comment

What you want to do here is to use a query string rather than changing the file name. This will bust the cache just as effectively while being much easier to manage as you don't need to change file names nor keep everything coordinated on how you are changing file names.

To get there you'll need to do a few things.

First, your app needs some way to know it's version number. Depending on platforms you might be able to pull a version number from a file (.NET / java) or it might require your build process having a version setting. On some apps we leave this manual and modify it when we've got a new version we want to bust cache with.

Second, you'll probably want to replace the calling code with a wrapper function that appends the version number query string parameter. Also handy for doing stuff like having configuration-driven CDN urls if you want to go that way. Again no point in getting into specifics without getting into platforms, but you should get the idea.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.