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 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.
[ show source ]
# File lib/rake.rb, line 2404
2404: def add_import(fn)
2405: @pending_imports << fn
2406: end
Add a loader to handle imported files ending in the extension ext.
[ show source ]
# 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.
[ show source ]
# File lib/rake.rb, line 2391
2391: def collect_tasks(argv)
2392: @top_level_tasks = []
2393: argv.each do |arg|
2394: if arg =~ /^(\w+)=(.*)$/
2395: ENV[$1] = $2
2396: else
2397: @top_level_tasks << arg unless arg =~ /^-/
2398: end
2399: end
2400: @top_level_tasks.push("default") if @top_level_tasks.size == 0
2401: end
Warn about deprecated use of top level constant names.
[ show source ]
# File lib/rake.rb, line 2423
2423: def const_warning(const_name)
2424: @const_warning ||= false
2425: if ! @const_warning
2426: $stderr.puts %{WARNING: Deprecated reference to top-level constant '#{const_name}' } +
2427: %{found at: #{rakefile_location}} # '
2428: $stderr.puts %{ Use --classic-namespace on rake command}
2429: $stderr.puts %{ or 'require "rake/classic_namespace"' in Rakefile}
2430: end
2431: @const_warning = true
2432: end
Display the tasks and prerequisites
[ show source ]
# File lib/rake.rb, line 2152
2152: def display_prerequisites
2153: tasks.each do |t|
2154: puts "rake #{t.name}"
2155: t.prerequisites.each { |pre| puts " #{pre}" }
2156: end
2157: end
Display the tasks and dependencies.
[ show source ]
# File lib/rake.rb, line 2089
2089: def display_tasks_and_comments
2090: displayable_tasks = tasks.select { |t|
2091: t.comment && t.name =~ options.show_task_pattern
2092: }
2093: if options.full_description
2094: displayable_tasks.each do |t|
2095: puts "rake #{t.name_with_args}"
2096: t.full_comment.split("\n").each do |line|
2097: puts " #{line}"
2098: end
2099: puts
2100: end
2101: else
2102: width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10
2103: max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil
2104: displayable_tasks.each do |t|
2105: printf "#{name} %-#{width}s # %s\n",
2106: t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment
2107: end
2108: end
2109: end
Calculate the dynamic width of the
[ show source ]
# File lib/rake.rb, line 2123
2123: def dynamic_width
2124: @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
2125: end
[ show source ]
# File lib/rake.rb, line 2127
2127: def dynamic_width_stty
2128: %x{stty size 2>/dev/null}.split[1].to_i
2129: end
[ show source ]
# File lib/rake.rb, line 2131
2131: def dynamic_width_tput
2132: %x{tput cols 2>/dev/null}.to_i
2133: end
[ show source ]
# File lib/rake.rb, line 2323
2323: def find_rakefile_location
2324: here = Dir.pwd
2325: while ! (fn = have_rakefile)
2326: Dir.chdir("..")
2327: if Dir.pwd == here || options.nosearch
2328: return nil
2329: end
2330: here = Dir.pwd
2331: end
2332: [fn, here]
2333: ensure
2334: Dir.chdir(Rake.original_dir)
2335: end
Read and handle the command line options.
[ show source ]
# File lib/rake.rb, line 2279
2279: def handle_options
2280: options.rakelib = ['rakelib']
2281:
2282: opts = OptionParser.new
2283: opts.banner = "rake [-f rakefile] {options} targets..."
2284: opts.separator ""
2285: opts.separator "Options are ..."
2286:
2287: opts.on_tail("-h", "--help", "-H", "Display this help message.") do
2288: puts opts
2289: exit
2290: end
2291:
2292: standard_rake_options.each { |args| opts.on(*args) }
2293: parsed_argv = opts.parse(ARGV)
2294:
2295: # If class namespaces are requested, set the global options
2296: # according to the values in the options structure.
2297: if options.classic_namespace
2298: $show_tasks = options.show_tasks
2299: $show_prereqs = options.show_prereqs
2300: $trace = options.trace
2301: $dryrun = options.dryrun
2302: $silent = options.silent
2303: end
2304: parsed_argv
2305: 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 2060
2060: def have_rakefile
2061: @rakefiles.each do |fn|
2062: if File.exist?(fn)
2063: others = Dir.glob(fn, File::FNM_CASEFOLD)
2064: return others.size == 1 ? others.first : fn
2065: elsif fn == ''
2066: return fn
2067: end
2068: end
2069: return nil
2070: end
Initialize the command line parameters and app name.
[ show source ]
# 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 —————————————————————-
[ show source ]
# 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.
[ show source ]
# File lib/rake.rb, line 2409
2409: def load_imports
2410: while fn = @pending_imports.shift
2411: next if @imported.member?(fn)
2412: if fn_task = lookup(fn)
2413: fn_task.invoke
2414: end
2415: ext = File.extname(fn)
2416: loader = @loaders[ext] || @default_loader
2417: loader.load(fn)
2418: @imported << fn
2419: end
2420: end
Find the rakefile and then load it and any pending imports.
[ show source ]
# 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
[ show source ]
# File lib/rake.rb, line 2011
2011: def options
2012: @options ||= OpenStruct.new
2013: end
[ show source ]
# 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.
[ show source ]
# File lib/rake.rb, line 2309
2309: def rake_require(file_name, paths=$LOAD_PATH, loaded=$")
2310: return false if loaded.include?(file_name)
2311: paths.each do |path|
2312: fn = file_name + ".rake"
2313: full_path = File.join(path, fn)
2314: if File.exist?(full_path)
2315: load full_path
2316: loaded << fn
2317: return true
2318: end
2319: end
2320: fail LoadError, "Can't find #{file_name}"
2321: end
[ show source ]
# File lib/rake.rb, line 2434
2434: def rakefile_location
2435: begin
2436: fail
2437: rescue RuntimeError => ex
2438: ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
2439: end
2440: 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 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.
[ show source ]
# 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.
[ show source ]
# File lib/rake.rb, line 2161
2161: def standard_rake_options
2162: [
2163: ['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace",
2164: lambda { |value|
2165: require 'rake/classic_namespace'
2166: options.classic_namespace = true
2167: }
2168: ],
2169: ['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
2170: lambda { |value|
2171: options.show_tasks = true
2172: options.full_description = true
2173: options.show_task_pattern = Regexp.new(value || '')
2174: }
2175: ],
2176: ['--dry-run', '-n', "Do a dry run without executing actions.",
2177: lambda { |value|
2178: verbose(true)
2179: nowrite(true)
2180: options.dryrun = true
2181: options.trace = true
2182: }
2183: ],
2184: ['--execute', '-e CODE', "Execute some Ruby code and exit.",
2185: lambda { |value|
2186: eval(value)
2187: exit
2188: }
2189: ],
2190: ['--execute-print', '-p CODE', "Execute some Ruby code, print the result, then exit.",
2191: lambda { |value|
2192: puts eval(value)
2193: exit
2194: }
2195: ],
2196: ['--execute-continue', '-E CODE',
2197: "Execute some Ruby code, then continue with normal task processing.",
2198: lambda { |value| eval(value) }
2199: ],
2200: ['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.",
2201: lambda { |value| $:.push(value) }
2202: ],
2203: ['--prereqs', '-P', "Display the tasks and dependencies, then exit.",
2204: lambda { |value| options.show_prereqs = true }
2205: ],
2206: ['--quiet', '-q', "Do not log messages to standard output.",
2207: lambda { |value| verbose(false) }
2208: ],
2209: ['--rakefile', '-f [FILE]', "Use FILE as the rakefile.",
2210: lambda { |value|
2211: value ||= ''
2212: @rakefiles.clear
2213: @rakefiles << value
2214: }
2215: ],
2216: ['--rakelibdir', '--rakelib', '-R RAKELIBDIR',
2217: "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')",
2218: lambda { |value| options.rakelib = value.split(':') }
2219: ],
2220: ['--require', '-r MODULE', "Require MODULE before executing rakefile.",
2221: lambda { |value|
2222: begin
2223: require value
2224: rescue LoadError => ex
2225: begin
2226: rake_require value
2227: rescue LoadError => ex2
2228: raise ex
2229: end
2230: end
2231: }
2232: ],
2233: ['--rules', "Trace the rules resolution.",
2234: lambda { |value| options.trace_rules = true }
2235: ],
2236: ['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.",
2237: lambda { |value| options.nosearch = true }
2238: ],
2239: ['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.",
2240: lambda { |value|
2241: verbose(false)
2242: options.silent = true
2243: }
2244: ],
2245: ['--system', '-g',
2246: "Using system wide (global) rakefiles (usually '~/.rake/*.rake').",
2247: lambda { |value| options.load_system = true }
2248: ],
2249: ['--no-system', '--nosystem', '-G',
2250: "Use standard project Rakefile search paths, ignore system wide rakefiles.",
2251: lambda { |value| options.ignore_system = true }
2252: ],
2253: ['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.",
2254: lambda { |value|
2255: options.show_tasks = true
2256: options.show_task_pattern = Regexp.new(value || '')
2257: options.full_description = false
2258: }
2259: ],
2260: ['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.",
2261: lambda { |value|
2262: options.trace = true
2263: verbose(true)
2264: }
2265: ],
2266: ['--verbose', '-v', "Log message to standard output (default).",
2267: lambda { |value| verbose(true) }
2268: ],
2269: ['--version', '-V', "Display the program version.",
2270: lambda { |value|
2271: puts "rake, version #{RAKEVERSION}"
2272: exit
2273: }
2274: ]
2275: ]
2276: end
The directory path containing the system wide rakefiles.
[ show source ]
# File lib/rake.rb, line 2369
2369: def system_dir
2370: @system_dir ||=
2371: begin
2372: if ENV['RAKE_SYSTEM']
2373: ENV['RAKE_SYSTEM']
2374: elsif Win32.windows?
2375: Win32.win32_system_dir
2376: else
2377: standard_system_dir
2378: end
2379: end
2380: end
[ show source ]
# File lib/rake.rb, line 2111
2111: def terminal_width
2112: if ENV['RAKE_COLUMNS']
2113: result = ENV['RAKE_COLUMNS'].to_i
2114: else
2115: result = unix? ? dynamic_width : 80
2116: end
2117: (result < 10) ? 80 : result
2118: rescue
2119: 80
2120: end
Run the top level tasks of a Rake application.
[ show source ]
# 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
[ show source ]
# File lib/rake.rb, line 2143
2143: def truncate(string, width)
2144: if string.length <= width
2145: string
2146: else
2147: ( string[0, width-3] || "" ) + "..."
2148: end
2149: 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 2084
2084: def truncate_output?
2085: tty_output? || ENV['RAKE_COLUMNS']
2086: end
Override the detected TTY output state (mostly for testing)
[ show source ]
# File lib/rake.rb, line 2078
2078: def tty_output=( tty_output_state )
2079: @tty_output = tty_output_state
2080: end
True if we are outputting to TTY, false otherwise
[ show source ]
# File lib/rake.rb, line 2073
2073: def tty_output?
2074: @tty_output
2075: end
[ show source ]
# File lib/rake.rb, line 2135
2135: def unix?
2136: RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
2137: end
[ show source ]
# File lib/rake.rb, line 2139
2139: def windows?
2140: Win32.windows?
2141: end