Rake main application object. When invoking rake from the command line, a Rake::Application object is created and run.
- add_import
- add_loader
- collect_tasks
- const_warning
- display_prerequisites
- display_tasks_and_comments
- dynamic_width
- dynamic_width_stty
- dynamic_width_tput
- find_rakefile_location
- handle_options
- have_rakefile
- init
- invoke_task
- load_imports
- load_rakefile
- new
- options
- parse_task_string
- rake_require
- rakefile_location
- run
- standard_exception_handling
- standard_rake_options
- system_dir
- terminal_width
- top_level
- truncate
- truncate_output?
- tty_output=
- tty_output?
- unix?
- windows?
DEFAULT_RAKEFILES | = | ['rakefile', 'Rakefile', 'rakefile.rb', 'Rakefile.rb'].freeze |
[R] | name | The name of the application (typically ‘rake’) |
[R] | original_dir | The original directory where rake was invoked. |
[R] | rakefile | Name of the actual rakefile used. |
[R] | top_level_tasks | List of the top level task names (task names from the command line). |
Initialize a Rake::Application object.
[ show source ]
# File lib/rake.rb, line 1972 1972: def initialize 1973: super 1974: @name = 'rake' 1975: @rakefiles = DEFAULT_RAKEFILES.dup 1976: @rakefile = nil 1977: @pending_imports = [] 1978: @imported = [] 1979: @loaders = {} 1980: @default_loader = Rake::DefaultLoader.new 1981: @original_dir = Dir.pwd 1982: @top_level_tasks = [] 1983: add_loader('rb', DefaultLoader.new) 1984: add_loader('rf', DefaultLoader.new) 1985: add_loader('rake', DefaultLoader.new) 1986: @tty_output = STDOUT.tty? 1987: end
Add a file to the list of files to be imported.
[ show source ]
# File lib/rake.rb, line 2439 2439: def add_import(fn) 2440: @pending_imports << fn 2441: end
Add a loader to handle imported files ending in the extension ext.
[ show source ]
# File lib/rake.rb, line 2037 2037: def add_loader(ext, loader) 2038: ext = ".#{ext}" unless ext =~ /^\./ 2039: @loaders[ext] = loader 2040: end
Collect the list of tasks on the command line. If no tasks are given, return a list containing only the default task. Environmental assignments are processed at this time as well.
[ show source ]
# File lib/rake.rb, line 2426 2426: def collect_tasks 2427: @top_level_tasks = [] 2428: ARGV.each do |arg| 2429: if arg =~ /^(\w+)=(.*)$/ 2430: ENV[$1] = $2 2431: else 2432: @top_level_tasks << arg unless arg =~ /^-/ 2433: end 2434: end 2435: @top_level_tasks.push("default") if @top_level_tasks.size == 0 2436: end
Warn about deprecated use of top level constant names.
[ show source ]
# File lib/rake.rb, line 2458 2458: def const_warning(const_name) 2459: @const_warning ||= false 2460: if ! @const_warning 2461: $stderr.puts %{WARNING: Deprecated reference to top-level constant '#{const_name}' } + 2462: %{found at: #{rakefile_location}} # ' 2463: $stderr.puts %{ Use --classic-namespace on rake command} 2464: $stderr.puts %{ or 'require "rake/classic_namespace"' in Rakefile} 2465: end 2466: @const_warning = true 2467: end
Display the tasks and prerequisites
[ show source ]
# File lib/rake.rb, line 2184 2184: def display_prerequisites 2185: tasks.each do |t| 2186: puts "#{name} #{t.name}" 2187: t.prerequisites.each { |pre| puts " #{pre}" } 2188: end 2189: end
Display the tasks and comments.
[ show source ]
# File lib/rake.rb, line 2121 2121: def display_tasks_and_comments 2122: displayable_tasks = tasks.select { |t| 2123: t.comment && t.name =~ options.show_task_pattern 2124: } 2125: if options.full_description 2126: displayable_tasks.each do |t| 2127: puts "#{name} #{t.name_with_args}" 2128: t.full_comment.split("\n").each do |line| 2129: puts " #{line}" 2130: end 2131: puts 2132: end 2133: else 2134: width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10 2135: max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil 2136: displayable_tasks.each do |t| 2137: printf "#{name} %-#{width}s # %s\n", 2138: t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment 2139: end 2140: end 2141: end
Calculate the dynamic width of the
[ show source ]
# File lib/rake.rb, line 2155 2155: def dynamic_width 2156: @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput) 2157: end
[ show source ]
# File lib/rake.rb, line 2159 2159: def dynamic_width_stty 2160: %x{stty size 2>/dev/null}.split[1].to_i 2161: end
[ show source ]
# File lib/rake.rb, line 2163 2163: def dynamic_width_tput 2164: %x{tput cols 2>/dev/null}.to_i 2165: end
[ show source ]
# File lib/rake.rb, line 2354 2354: def find_rakefile_location 2355: here = Dir.pwd 2356: while ! (fn = have_rakefile) 2357: Dir.chdir("..") 2358: if Dir.pwd == here || options.nosearch 2359: return nil 2360: end 2361: here = Dir.pwd 2362: end 2363: [fn, here] 2364: ensure 2365: Dir.chdir(Rake.original_dir) 2366: end
Read and handle the command line options.
[ show source ]
# File lib/rake.rb, line 2311 2311: def handle_options 2312: options.rakelib = ['rakelib'] 2313: 2314: OptionParser.new do |opts| 2315: opts.banner = "rake [-f rakefile] {options} targets..." 2316: opts.separator "" 2317: opts.separator "Options are ..." 2318: 2319: opts.on_tail("-h", "--help", "-H", "Display this help message.") do 2320: puts opts 2321: exit 2322: end 2323: 2324: standard_rake_options.each { |args| opts.on(*args) } 2325: end.parse! 2326: 2327: # If class namespaces are requested, set the global options 2328: # according to the values in the options structure. 2329: if options.classic_namespace 2330: $show_tasks = options.show_tasks 2331: $show_prereqs = options.show_prereqs 2332: $trace = options.trace 2333: $dryrun = options.dryrun 2334: $silent = options.silent 2335: end 2336: end
True if one of the files in RAKEFILES is in the current directory. If a match is found, it is copied into @rakefile.
[ show source ]
# File lib/rake.rb, line 2092 2092: def have_rakefile 2093: @rakefiles.each do |fn| 2094: if File.exist?(fn) 2095: others = Dir.glob(fn, File::FNM_CASEFOLD) 2096: return others.size == 1 ? others.first : fn 2097: elsif fn == '' 2098: return fn 2099: end 2100: end 2101: return nil 2102: end
Initialize the command line parameters and app name.
[ show source ]
# File lib/rake.rb, line 2007 2007: def init(app_name='rake') 2008: standard_exception_handling do 2009: @name = app_name 2010: handle_options 2011: collect_tasks 2012: end 2013: end
private —————————————————————-
[ show source ]
# File lib/rake.rb, line 2049 2049: def invoke_task(task_string) 2050: name, args = parse_task_string(task_string) 2051: t = self[name] 2052: t.invoke(*args) 2053: end
Load the pending list of imported files.
[ show source ]
# File lib/rake.rb, line 2444 2444: def load_imports 2445: while fn = @pending_imports.shift 2446: next if @imported.member?(fn) 2447: if fn_task = lookup(fn) 2448: fn_task.invoke 2449: end 2450: ext = File.extname(fn) 2451: loader = @loaders[ext] || @default_loader 2452: loader.load(fn) 2453: @imported << fn 2454: end 2455: end
Find the rakefile and then load it and any pending imports.
[ show source ]
# File lib/rake.rb, line 2016 2016: def load_rakefile 2017: standard_exception_handling do 2018: raw_load_rakefile 2019: end 2020: end
Application options from the command line
[ show source ]
# File lib/rake.rb, line 2043 2043: def options 2044: @options ||= OpenStruct.new 2045: end
[ show source ]
# File lib/rake.rb, line 2055 2055: def parse_task_string(string) 2056: if string =~ /^([^\[]+)(\[(.*)\])$/ 2057: name = $1 2058: args = $3.split(/\s*,\s*/) 2059: else 2060: name = string 2061: args = [] 2062: end 2063: [name, args] 2064: end
Similar to the regular Ruby require command, but will check for *.rake files in addition to *.rb files.
[ show source ]
# File lib/rake.rb, line 2340 2340: def rake_require(file_name, paths=$LOAD_PATH, loaded=$") 2341: return false if loaded.include?(file_name) 2342: paths.each do |path| 2343: fn = file_name + ".rake" 2344: full_path = File.join(path, fn) 2345: if File.exist?(full_path) 2346: load full_path 2347: loaded << fn 2348: return true 2349: end 2350: end 2351: fail LoadError, "Can't find #{file_name}" 2352: end
[ show source ]
# File lib/rake.rb, line 2469 2469: def rakefile_location 2470: begin 2471: fail 2472: rescue RuntimeError => ex 2473: ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || "" 2474: end 2475: end
Run the Rake application. The run method performs the following three steps:
- Initialize the command line options (init).
- Define the tasks (load_rakefile).
- Run the top level tasks (run_tasks).
If you wish to build a custom rake command, you should call init on your application. The define any tasks. Finally, call top_level to run your top level tasks.
[ show source ]
# File lib/rake.rb, line 1998 1998: def run 1999: standard_exception_handling do 2000: init 2001: load_rakefile 2002: top_level 2003: end 2004: end
Provide standard execption handling for the given block.
[ show source ]
# File lib/rake.rb, line 2067 2067: def standard_exception_handling 2068: begin 2069: yield 2070: rescue SystemExit => ex 2071: # Exit silently with current status 2072: raise 2073: rescue OptionParser::InvalidOption => ex 2074: # Exit silently 2075: exit(false) 2076: rescue Exception => ex 2077: # Exit with error message 2078: $stderr.puts "#{name} aborted!" 2079: $stderr.puts ex.message 2080: if options.trace 2081: $stderr.puts ex.backtrace.join("\n") 2082: else 2083: $stderr.puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || "" 2084: $stderr.puts "(See full trace by running task with --trace)" 2085: end 2086: exit(false) 2087: end 2088: end
A list of all the standard options used in rake, suitable for passing to OptionParser.
[ show source ]
# File lib/rake.rb, line 2193 2193: def standard_rake_options 2194: [ 2195: ['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace", 2196: lambda { |value| 2197: require 'rake/classic_namespace' 2198: options.classic_namespace = true 2199: } 2200: ], 2201: ['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.", 2202: lambda { |value| 2203: options.show_tasks = true 2204: options.full_description = true 2205: options.show_task_pattern = Regexp.new(value || '') 2206: } 2207: ], 2208: ['--dry-run', '-n', "Do a dry run without executing actions.", 2209: lambda { |value| 2210: verbose(true) 2211: nowrite(true) 2212: options.dryrun = true 2213: options.trace = true 2214: } 2215: ], 2216: ['--execute', '-e CODE', "Execute some Ruby code and exit.", 2217: lambda { |value| 2218: eval(value) 2219: exit 2220: } 2221: ], 2222: ['--execute-print', '-p CODE', "Execute some Ruby code, print the result, then exit.", 2223: lambda { |value| 2224: puts eval(value) 2225: exit 2226: } 2227: ], 2228: ['--execute-continue', '-E CODE', 2229: "Execute some Ruby code, then continue with normal task processing.", 2230: lambda { |value| eval(value) } 2231: ], 2232: ['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.", 2233: lambda { |value| $:.push(value) } 2234: ], 2235: ['--prereqs', '-P', "Display the tasks and dependencies, then exit.", 2236: lambda { |value| options.show_prereqs = true } 2237: ], 2238: ['--quiet', '-q', "Do not log messages to standard output.", 2239: lambda { |value| verbose(false) } 2240: ], 2241: ['--rakefile', '-f [FILE]', "Use FILE as the rakefile.", 2242: lambda { |value| 2243: value ||= '' 2244: @rakefiles.clear 2245: @rakefiles << value 2246: } 2247: ], 2248: ['--rakelibdir', '--rakelib', '-R RAKELIBDIR', 2249: "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')", 2250: lambda { |value| options.rakelib = value.split(':') } 2251: ], 2252: ['--require', '-r MODULE', "Require MODULE before executing rakefile.", 2253: lambda { |value| 2254: begin 2255: require value 2256: rescue LoadError => ex 2257: begin 2258: rake_require value 2259: rescue LoadError => ex2 2260: raise ex 2261: end 2262: end 2263: } 2264: ], 2265: ['--rules', "Trace the rules resolution.", 2266: lambda { |value| options.trace_rules = true } 2267: ], 2268: ['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.", 2269: lambda { |value| options.nosearch = true } 2270: ], 2271: ['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.", 2272: lambda { |value| 2273: verbose(false) 2274: options.silent = true 2275: } 2276: ], 2277: ['--system', '-g', 2278: "Using system wide (global) rakefiles (usually '~/.rake/*.rake').", 2279: lambda { |value| options.load_system = true } 2280: ], 2281: ['--no-system', '--nosystem', '-G', 2282: "Use standard project Rakefile search paths, ignore system wide rakefiles.", 2283: lambda { |value| options.ignore_system = true } 2284: ], 2285: ['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.", 2286: lambda { |value| 2287: options.show_tasks = true 2288: options.show_task_pattern = Regexp.new(value || '') 2289: options.full_description = false 2290: } 2291: ], 2292: ['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.", 2293: lambda { |value| 2294: options.trace = true 2295: verbose(true) 2296: } 2297: ], 2298: ['--verbose', '-v', "Log message to standard output.", 2299: lambda { |value| verbose(true) } 2300: ], 2301: ['--version', '-V', "Display the program version.", 2302: lambda { |value| 2303: puts "rake, version #{RAKEVERSION}" 2304: exit 2305: } 2306: ] 2307: ] 2308: end
The directory path containing the system wide rakefiles.
[ show source ]
# File lib/rake.rb, line 2400 2400: def system_dir 2401: @system_dir ||= 2402: begin 2403: if ENV['RAKE_SYSTEM'] 2404: ENV['RAKE_SYSTEM'] 2405: else 2406: standard_system_dir 2407: end 2408: end 2409: end
[ show source ]
# File lib/rake.rb, line 2143 2143: def terminal_width 2144: if ENV['RAKE_COLUMNS'] 2145: result = ENV['RAKE_COLUMNS'].to_i 2146: else 2147: result = unix? ? dynamic_width : 80 2148: end 2149: (result < 10) ? 80 : result 2150: rescue 2151: 80 2152: end
Run the top level tasks of a Rake application.
[ show source ]
# File lib/rake.rb, line 2023 2023: def top_level 2024: standard_exception_handling do 2025: if options.show_tasks 2026: display_tasks_and_comments 2027: elsif options.show_prereqs 2028: display_prerequisites 2029: else 2030: top_level_tasks.each { |task_name| invoke_task(task_name) } 2031: end 2032: end 2033: end
[ show source ]
# File lib/rake.rb, line 2175 2175: def truncate(string, width) 2176: if string.length <= width 2177: string 2178: else 2179: ( string[0, width-3] || "" ) + "..." 2180: end 2181: end
We will truncate output if we are outputting to a TTY or if we‘ve been given an explicit column width to honor
[ show source ]
# File lib/rake.rb, line 2116 2116: def truncate_output? 2117: tty_output? || ENV['RAKE_COLUMNS'] 2118: end
Override the detected TTY output state (mostly for testing)
[ show source ]
# File lib/rake.rb, line 2110 2110: def tty_output=( tty_output_state ) 2111: @tty_output = tty_output_state 2112: end
True if we are outputting to TTY, false otherwise
[ show source ]
# File lib/rake.rb, line 2105 2105: def tty_output? 2106: @tty_output 2107: end
[ show source ]
# File lib/rake.rb, line 2167 2167: def unix? 2168: RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i 2169: end
[ show source ]
# File lib/rake.rb, line 2171 2171: def windows? 2172: Win32.windows? 2173: end