Skip to content

Instantly share code, notes, and snippets.

@mflorida
Last active September 10, 2017 17:52
Show Gist options
  • Save mflorida/2c3541d445211d4bfbac5a9c60815b4f to your computer and use it in GitHub Desktop.
Save mflorida/2c3541d445211d4bfbac5a9c60815b4f to your computer and use it in GitHub Desktop.
Create an object map of a directory tree then save to .json and .js files.
#!/usr/bin/env groovy
import groovy.json.*
// Drill down through the directory structure and output
// a representation to json and js files
//
// usage:
//
// ./filList.groovy ./ files._ comma,separated,list,of,files,to,skip
// ^-- script ^-- start dir ^-- output file name ^-- skip ALL files with these names
// NOTE: for the output file name, using a ._ extension means that BOTH .json and .js files are created
// set to current directory if not specified as the first argument
def startPath = args.length >= 1 ? args[0] : '.'
// extract the start path directory name
def startDir = (new File(new File(startPath).canonicalPath)).name
// rewrite startPath to current directory if necessary
if (startPath ==~ /^(\.|\.\/)$/) {
startPath = '../' + startDir
}
// pass comma-separated list of file names to skip as third argument
skipList = (args.length >= 3 ? args[2].split(/\s*,\s*/) : [])
// main method for creating the file list object
def makeFileList(File file) {
def obj = ['.': null]
def fileList = null
// creating the '.' item here will create the
// property for every directory, even if it's empty
file.listFiles().collect { it }.each {
// skip files that match the following pattern...
def skip = it.name ==~ /^(\.DS_Store|\._.*|\.git.*|\.idea.*)/
if (skip || skipList.contains(it.name)) {
return
}
if (it.directory) {
fileList = makeFileList(it)
obj[it.name] = fileList
// empty directories will have a single '.' property set to null,
// otherwise, it will be an object map of directories
//obj[it.name] = fileList.size() ? fileList : ['.':null]
} else {
// creating the '.' item here will prevent
// the creation of an empty '.' array
// if there are no *files* in the folder
//obj['.'] = obj['.'] ?: []
//obj['.'].add(it.name)
// TODO: DECIDE ON ARRAY OR MAP FOR FILES
// TODO: ARRAY IS CLEANER BUT MAP IS EASIER TO TEST
obj['.'] = obj['.'] ?: [:]
obj['.'][it.name] = it.length()
}
}
// if there are folders but no files,
// remove the '.' property
if (fileList && !obj['.']) {
obj.remove('.')
}
return obj
}
def fileListing = [
(startDir): makeFileList(new File(startPath))
]
def jsonFileList = new JsonBuilder(fileListing).toPrettyString()
// specify a file name (without extension) as the second argument
// or a 'files.json' file will be written to the same
// directory specified in the first argument or the working
// directory where the script is invoked
def outputFile = args.length >= 2 ? args[1] : 'files'
def jsonFile = outputFile ==~ /(?i).*(\.json|\.\*|\._)$/
def jsFile = outputFile ==~ /(?i).*(\.js|\.\*|\._)$/
//println 'jsonFile: ' + jsonFile
//println 'jsFile: ' + jsFile
// if neither extension is present, do only json
if (!jsonFile && !jsFile) {
jsonFile = true
}
//println 'jsonFile: ' + jsonFile
//println 'jsFile: ' + jsFile
// strip file extension if present
outputFile = outputFile.replaceAll(/(?i)(\.json|\.js|\.\*|\._)$/, '')
// write to JSON file
if (jsonFile) {
new File(startPath, outputFile + '.json').newWriter().withWriter { w ->
w << jsonFileList
}
}
// write to js file
if (jsFile) {
def jsVar = (startDir + '-' + outputFile).replaceAll(/^\W*/, '').replaceAll(/\W+|-+/, '-')
new File(startPath, outputFile + '.js').newWriter().withWriter { w ->
w << ("window['" + startDir + "'] = { '" + outputFile + "': " + jsonFileList + '};')
}
}
@mflorida
Copy link
Author

mflorida commented Sep 7, 2017

Sample usage:

./fileListMap.groovy ./ myFileList .git,.gitignore,foo,bar,bogus
  • ./fileListMap.groovy - launches the script
  • ./ - the start directory (the directory the script is processing, not where the script resides)
  • myFileList - the output file name (without extension - both .json and .js files are created)
  • .git,.gitignore,foo,bar,bogus - comma-separated list of files to skip - ALL MATCHING FILES WILL BE SKIPPED, REGARDLESS OF THEIR LOCATION IN THE HIERARCHY

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