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 1948 1948: def initialize 1949: super 1950: @name = 'rake' 1951: @rakefiles = DEFAULT_RAKEFILES.dup 1952: @rakefile = nil 1953: @pending_imports = [] 1954: @imported = [] 1955: @loaders = {} 1956: @default_loader = Rake::DefaultLoader.new 1957: @original_dir = Dir.pwd 1958: @top_level_tasks = [] 1959: add_loader('rb', DefaultLoader.new) 1960: add_loader('rf', DefaultLoader.new) 1961: add_loader('rake', DefaultLoader.new) 1962: @tty_output = STDOUT.tty? 1963: end
Add a file to the list of files to be imported.
# File lib/rake.rb, line 2411 2411: def add_import(fn) 2412: @pending_imports << fn 2413: end
Add a loader to handle imported files ending in the extension ext.
# File lib/rake.rb, line 2013 2013: def add_loader(ext, loader) 2014: ext = ".#{ext}" unless ext =~ /^\./ 2015: @loaders[ext] = loader 2016: 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 2398 2398: def collect_tasks 2399: @top_level_tasks = [] 2400: ARGV.each do |arg| 2401: if arg =~ /^(\w+)=(.*)$/ 2402: ENV[$1] = $2 2403: else 2404: @top_level_tasks << arg unless arg =~ /^-/ 2405: end 2406: end 2407: @top_level_tasks.push("default") if @top_level_tasks.size == 0 2408: end
Warn about deprecated use of top level constant names.
# File lib/rake.rb, line 2430 2430: def const_warning(const_name) 2431: @const_warning ||= false 2432: if ! @const_warning 2433: $stderr.puts %{WARNING: Deprecated reference to top-level constant '#{const_name}' } + 2434: %{found at: #{rakefile_location}} # ' 2435: $stderr.puts %{ Use --classic-namespace on rake command} 2436: $stderr.puts %{ or 'require "rake/classic_namespace"' in Rakefile} 2437: end 2438: @const_warning = true 2439: end
Display the tasks and prerequisites
# File lib/rake.rb, line 2160 2160: def display_prerequisites 2161: tasks.each do |t| 2162: puts "#{name} #{t.name}" 2163: t.prerequisites.each { |pre| puts " #{pre}" } 2164: end 2165: end
Display the tasks and comments.
# File lib/rake.rb, line 2097 2097: def display_tasks_and_comments 2098: displayable_tasks = tasks.select { |t| 2099: t.comment && t.name =~ options.show_task_pattern 2100: } 2101: if options.full_description 2102: displayable_tasks.each do |t| 2103: puts "#{name} #{t.name_with_args}" 2104: t.full_comment.split("\n").each do |line| 2105: puts " #{line}" 2106: end 2107: puts 2108: end 2109: else 2110: width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10 2111: max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil 2112: displayable_tasks.each do |t| 2113: printf "#{name} %-#{width}s # %s\n", 2114: t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment 2115: end 2116: end 2117: end
Calculate the dynamic width of the
# File lib/rake.rb, line 2131 2131: def dynamic_width 2132: @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput) 2133: end
# File lib/rake.rb, line 2135 2135: def dynamic_width_stty 2136: %x{stty size 2>/dev/null}.split[1].to_i 2137: end
# File lib/rake.rb, line 2139 2139: def dynamic_width_tput 2140: %x{tput cols 2>/dev/null}.to_i 2141: end
# File lib/rake.rb, line 2330 2330: def find_rakefile_location 2331: here = Dir.pwd 2332: while ! (fn = have_rakefile) 2333: Dir.chdir("..") 2334: if Dir.pwd == here || options.nosearch 2335: return nil 2336: end 2337: here = Dir.pwd 2338: end 2339: [fn, here] 2340: ensure 2341: Dir.chdir(Rake.original_dir) 2342: end
Read and handle the command line options.
# File lib/rake.rb, line 2287 2287: def handle_options 2288: options.rakelib = ['rakelib'] 2289: 2290: OptionParser.new do |opts| 2291: opts.banner = "rake [-f rakefile] {options} targets..." 2292: opts.separator "" 2293: opts.separator "Options are ..." 2294: 2295: opts.on_tail("-h", "--help", "-H", "Display this help message.") do 2296: puts opts 2297: exit 2298: end 2299: 2300: standard_rake_options.each { |args| opts.on(*args) } 2301: end.parse! 2302: 2303: # If class namespaces are requested, set the global options 2304: # according to the values in the options structure. 2305: if options.classic_namespace 2306: $show_tasks = options.show_tasks 2307: $show_prereqs = options.show_prereqs 2308: $trace = options.trace 2309: $dryrun = options.dryrun 2310: $silent = options.silent 2311: end 2312: 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 2068 2068: def have_rakefile 2069: @rakefiles.each do |fn| 2070: if File.exist?(fn) 2071: others = Dir.glob(fn, File::FNM_CASEFOLD) 2072: return others.size == 1 ? others.first : fn 2073: elsif fn == '' 2074: return fn 2075: end 2076: end 2077: return nil 2078: end
Initialize the command line parameters and app name.
# File lib/rake.rb, line 1983 1983: def init(app_name='rake') 1984: standard_exception_handling do 1985: @name = app_name 1986: handle_options 1987: collect_tasks 1988: end 1989: end
private —————————————————————-
# File lib/rake.rb, line 2025 2025: def invoke_task(task_string) 2026: name, args = parse_task_string(task_string) 2027: t = self[name] 2028: t.invoke(*args) 2029: end
Load the pending list of imported files.
# File lib/rake.rb, line 2416 2416: def load_imports 2417: while fn = @pending_imports.shift 2418: next if @imported.member?(fn) 2419: if fn_task = lookup(fn) 2420: fn_task.invoke 2421: end 2422: ext = File.extname(fn) 2423: loader = @loaders[ext] || @default_loader 2424: loader.load(fn) 2425: @imported << fn 2426: end 2427: end
Find the rakefile and then load it and any pending imports.
# File lib/rake.rb, line 1992 1992: def load_rakefile 1993: standard_exception_handling do 1994: raw_load_rakefile 1995: end 1996: end
Application options from the command line
# File lib/rake.rb, line 2019 2019: def options 2020: @options ||= OpenStruct.new 2021: end
# File lib/rake.rb, line 2031 2031: def parse_task_string(string) 2032: if string =~ /^([^\[]+)(\[(.*)\])$/ 2033: name = $1 2034: args = $3.split(/\s*,\s*/) 2035: else 2036: name = string 2037: args = [] 2038: end 2039: [name, args] 2040: end
Similar to the regular Ruby require command, but will check for *.rake files in addition to *.rb files.
# File lib/rake.rb, line 2316 2316: def rake_require(file_name, paths=$LOAD_PATH, loaded=$") 2317: return false if loaded.include?(file_name) 2318: paths.each do |path| 2319: fn = file_name + ".rake" 2320: full_path = File.join(path, fn) 2321: if File.exist?(full_path) 2322: load full_path 2323: loaded << fn 2324: return true 2325: end 2326: end 2327: fail LoadError, "Can't find #{file_name}" 2328: end
# File lib/rake.rb, line 2441 2441: def rakefile_location 2442: begin 2443: fail 2444: rescue RuntimeError => ex 2445: ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || "" 2446: end 2447: 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 1974 1974: def run 1975: standard_exception_handling do 1976: init 1977: load_rakefile 1978: top_level 1979: end 1980: end
Provide standard execption handling for the given block.
# File lib/rake.rb, line 2043 2043: def standard_exception_handling 2044: begin 2045: yield 2046: rescue SystemExit => ex 2047: # Exit silently with current status 2048: exit(ex.status) 2049: rescue SystemExit, OptionParser::InvalidOption => ex 2050: # Exit silently 2051: exit(1) 2052: rescue Exception => ex 2053: # Exit with error message 2054: $stderr.puts "#{name} aborted!" 2055: $stderr.puts ex.message 2056: if options.trace 2057: $stderr.puts ex.backtrace.join("\n") 2058: else 2059: $stderr.puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || "" 2060: $stderr.puts "(See full trace by running task with --trace)" 2061: end 2062: exit(1) 2063: end 2064: end
A list of all the standard options used in rake, suitable for passing to OptionParser.
# File lib/rake.rb, line 2169 2169: def standard_rake_options 2170: [ 2171: ['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace", 2172: lambda { |value| 2173: require 'rake/classic_namespace' 2174: options.classic_namespace = true 2175: } 2176: ], 2177: ['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.", 2178: lambda { |value| 2179: options.show_tasks = true 2180: options.full_description = true 2181: options.show_task_pattern = Regexp.new(value || '') 2182: } 2183: ], 2184: ['--dry-run', '-n', "Do a dry run without executing actions.", 2185: lambda { |value| 2186: verbose(true) 2187: nowrite(true) 2188: options.dryrun = true 2189: options.trace = true 2190: } 2191: ], 2192: ['--execute', '-e CODE', "Execute some Ruby code and exit.", 2193: lambda { |value| 2194: eval(value) 2195: exit 2196: } 2197: ], 2198: ['--execute-print', '-p CODE', "Execute some Ruby code, print the result, then exit.", 2199: lambda { |value| 2200: puts eval(value) 2201: exit 2202: } 2203: ], 2204: ['--execute-continue', '-E CODE', 2205: "Execute some Ruby code, then continue with normal task processing.", 2206: lambda { |value| eval(value) } 2207: ], 2208: ['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.", 2209: lambda { |value| $:.push(value) } 2210: ], 2211: ['--prereqs', '-P', "Display the tasks and dependencies, then exit.", 2212: lambda { |value| options.show_prereqs = true } 2213: ], 2214: ['--quiet', '-q', "Do not log messages to standard output.", 2215: lambda { |value| verbose(false) } 2216: ], 2217: ['--rakefile', '-f [FILE]', "Use FILE as the rakefile.", 2218: lambda { |value| 2219: value ||= '' 2220: @rakefiles.clear 2221: @rakefiles << value 2222: } 2223: ], 2224: ['--rakelibdir', '--rakelib', '-R RAKELIBDIR', 2225: "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')", 2226: lambda { |value| options.rakelib = value.split(':') } 2227: ], 2228: ['--require', '-r MODULE', "Require MODULE before executing rakefile.", 2229: lambda { |value| 2230: begin 2231: require value 2232: rescue LoadError => ex 2233: begin 2234: rake_require value 2235: rescue LoadError => ex2 2236: raise ex 2237: end 2238: end 2239: } 2240: ], 2241: ['--rules', "Trace the rules resolution.", 2242: lambda { |value| options.trace_rules = true } 2243: ], 2244: ['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.", 2245: lambda { |value| options.nosearch = true } 2246: ], 2247: ['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.", 2248: lambda { |value| 2249: verbose(false) 2250: options.silent = true 2251: } 2252: ], 2253: ['--system', '-g', 2254: "Using system wide (global) rakefiles (usually '~/.rake/*.rake').", 2255: lambda { |value| options.load_system = true } 2256: ], 2257: ['--no-system', '--nosystem', '-G', 2258: "Use standard project Rakefile search paths, ignore system wide rakefiles.", 2259: lambda { |value| options.ignore_system = true } 2260: ], 2261: ['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.", 2262: lambda { |value| 2263: options.show_tasks = true 2264: options.show_task_pattern = Regexp.new(value || '') 2265: options.full_description = false 2266: } 2267: ], 2268: ['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.", 2269: lambda { |value| 2270: options.trace = true 2271: verbose(true) 2272: } 2273: ], 2274: ['--verbose', '-v', "Log message to standard output.", 2275: lambda { |value| verbose(true) } 2276: ], 2277: ['--version', '-V', "Display the program version.", 2278: lambda { |value| 2279: puts "rake, version #{RAKEVERSION}" 2280: exit 2281: } 2282: ] 2283: ] 2284: end
The directory path containing the system wide rakefiles.
# File lib/rake.rb, line 2376 2376: def system_dir 2377: @system_dir ||= 2378: begin 2379: if ENV['RAKE_SYSTEM'] 2380: ENV['RAKE_SYSTEM'] 2381: elsif Win32.windows? 2382: Win32.win32_system_dir 2383: else 2384: standard_system_dir 2385: end 2386: end 2387: end
# File lib/rake.rb, line 2119 2119: def terminal_width 2120: if ENV['RAKE_COLUMNS'] 2121: result = ENV['RAKE_COLUMNS'].to_i 2122: else 2123: result = unix? ? dynamic_width : 80 2124: end 2125: (result < 10) ? 80 : result 2126: rescue 2127: 80 2128: end
Run the top level tasks of a Rake application.
# File lib/rake.rb, line 1999 1999: def top_level 2000: standard_exception_handling do 2001: if options.show_tasks 2002: display_tasks_and_comments 2003: elsif options.show_prereqs 2004: display_prerequisites 2005: else 2006: top_level_tasks.each { |task_name| invoke_task(task_name) } 2007: end 2008: end 2009: end
# File lib/rake.rb, line 2151 2151: def truncate(string, width) 2152: if string.length <= width 2153: string 2154: else 2155: ( string[0, width-3] || "" ) + "..." 2156: end 2157: end
Override the detected TTY output state (mostly for testing)
# File lib/rake.rb, line 2086 2086: def tty_output=( tty_output_state ) 2087: @tty_output = tty_output_state 2088: end
True if we are outputting to TTY, false otherwise
# File lib/rake.rb, line 2081 2081: def tty_output? 2082: @tty_output 2083: end