From fe5bc756dc50c794505b3fd3b0f0142d70abe614 Mon Sep 17 00:00:00 2001 From: Mario-Kart-Felix <76971465+Mario-Kart-Felix@users.noreply.github.com> Date: Mon, 22 Mar 2021 05:30:14 -0600 Subject: [PATCH] Create cake --- cake | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 cake diff --git a/cake b/cake new file mode 100644 index 0000000..4b746dc --- /dev/null +++ b/cake @@ -0,0 +1,98 @@ +CAKE.COFFEE +¶ +cake is a simplified version of Make (Rake, Jake) for CoffeeScript. You define tasks with names and descriptions in a Cakefile, and can call them from the command line, or invoke them from other tasks. + +Running cake with no arguments will print out a list of all the tasks in the current directory's Cakefile. + +External dependencies. + + +fs = require 'fs' +path = require 'path' +helpers = require './helpers' +optparse = require './optparse' +CoffeeScript = require './coffee-script' + +existsSync = fs.existsSync or path.existsSync +¶ +Keep track of the list of defined tasks, the accepted options, and so on. + + +tasks = {} +options = {} +switches = [] +oparse = null +¶ +Mixin the top-level Cake functions for Cakefiles to use directly. + + +helpers.extend global, +¶ +Define a Cake task with a short name, an optional sentence description, and the function to run as the action itself. + + + task: (name, description, action) -> + [action, description] = [description, action] unless action + tasks[name] = {name, description, action} +¶ +Define an option that the Cakefile accepts. The parsed options hash, containing all of the command-line options passed, will be made available as the first argument to the action. + + + option: (letter, flag, description) -> + switches.push [letter, flag, description] +¶ +Invoke another task in the current Cakefile. + + + invoke: (name, cb) -> + missingTask name unless tasks[name] + tasks[name].action options +¶ +Run cake. Executes all of the tasks you pass, in order. Note that Node's asynchrony may cause tasks to execute in a different order than you'd expect. If no tasks are passed, print the help screen. Keep a reference to the original directory name, when running Cake tasks from subdirectories. + + +exports.run = (cb) -> + global.__originalDirname = fs.realpathSync '.' + process.chdir cakefileDirectory __originalDirname + args = process.argv[2..] + CoffeeScript.run fs.readFileSync('Cakefile').toString(), filename: 'Cakefile' + oparse = new optparse.OptionParser switches + return printTasks() unless args.length + try + options = oparse.parse(args) + catch e + return fatalError "#{e}" + invoke arg for arg in options.arguments +¶ +Display the list of Cake tasks in a format similar to rake -T + + +printTasks = -> + relative = path.relative or path.resolve + cakefilePath = path.join relative(__originalDirname, process.cwd()), 'Cakefile' + console.log "#{cakefilePath} defines the following tasks:\n" + for name, task of tasks + spaces = 20 - name.length + spaces = if spaces > 0 then Array(spaces + 1).join(' ') else '' + desc = if task.description then "# #{task.description}" else '' + console.log "cake #{name}#{spaces} #{desc}" + console.log oparse.help() if switches.length +¶ +Print an error and exit when attempting to use an invalid task/option. + + +fatalError = (message) -> + console.error message + '\n' + console.log 'To see a list of all tasks/options, run "cake"' + process.exit 1 + +missingTask = (task) -> fatalError "No such task: #{task}" +¶ +When cake is invoked, search in the current and all parent directories to find the relevant Cakefile. + + +cakefileDirectory = (dir) -> + return dir if existsSync path.join dir, 'Cakefile' + parent = path.normalize path.join dir, '..' + return cakefileDirectory parent unless parent is dir + throw new Error "Cakefile not found in #{process.cwd()}"