Class | Rake::Application |
In: |
lib/rake.rb
|
Parent: | Object |
Rake main application object. When invoking rake from the command line, a Rake::Application object is created and run.
DEFAULT_RAKEFILES | = | ['rakefile', 'Rakefile', 'rakefile.rb', 'Rakefile.rb'].freeze |
name | [R] | The name of the application (typically ‘rake’) |
original_dir | [R] | The original directory where rake was invoked. |
rakefile | [R] | Name of the actual rakefile used. |
top_level_tasks | [R] | List of the top level task names (task names from the command line). |
Initialize a Rake::Application object.
# File lib/rake.rb, line 1941 1941: def initialize 1942: super 1943: @name = 'rake' 1944: @rakefiles = DEFAULT_RAKEFILES.dup 1945: @rakefile = nil 1946: @pending_imports = [] 1947: @imported = [] 1948: @loaders = {} 1949: @default_loader = Rake::DefaultLoader.new 1950: @original_dir = Dir.pwd 1951: @top_level_tasks = [] 1952: add_loader('rb', DefaultLoader.new) 1953: add_loader('rf', DefaultLoader.new) 1954: add_loader('rake', DefaultLoader.new) 1955: @tty_output = STDOUT.tty? 1956: end
Add a file to the list of files to be imported.
# File lib/rake.rb, line 2401 2401: def add_import(fn) 2402: @pending_imports << fn 2403: end
Add a loader to handle imported files ending in the extension ext.
# File lib/rake.rb, line 2005 2005: def add_loader(ext, loader) 2006: ext = ".#{ext}" unless ext =~ /^\./ 2007: @loaders[ext] = loader 2008: 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.
# File lib/rake.rb, line 2388 2388: def collect_tasks(argv) 2389: @top_level_tasks = [] 2390: argv.each do |arg| 2391: if arg =~ /^(\w+)=(.*)$/ 2392: ENV[$1] = $2 2393: else 2394: @top_level_tasks << arg unless arg =~ /^-/ 2395: end 2396: end 2397: @top_level_tasks.push("default") if @top_level_tasks.size == 0 2398: end
Warn about deprecated use of top level constant names.
# File lib/rake.rb, line 2420 2420: def const_warning(const_name) 2421: @const_warning ||= false 2422: if ! @const_warning 2423: $stderr.puts %{WARNING: Deprecated reference to top-level constant '#{const_name}' } + 2424: %{found at: #{rakefile_location}} # ' 2425: $stderr.puts %{ Use --classic-namespace on rake command} 2426: $stderr.puts %{ or 'require "rake/classic_namespace"' in Rakefile} 2427: end 2428: @const_warning = true 2429: end
Display the tasks and prerequisites
# File lib/rake.rb, line 2149 2149: def display_prerequisites 2150: tasks.each do |t| 2151: puts "rake #{t.name}" 2152: t.prerequisites.each { |pre| puts " #{pre}" } 2153: end 2154: end
Display the tasks and dependencies.
# File lib/rake.rb, line 2086 2086: def display_tasks_and_comments 2087: displayable_tasks = tasks.select { |t| 2088: t.comment && t.name =~ options.show_task_pattern 2089: } 2090: if options.full_description 2091: displayable_tasks.each do |t| 2092: puts "rake #{t.name_with_args}" 2093: t.full_comment.split("\n").each do |line| 2094: puts " #{line}" 2095: end 2096: puts 2097: end 2098: else 2099: width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10 2100: max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil 2101: displayable_tasks.each do |t| 2102: printf "#{name} %-#{width}s # %s\n", 2103: t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment 2104: end 2105: end 2106: end
Calculate the dynamic width of the
# File lib/rake.rb, line 2120 2120: def dynamic_width 2121: @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput) 2122: end
# File lib/rake.rb, line 2124 2124: def dynamic_width_stty 2125: %x{stty size 2>/dev/null}.split[1].to_i 2126: end
# File lib/rake.rb, line 2128 2128: def dynamic_width_tput 2129: %x{tput cols 2>/dev/null}.to_i 2130: end
# File lib/rake.rb, line 2320 2320: def find_rakefile_location 2321: here = Dir.pwd 2322: while ! (fn = have_rakefile) 2323: Dir.chdir("..") 2324: if Dir.pwd == here || options.nosearch 2325: return nil 2326: end 2327: here = Dir.pwd 2328: end 2329: [fn, here] 2330: ensure 2331: Dir.chdir(Rake.original_dir) 2332: end
Read and handle the command line options.
# File lib/rake.rb, line 2276 2276: def handle_options 2277: options.rakelib = ['rakelib'] 2278: 2279: opts = OptionParser.new 2280: opts.banner = "rake [-f rakefile] {options} targets..." 2281: opts.separator "" 2282: opts.separator "Options are ..." 2283: 2284: opts.on_tail("-h", "--help", "-H", "Display this help message.") do 2285: puts opts 2286: exit 2287: end 2288: 2289: standard_rake_options.each { |args| opts.on(*args) } 2290: parsed_argv = opts.parse(ARGV) 2291: 2292: # If class namespaces are requested, set the global options 2293: # according to the values in the options structure. 2294: if options.classic_namespace 2295: $show_tasks = options.show_tasks 2296: $show_prereqs = options.show_prereqs 2297: $trace = options.trace 2298: $dryrun = options.dryrun 2299: $silent = options.silent 2300: end 2301: parsed_argv 2302: end
True if one of the files in RAKEFILES is in the current directory. If a match is found, it is copied into @rakefile.
# File lib/rake.rb, line 2060 2060: def have_rakefile 2061: @rakefiles.each do |fn| 2062: if File.exist?(fn) || fn == '' 2063: return fn 2064: end 2065: end 2066: return nil 2067: end
Initialize the command line parameters and app name.
# File lib/rake.rb, line 1976 1976: def init(app_name='rake') 1977: standard_exception_handling do 1978: @name = app_name 1979: collect_tasks handle_options 1980: end 1981: end
private —————————————————————-
# File lib/rake.rb, line 2017 2017: def invoke_task(task_string) 2018: name, args = parse_task_string(task_string) 2019: t = self[name] 2020: t.invoke(*args) 2021: end
Load the pending list of imported files.
# File lib/rake.rb, line 2406 2406: def load_imports 2407: while fn = @pending_imports.shift 2408: next if @imported.member?(fn) 2409: if fn_task = lookup(fn) 2410: fn_task.invoke 2411: end 2412: ext = File.extname(fn) 2413: loader = @loaders[ext] || @default_loader 2414: loader.load(fn) 2415: @imported << fn 2416: end 2417: end
Find the rakefile and then load it and any pending imports.
# File lib/rake.rb, line 1984 1984: def load_rakefile 1985: standard_exception_handling do 1986: raw_load_rakefile 1987: end 1988: end
Application options from the command line
# File lib/rake.rb, line 2011 2011: def options 2012: @options ||= OpenStruct.new 2013: end
# File lib/rake.rb, line 2023 2023: def parse_task_string(string) 2024: if string =~ /^([^\[]+)(\[(.*)\])$/ 2025: name = $1 2026: args = $3.split(/\s*,\s*/) 2027: else 2028: name = string 2029: args = [] 2030: end 2031: [name, args] 2032: end
Similar to the regular Ruby require command, but will check for *.rake files in addition to *.rb files.
# File lib/rake.rb, line 2306 2306: def rake_require(file_name, paths=$LOAD_PATH, loaded=$") 2307: return false if loaded.include?(file_name) 2308: paths.each do |path| 2309: fn = file_name + ".rake" 2310: full_path = File.join(path, fn) 2311: if File.exist?(full_path) 2312: load full_path 2313: loaded << fn 2314: return true 2315: end 2316: end 2317: fail LoadError, "Can't find #{file_name}" 2318: end
# File lib/rake.rb, line 2431 2431: def rakefile_location 2432: begin 2433: fail 2434: rescue RuntimeError => ex 2435: ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || "" 2436: end 2437: end
Run the Rake application. The run method performs the following three steps:
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.
# File lib/rake.rb, line 1967 1967: def run 1968: standard_exception_handling do 1969: init 1970: load_rakefile 1971: top_level 1972: end 1973: end
Provide standard execption handling for the given block.
# File lib/rake.rb, line 2035 2035: def standard_exception_handling 2036: begin 2037: yield 2038: rescue SystemExit => ex 2039: # Exit silently with current status 2040: exit(ex.status) 2041: rescue SystemExit, OptionParser::InvalidOption => ex 2042: # Exit silently 2043: exit(1) 2044: rescue Exception => ex 2045: # Exit with error message 2046: $stderr.puts "rake aborted!" 2047: $stderr.puts ex.message 2048: if options.trace 2049: $stderr.puts ex.backtrace.join("\n") 2050: else 2051: $stderr.puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || "" 2052: $stderr.puts "(See full trace by running task with --trace)" 2053: end 2054: exit(1) 2055: end 2056: end
A list of all the standard options used in rake, suitable for passing to OptionParser.
# File lib/rake.rb, line 2158 2158: def standard_rake_options 2159: [ 2160: ['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace", 2161: lambda { |value| 2162: require 'rake/classic_namespace' 2163: options.classic_namespace = true 2164: } 2165: ], 2166: ['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.", 2167: lambda { |value| 2168: options.show_tasks = true 2169: options.full_description = true 2170: options.show_task_pattern = Regexp.new(value || '') 2171: } 2172: ], 2173: ['--dry-run', '-n', "Do a dry run without executing actions.", 2174: lambda { |value| 2175: verbose(true) 2176: nowrite(true) 2177: options.dryrun = true 2178: options.trace = true 2179: } 2180: ], 2181: ['--execute', '-e CODE', "Execute some Ruby code and exit.", 2182: lambda { |value| 2183: eval(value) 2184: exit 2185: } 2186: ], 2187: ['--execute-print', '-p CODE', "Execute some Ruby code, print the result, then exit.", 2188: lambda { |value| 2189: puts eval(value) 2190: exit 2191: } 2192: ], 2193: ['--execute-continue', '-E CODE', 2194: "Execute some Ruby code, then continue with normal task processing.", 2195: lambda { |value| eval(value) } 2196: ], 2197: ['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.", 2198: lambda { |value| $:.push(value) } 2199: ], 2200: ['--prereqs', '-P', "Display the tasks and dependencies, then exit.", 2201: lambda { |value| options.show_prereqs = true } 2202: ], 2203: ['--quiet', '-q', "Do not log messages to standard output.", 2204: lambda { |value| verbose(false) } 2205: ], 2206: ['--rakefile', '-f [FILE]', "Use FILE as the rakefile.", 2207: lambda { |value| 2208: value ||= '' 2209: @rakefiles.clear 2210: @rakefiles << value 2211: } 2212: ], 2213: ['--rakelibdir', '--rakelib', '-R RAKELIBDIR', 2214: "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')", 2215: lambda { |value| options.rakelib = value.split(':') } 2216: ], 2217: ['--require', '-r MODULE', "Require MODULE before executing rakefile.", 2218: lambda { |value| 2219: begin 2220: require value 2221: rescue LoadError => ex 2222: begin 2223: rake_require value 2224: rescue LoadError => ex2 2225: raise ex 2226: end 2227: end 2228: } 2229: ], 2230: ['--rules', "Trace the rules resolution.", 2231: lambda { |value| options.trace_rules = true } 2232: ], 2233: ['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.", 2234: lambda { |value| options.nosearch = true } 2235: ], 2236: ['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.", 2237: lambda { |value| 2238: verbose(false) 2239: options.silent = true 2240: } 2241: ], 2242: ['--system', '-g', 2243: "Using system wide (global) rakefiles (usually '~/.rake/*.rake').", 2244: lambda { |value| options.load_system = true } 2245: ], 2246: ['--no-system', '--nosystem', '-G', 2247: "Use standard project Rakefile search paths, ignore system wide rakefiles.", 2248: lambda { |value| options.ignore_system = true } 2249: ], 2250: ['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.", 2251: lambda { |value| 2252: options.show_tasks = true 2253: options.show_task_pattern = Regexp.new(value || '') 2254: options.full_description = false 2255: } 2256: ], 2257: ['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.", 2258: lambda { |value| 2259: options.trace = true 2260: verbose(true) 2261: } 2262: ], 2263: ['--verbose', '-v', "Log message to standard output (default).", 2264: lambda { |value| verbose(true) } 2265: ], 2266: ['--version', '-V', "Display the program version.", 2267: lambda { |value| 2268: puts "rake, version #{RAKEVERSION}" 2269: exit 2270: } 2271: ] 2272: ] 2273: end
The directory path containing the system wide rakefiles.
# File lib/rake.rb, line 2366 2366: def system_dir 2367: @system_dir ||= 2368: begin 2369: if ENV['RAKE_SYSTEM'] 2370: ENV['RAKE_SYSTEM'] 2371: elsif Win32.windows? 2372: Win32.win32_system_dir 2373: else 2374: standard_system_dir 2375: end 2376: end 2377: end
# File lib/rake.rb, line 2108 2108: def terminal_width 2109: if ENV['RAKE_COLUMNS'] 2110: result = ENV['RAKE_COLUMNS'].to_i 2111: else 2112: result = unix? ? dynamic_width : 80 2113: end 2114: (result < 10) ? 80 : result 2115: rescue 2116: 80 2117: end
Run the top level tasks of a Rake application.
# File lib/rake.rb, line 1991 1991: def top_level 1992: standard_exception_handling do 1993: if options.show_tasks 1994: display_tasks_and_comments 1995: elsif options.show_prereqs 1996: display_prerequisites 1997: else 1998: top_level_tasks.each { |task_name| invoke_task(task_name) } 1999: end 2000: end 2001: end
# File lib/rake.rb, line 2140 2140: def truncate(string, width) 2141: if string.length <= width 2142: string 2143: else 2144: ( string[0, width-3] || "" ) + "..." 2145: end 2146: end
Override the detected TTY output state (mostly for testing)
# File lib/rake.rb, line 2075 2075: def tty_output=( tty_output_state ) 2076: @tty_output = tty_output_state 2077: end
True if we are outputting to TTY, false otherwise
# File lib/rake.rb, line 2070 2070: def tty_output? 2071: @tty_output 2072: end