Class: Thor::Runner

Inherits:
Thor
  • Object
show all
Defined in:
lib/thor/lib/thor/runner.rb

Instance Attribute Summary

Attributes inherited from Thor

#options

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Thor

[], default_task, desc, group, group_name, #initialize, install_task, #invoke, invoke, map, maxima, method_options, opts, package_task, spec_task, start, subclass_files, subclasses, tasks

Constructor Details

This class inherits a constructor from Thor

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args) ⇒ Object



149
150
151
152
153
154
155
156
# File 'lib/thor/lib/thor/runner.rb', line 149

def method_missing(meth, *args)
  meth = meth.to_s
  super(meth.to_sym, *args) unless meth.include? ?:

  initialize_thorfiles(meth)
  task = Thor[meth]
  task.parse task.klass.new, ARGV[1..-1]
end

Class Method Details

.globs_for(path) ⇒ Object



11
12
13
# File 'lib/thor/lib/thor/runner.rb', line 11

def self.globs_for(path)
  ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"]
end

.thor_rootObject



158
159
160
# File 'lib/thor/lib/thor/runner.rb', line 158

def self.thor_root
  File.join(ENV["HOME"] || ENV["APPDATA"], ".thor")
end

.thor_root_globObject



162
163
164
165
166
167
168
169
170
171
172
# File 'lib/thor/lib/thor/runner.rb', line 162

def self.thor_root_glob
  # On Windows thor_root will be something like this:
  #
  #   C:\Documents and Settings\james\.thor
  #
  # If we don't #gsub the \ character, Dir.glob will fail.
  files = Dir["#{thor_root.gsub(/\\/, '/')}/*"]
  files.map! do |file|
    File.directory?(file) ? File.join(file, "main.thor") : file
  end
end

Instance Method Details

#help(task = nil) ⇒ Object

Override Thor#help so we can give info about not-yet-loaded tasks



144
145
146
147
# File 'lib/thor/lib/thor/runner.rb', line 144

def help(task = nil)
  initialize_thorfiles(task) if task && task.include?(?:)
  super
end

#install(name) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/thor/lib/thor/runner.rb', line 19

def install(name)
  initialize_thorfiles

  base = name
  package = :file

  begin
    if File.directory?(File.expand_path(name))
      base, package = File.join(name, "main.thor"), :directory
      contents = open(base).read
    else
      contents = open(name).read
    end
  rescue OpenURI::HTTPError
    raise Error, "Error opening URI `#{name}'"
  rescue Errno::ENOENT
    raise Error, "Error opening file `#{name}'"
  end
  
  is_uri = File.exist?(name) ? false : true
  
  puts "Your Thorfile contains: "
  puts contents
  print "Do you wish to continue [y/N]? "
  response = Readline.readline
  
  return false unless response =~ /^\s*y/i
  
  constants = Thor::Util.constants_in_contents(contents, base)
  
  as = options["as"] || begin
    first_line = contents.split("\n")[0]
    (match = first_line.match(/\s*#\s*module:\s*([^\n]*)/)) ? match[1].strip : nil
  end
      
  if !as
    print "Please specify a name for #{name} in the system repository [#{name}]: "
    as = Readline.readline
    as = name if as.empty?
  end
  
  FileUtils.mkdir_p thor_root
  
  yaml_file = File.join(thor_root, "thor.yml")
  FileUtils.touch(yaml_file)
  yaml = thor_yaml
  
  location = (options[:relative] || is_uri) ? name : File.expand_path(name)
  yaml[as] = {:filename => Digest::MD5.hexdigest(name + as), :location => location, :constants => constants}
  
  save_yaml(yaml)
  
  puts "Storing thor file in your system repository"
  
  destination = File.join(thor_root, yaml[as][:filename])
  
  if package == :file
    File.open(destination, "w") {|f| f.puts contents }
  else
    FileUtils.cp_r(name, destination)
  end
  
  yaml[as][:filename] # Indicate sucess
end

#installedObject



115
116
117
118
119
120
121
122
123
124
# File 'lib/thor/lib/thor/runner.rb', line 115

def installed
  thor_root_glob.each do |f|
    next if f =~ /thor\.yml$/
    load_thorfile f unless Thor.subclass_files.keys.include?(File.expand_path(f))
  end

  klasses = Thor.subclasses
  klasses -= [Thor, Thor::Runner] unless options['internal']
  display_klasses(true, klasses)
end

#list(search = "") ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/thor/lib/thor/runner.rb', line 130

def list(search = "")
  initialize_thorfiles
  search = ".*#{search}" if options["substring"]
  search = /^#{search}.*/i
  group  = options[:group] || 'standard'

  classes = Thor.subclasses.select do |k|
    (options[:all] || k.group_name == group) && 
    Thor::Util.constant_to_thor_path(k.name) =~ search
  end
  display_klasses(false, classes)
end

#uninstall(name) ⇒ Object

Raises:



85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/thor/lib/thor/runner.rb', line 85

def uninstall(name)
  yaml = thor_yaml
  raise Error, "Can't find module `#{name}'" unless yaml[name]
  
  puts "Uninstalling #{name}."
  
  file = File.join(thor_root, "#{yaml[name][:filename]}")
  FileUtils.rm_rf(file)
  yaml.delete(name)
  save_yaml(yaml)
  
  puts "Done."
end

#update(name) ⇒ Object

Raises:



100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/thor/lib/thor/runner.rb', line 100

def update(name)
  yaml = thor_yaml
  raise Error, "Can't find module `#{name}'" if !yaml[name] || !yaml[name][:location]

  puts "Updating `#{name}' from #{yaml[name][:location]}"
  old_filename = yaml[name][:filename]
  self.options = self.options.merge("as" => name)
  filename = install(yaml[name][:location])
  unless filename == old_filename
    File.delete(File.join(thor_root, old_filename))
  end
end