瀏覽代碼

Use find -type f to get a list of output files

James Allen 12 年之前
父節點
當前提交
ffa7919e46

+ 1 - 0
services/clsi/Gruntfile.coffee

@@ -50,6 +50,7 @@ module.exports = (grunt) ->
 			unit:
 				options:
 					reporter: "spec"
+					grep: grunt.option("grep")
 				src: ["test/unit/js/**/*.js"]
 			acceptance:
 				options:

+ 25 - 32
services/clsi/app/coffee/OutputFileFinder.coffee

@@ -1,7 +1,7 @@
 async = require "async"
 fs = require "fs"
 Path = require "path"
-wrench = require "wrench"
+spawn = require("child_process").spawn
 
 module.exports = OutputFileFinder =
 	findOutputFiles: (resources, directory, callback = (error, outputFiles) ->) ->
@@ -16,44 +16,37 @@ module.exports = OutputFileFinder =
 			for file in allFiles
 				do (file) ->
 					jobs.push (callback) ->
-						if incomingResources[file.path]
+						if incomingResources[file]
 							return callback()
 						else
-							OutputFileFinder._isDirectory Path.join(directory, file.path), (error, directory) ->
-								return callback(error) if error?
-								if !directory
-									outputFiles.push file
-								callback()
+							outputFiles.push {
+								path: file
+								type: file.match(/\.([^\.]+)$/)?[1]
+							}
+							callback()
 
 			async.series jobs, (error) ->
 				return callback(error) if error?
 				callback null, outputFiles
 
-	_isDirectory: (path, callback = (error, directory) ->) ->
-		fs.stat path, (error, stat) ->
-			callback error, stat?.isDirectory()
-
-	_getAllFiles: (directory, _callback = (error, outputFiles) ->) ->
-		callback = (error, outputFiles) ->
-			_callback(error, outputFiles)
+	_getAllFiles: (directory, _callback = (error, fileList) ->) ->
+		callback = (error, fileList) ->
+			_callback(error, fileList)
 			_callback = () ->
 
-		outputFiles = []
-
-		wrench.readdirRecursive directory, (error, files) =>
-			if error?
-				if error.code == "ENOENT"
-					# Directory doesn't exist, which is not a problem
-					return callback(null, [])
-				else
-					return callback(error)
-
-			# readdirRecursive returns multiple times and finishes with a null response
-			if !files?
-				return callback(null, outputFiles)
-
-			for file in files
-				outputFiles.push
-					path: file
-					type: file.match(/\.([^\.]+)$/)?[1]
+		proc = spawn("find", [directory, "-type", "f"])
+		stdout = ""
+		proc.stdout.on "data", (chunk) ->
+			stdout += chunk.toString()	
+		proc.on "error", callback	
+		proc.on "close", (code) ->
+			if code != 0
+				error = new Error("find returned non-zero exit code: #{code}")
+				return callback(error)
+			
+			fileList = stdout.trim().split("\n")
+			fileList = fileList.map (file) ->
+				# Strip leading directory
+				path = Path.relative(directory, file)
+			return callback null, fileList
 

+ 25 - 10
services/clsi/test/unit/coffee/OutputFileFinderTests.coffee

@@ -4,29 +4,25 @@ require('chai').should()
 modulePath = require('path').join __dirname, '../../../app/js/OutputFileFinder'
 path = require "path"
 expect = require("chai").expect
+EventEmitter = require("events").EventEmitter
 
 describe "OutputFileFinder", ->
 	beforeEach ->
 		@OutputFileFinder = SandboxedModule.require modulePath, requires:
 			"fs": @fs = {}
-			"wrench": @wrench = {}
+			"child_process": spawn: @spawn = sinon.stub()
 		@directory = "/test/dir"
 		@callback = sinon.stub()
 
 	describe "findOutputFiles", ->
 		beforeEach ->
 			@resource_path = "resource/path.tex"
-			@output_paths   = ["output.pdf", "extra", "extra/file.tex"]
+			@output_paths   = ["output.pdf", "extra/file.tex"]
+			@all_paths = @output_paths.concat [@resource_path]
 			@resources = [
 				path: @resource_path = "resource/path.tex"
 			]
-			@OutputFileFinder._isDirectory = (dirPath, callback = (error, directory) ->) =>
-				callback null, dirPath == path.join(@directory, "extra")
-
-			@wrench.readdirRecursive = (dir, callback) =>
-				callback(null, [@resource_path].concat(@output_paths))
-				callback(null, null)
-			sinon.spy @wrench, "readdirRecursive"
+			@OutputFileFinder._getAllFiles = sinon.stub().callsArgWith(1, null, @all_paths)
 			@OutputFileFinder.findOutputFiles @resources, @directory, (error, @outputFiles) =>
 
 		it "should only return the output files, not directories or resource paths", ->
@@ -37,5 +33,24 @@ describe "OutputFileFinder", ->
 				path: "extra/file.tex",
 				type: "tex"
 			}]
-
+			
+	describe "_getAllFiles", ->
+		beforeEach ->
+			@proc = new EventEmitter()
+			@proc.stdout = new EventEmitter()
+			@spawn.returns @proc
+			@directory = "/base/dir"
+			@OutputFileFinder._getAllFiles @directory, @callback
+			
+			@proc.stdout.emit(
+				"data",
+				["/base/dir/main.tex", "/base/dir/chapters/chapter1.tex"].join("\n") + "\n"
+			)
+			@proc.emit "close", 0
+			
+		it "should call the callback with the relative file paths", ->
+			@callback.calledWith(
+				null,
+				["main.tex", "chapters/chapter1.tex"]
+			).should.equal true