0
+# Sake. Best served warm.
0
+ die "=> Sake requires the ruby2ruby gem. Please install it. Thanks!"
0
-$:.unshift File.dirname(__FILE__)
0
+# Show all Sake tasks (but no local Rake tasks).
0
+# Show tasks in a Rake file.
0
+# Install all tasks in a Rake file or a single Rake task
0
+# $ sake -i Rakefile db:migrate
0
+# Some Sake tasks may depend on tasks which exist only locally.
0
+# For instance, you may have a db:version sake task which depends
0
+# on the 'environment' Rake task. The 'environment' Rake task is one
0
+# defined by Rails to load its environment. This db:version task will
0
+# work when your current directory is within a Rails app because
0
+# Sake knows how to find Rake tasks. This task will not work,
0
+# however, in any other directory (unless a task named 'environment'
0
+# Sake can also serve its tasks over a network by launching a Mongrel handler.
0
+# Pass the -S switch to start Sake in server mode.
0
+# You can, of course, specify a port.
0
+# You can also daemonize your server for long term serving fun.
0
+ String = [ Major, Minor, Tweak ].join('.')
0
-require 'sake/rake_faker'
0
+ # The `application' class, this is basically the controller
0
+ # which decides what to do then executes.
0
+ Rake.application.options.silent = true
0
-Dir[File.dirname(__FILE__) + '/sake/actions/*'].each do |action|
0
+ # This method figures out what to do and does it.
0
+ # Basically a big switch. Note the seemingly random
0
+ # return statements: return if you don't want run_rake invoked.
0
+ # Some actions do want it invoked, however, so they don't return
0
+ # (like version, which prints a Sake version then trusts Rake to do
0
+ # Examine a Rake file.
0
+ if (index = @args.index('-T')) && (file = @args[index+1]).is_file?
0
+ return show_tasks(TasksFile.new(file).tasks)
0
+ # Show all Sake tasks (but no local Rake tasks).
0
+ elsif index || @args.empty?
0
+ return show_tasks(Store.tasks.sort, @args[index.to_i+1])
0
+ # Install a Rake file or a single Rake task
0
+ # $ sake -i Rakefile db:migrate
0
+ elsif index = @args.index('-i')
0
- def initialize(args = [])
0
- :target => detect_target(args),
0
- :source => detect_source(args)
0
+ # Start a Mongrel handler which will serve local Rake tasks
0
+ # to anyone who wants them.
0
+ elsif @args.include? '-S'
0
+ # Prints Sake and Rake versions.
0
+ elsif @args.include? '--version'
0
+ # Runs Rake proper, including our ~/.sake tasks.
0
+ def show_tasks(tasks = [], pattern = nil)
0
+ Rake.application.show(tasks, pattern)
0
- Action.invoke(@options)
0
+ unless (file = @args[index+1]) && file.is_file?
0
+ die "=> `#{file}' is not a Rakefile, sorry."
0
+ tasks = TasksFile.new(file).tasks
0
+ # We may want to install a specific task
0
+ if target_task = @args[index + 2]
0
+ tasks = tasks.select { |task| task.name == target_task }
0
+ if Store.has_task? task
0
+ puts "!! Task `#{task}' already exists in #{Store.path}"
0
+ puts "=> Installing task `#{task}'"
0
+ puts "sake, version #{Version::String}"
0
+ import Sake::Store.path
0
+ # This class represents a Rake task file, in the traditional sense.
0
+ # It takes on parameter: the path to a Rake file. When instantiated,
0
+ # it will read the file and parse out the rake tasks, storing them in
0
+ # a 'tasks' array. This array can be accessed directly:
0
+ # file = Sake::TasksFile.new('Rakefile')
0
+ # puts file.tasks.inspect
0
+ instance_eval File.read(file) if file.is_file?
0
+ # We fake out an approximation of the Rake DSL in order to build
0
+ # Set a namespace for the duration of the block. Namespaces can be
0
+ @namespace.delete name
0
+ # Describe the following task.
0
+ # Define a task and any dependencies it may have.
0
+ def task(name, &block)
0
+ # If we're passed a hash, we know it has one key (the name of
0
+ # the task) pointing to a single or multiple dependencies.
0
+ deps = name.values.first
0
+ name = name.keys.first
0
+ # Our namespace is really just a convenience method. Essentially,
0
+ # a namespace is just part of the task name.
0
+ name = [ @namespace, name ].flatten * ':'
0
+ # Sake's version of a rake task
0
+ task = Task.new(name, deps, @comment, &block)
0
+ # We sucked up the last 'desc' declaration if it existed, so now clear
0
+ # it -- we don't want tasks without a description given one.
0
+ # Call to_ruby on all our tasks and return a concat'd string of them.
0
+ @tasks.map { |task| task.to_ruby }.join("\n")
0
+ # Add tasks to this TasksFile. Can accept another TasksFile object or
0
+ # an array of Task objects.
0
+ Array(tasks.is_a?(TasksFile) ? tasks.tasks : tasks).each do |task|
0
+ # Single task version of add_tasks
0
+ # Does this task exist?
0
+ @tasks.map { |t| t.to_s }.include? task.to_s
0
+ # Hunt for and remove a particular task.
0
+ def remove_task(task_name)
0
+ @tasks.reject! { |task| task.name == task_name }
0
+ # This is Sake's version of a Rake task. Please handle with care.
0
+ attr_reader :name, :comment
0
+ def initialize(name, deps = nil, comment = nil, &block)
0
+ # Turn ourselves back into Rake task plaintext.
0
+ out << "desc '#{@comment}'\n" if @comment
0
+ out << "task '#{@name}'"
0
+ deps = @deps.map { |dep| "'#{dep}'" }.join(', ')
0
+ out << " => [ #{deps} ]"
0
+ # get rid of the proc { / } lines
0
+ out << @body.to_ruby.split("\n")[1...-1].join("\n")
0
+ # String-ish duck typing
0
+ def inspect; @name.inspect end
0
- # Command line parsing
0
- def detect_target(args)
0
- args.detect { |arg| arg[/-|:\/\//].nil? }
0
+ # The store is, as of writing, a single Rake file: ~/.sake
0
+ # When we add new tasks, we just re-build this file. Over
0
+ # Everything we can't catch gets sent to our tasks_file.
0
+ # Common examples are #tasks or #add_task.
0
+ def method_missing(*args, &block)
0
+ tasks_file.send(*args, &block)
0
+ FileUtils.touch(path) unless path.is_file?
0
+ @tasks_file ||= TasksFile.new(path)
0
+ File.join(File.expand_path('~'), '.sake')
0
+ File.open(path, 'w') do |file|
0
+ file.puts tasks_file.to_ruby
0
+ # Show the tasks as 'sake' tasks.
0
+ args[0].sub!('rake', 'sake') if args[0].is_a? String
0
+ # Show tasks that don't have comments'
0
+ def display_tasks_and_comments(tasks = nil, pattern = nil)
0
+ if pattern ||= options.show_task_pattern
0
+ tasks = tasks.select { |t| t.name[pattern] || t.comment.to_s[pattern] }
0
+ width = tasks.collect { |t| t.name.length }.max
0
+ comment = " # #{t.comment}" if t.comment
0
+ printf "sake %-#{width}s#{comment}\n", t.name
0
+ alias_method :show, :display_tasks_and_comments
0
+ # Run Sake even if no Rakefile exists in the current directory.
0
+ alias_method :sake_original_have_rakefile, :have_rakefile
0
+ def have_rakefile(*args)
0
+ sake_original_have_rakefile(*args) || true
0
- def detect_source(args)
0
- args.detect { |arg| arg[/(\w+:\/\/)/] }
0
+ # We want only run a Sake task -- not any other matching
0
+ def enhance(deps=nil, &block)
0
+ @prerequisites |= deps if deps
0
+ @actions = [block] if block_given?
0
-Sake.new(ARGV).invoke if $0 == __FILE__
0
+# Hacks which give us "Rakefile".is_file?
0
+Sake.new(ARGV).run if $0 == __FILE__
Comments
No one has commented yet.