| 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