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.

Methods

Included Modules

TaskManager

Constants

DEFAULT_RAKEFILES = ['rakefile', 'Rakefile', 'rakefile.rb', 'Rakefile.rb'].freeze

Attributes

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).

Public Class methods

Initialize a Rake::Application object.

[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

Public Instance methods

Add a file to the list of files to be imported.

[Source]

      # 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.

[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.

[Source]

      # 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.

[Source]

      # 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

[Source]

      # 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.

[Source]

      # 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

[Source]

      # File lib/rake.rb, line 2120
2120:     def dynamic_width
2121:       @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
2122:     end

[Source]

      # File lib/rake.rb, line 2124
2124:     def dynamic_width_stty
2125:       %x{stty size 2>/dev/null}.split[1].to_i
2126:     end

[Source]

      # File lib/rake.rb, line 2128
2128:     def dynamic_width_tput
2129:       %x{tput cols 2>/dev/null}.to_i
2130:     end

[Source]

      # 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.

[Source]

      # 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.

[Source]

      # 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.

[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 —————————————————————-

[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.

[Source]

      # 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.

[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

[Source]

      # File lib/rake.rb, line 2011
2011:     def options
2012:       @options ||= OpenStruct.new
2013:     end

[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.

[Source]

      # 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

[Source]

      # 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.

[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.

[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.

[Source]

      # 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.

[Source]

      # 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

[Source]

      # 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.

[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

[Source]

      # 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

We will truncate output if we are outputting to a TTY or if we‘ve been given an explicit column width to honor

[Source]

      # File lib/rake.rb, line 2081
2081:     def truncate_output?
2082:       tty_output? || ENV['RAKE_COLUMNS']
2083:     end

Override the detected TTY output state (mostly for testing)

[Source]

      # 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

[Source]

      # File lib/rake.rb, line 2070
2070:     def tty_output?
2071:       @tty_output
2072:     end

[Source]

      # File lib/rake.rb, line 2132
2132:     def unix?
2133:       RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
2134:     end

[Source]

      # File lib/rake.rb, line 2136
2136:     def windows?
2137:       Win32.windows?
2138:     end

[Validate]