Last active
December 26, 2015 04:49
-
-
Save colingourlay/7095968 to your computer and use it in GitHub Desktop.
Grunt task for cycling through each item in a directory on an interval and creating a symlink which points to it. This is helpful for cycling through logs, or an archive of data captured over time. Coupled with a server, it serves as a good simulated data endpoint. This should be defined after grunt.initConfig inside your Gruntfile, or you can r…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ grunt link-cycler --root=archive/json --interval=30000 --link=current --verbose --initial=10 | |
Running "link-cycler" task | |
Cycling through last 3 of 12 children, 1 per 30000ms... | |
Child 10/12: | |
Linking archive/json/current to archive/json/2013-09-23_12-28-32 | |
Child 11/12: | |
Unlinking archive/json/current | |
Linking archive/json/current to archive/json/2013-09-23_12-58-32 | |
Child 12/12: | |
Unlinking archive/json/current | |
Linking archive/json/current to archive/json/2013-09-23_13-28-32 | |
Reached last child. Exiting. | |
Done, without errors. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
grunt.registerTask('link-cycler', function () { | |
var rootPath = grunt.option('root') || '.', | |
linkName = grunt.option('link') || '.link-cycler-current-link', | |
cycleInterval = +grunt.option('interval') || 1000, | |
nextIndex = +(grunt.option('initial') || 1) - 1, | |
linkPath = slashed(rootPath) + linkName, | |
rootChildNames, | |
done; | |
function slashed(str) { | |
return str + (str.charAt(str.length - 1) === '/' ? '' : '/'); | |
} | |
function next() { | |
var name = rootChildNames[nextIndex], | |
path; | |
if (!name) { | |
grunt.verbose.writeln('\nReached last child. Exiting.'); | |
return done(); | |
} | |
grunt.verbose.writeln('\nChild ' + (nextIndex + 1) + '/' + rootChildNames.length + ':'); | |
name = rootChildNames[nextIndex]; | |
path = slashed(rootPath) + name; | |
nextIndex++; | |
if (fs.existsSync(path)) { | |
if (path !== linkPath) { | |
if (fs.existsSync(linkPath)) { | |
grunt.verbose.writeln('Unlinking ' + linkPath); | |
fs.unlinkSync(linkPath); | |
} | |
grunt.verbose.writeln('Linking ' + linkPath + ' to ' + path); | |
fs.symlinkSync(name, linkPath, fs.statSync(path).isDirectory() ? 'dir' : 'file'); | |
return setTimeout(next, cycleInterval); | |
} else { | |
grunt.verbose.writeln('Skipping existing link ' + linkPath); | |
return next(); | |
} | |
} else { | |
grunt.verbose.writeln('Skipping non-existant path ' + path); | |
return next(); | |
} | |
} | |
if (!fs.existsSync(rootPath)) { | |
grunt.warn('\nRoot path does not exist. Exiting.'); | |
} | |
done = this.async(); | |
rootChildNames = fs.readdirSync(rootPath).filter(function (name) { return name !== linkName; }); | |
grunt.log.writeln('\nCycling through ' + (nextIndex ? ('last ' + (rootChildNames.length - nextIndex) + ' of ') : '') + rootChildNames.length + ' children, 1 per ' + cycleInterval + 'ms...'); | |
next(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment