public void Compile(CompilerOptions opt) { if (!File.Exists(opt.Path) && !Directory.Exists(opt.Path)) { throw new SourceNotFoundException(opt.Path); } if(! opt.OutputDir.IsNullOrWhiteSpace() && !opt.OutputDir.AsDirectory().Exists) { throw new TargetNotFoundException(opt.OutputDir); } IEnumerable<string> toCompile; if (!Directory.Exists(opt.Path) && File.Exists(opt.Path)) toCompile = new[] { opt.Path }; else toCompile = Glob(opt.Path, "*.coffee"); if (opt.Compile) { CompileMany(toCompile, opt); } if (opt.Watch) { StartWatching(opt); } return; }
private static void CompileMany(IEnumerable<string> toCompile, CompilerOptions opt) { foreach (var sourcePath in toCompile) { string result = Compile(sourcePath, opt); if (opt.Print) Console.WriteLine(result); else { string dest; dest = opt.OutputDir.IsNullOrWhiteSpace() ? sourcePath : sourcePath.Replace(opt.Path, opt.OutputDir); dest = Path.ChangeExtension(dest, ".js"); var destDir = new FileInfo(dest).Directory; if(!destDir.Exists) { destDir.Create(); } File.WriteAllText(dest, result, Encoding.UTF8); } } }
private static string Compile(string sourcePath, CompilerOptions opt) { //ugly hack. When triggered by the filesystemwatcher (--watch mode), the file may be transiently locked //by another process, and the call to Read would throw. Trying to monitor this in procmon I found at least //three background processes happily opening the file. We should poll and check locking beforehand, but this //will do for now. Wow, that's a big comment/code ratio. Thread.Sleep(100); var source = File.ReadAllText(sourcePath, Encoding.UTF8); string result = ""; try { result = CoffeeScriptProcessor.Process(source, opt.Bare); } catch (Exception ex) { Console.WriteLine("Error while compiling " + sourcePath + " :"); Console.WriteLine(ex.Message); } return result; }
static void Main(string[] args) { var opt = new CompilerOptions(); var p = new OptionSet() .Add("c|compile", "compile to JavaScript and save as .js files", _ => opt.Compile = true) .Add("o=|output=","set the directory for compiled JavaScript", d => opt.OutputDir = d ) .Add("w|watch","watch scripts for changes, and recompile", d => opt.Watch = true ) .Add("p|print", "print the compiled JavaScript to stdout", _ => opt.Print = true) .Add("b|bare", "compile without the top-level function wrapper", _ => opt.Bare = true) .Add("v|version", "display coffeescript version", _ => DisplayVersion()) .Add("h|help", "display this help message", _ => opt.Help = true); if (args.Length == 0) { DisplayHelp(p); } if (opt.Help) DisplayHelp(p); try { opt.Path = p.Parse(args).First(); } catch (Exception ex) { Console.WriteLine("Error parsing arguments: " + ex.Message); DisplayHelp(p); } new Compiler().Compile(opt); if(opt.Watch) { Console.WriteLine("Press enter to quit"); Console.ReadLine(); Environment.Exit(0); } }
public ChangeWatcher(string path, CompilerOptions options, Action<string,CompilerOptions> action) { //Filesystemwatcher watches..directories. So if the path is a file we watch the file dir var isDirectory = (File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory; var subDirs = isDirectory; string toWatch = path; string filter = "*.coffee"; if (!isDirectory) { var info = new FileInfo(path); toWatch = info.DirectoryName; filter = info.Name; } watcher = new FileSystemWatcher(toWatch, filter) { IncludeSubdirectories = subDirs }; this.action = action; this.options = options; watcher.NotifyFilter = NotifyFilters.LastWrite; watcher.Changed += OnChanged; }
private static void StartWatching(CompilerOptions opt) { Console.WriteLine("watching:" + opt.Path); var watcher = new ChangeWatcher(opt.Path, opt, (path, options) => { Console.WriteLine(DateTime.Now + ":" + path + " has changed."); CompileMany(new[] { path }, options); Console.WriteLine(DateTime.Now + ":" + path + " recompiled"); }); watcher.Start(); }