Class: Gem::Commands::SpecificInstallCommand

Inherits:
Gem::Command
  • Object
show all
Defined in:
lib/rubygems/commands/specific_install_command.rb

Direct Known Subclasses

GitInstallCommand

Constant Summary collapse

DOTDOT_REGEX =
/(?:#{File::PATH_SEPARATOR}|\A)\.\.(?:#{File::PATH_SEPARATOR}|\z)/.freeze
ABS_REGEX =
/\A#{File::PATH_SEPARATOR}/.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(output = STDOUT) ⇒ SpecificInstallCommand

Returns a new instance of SpecificInstallCommand.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/rubygems/commands/specific_install_command.rb', line 15

def initialize(output=STDOUT)
  super 'specific_install', description
  @output = output

  add_option('-l', '--location LOCATION', arguments) do |location, options|
    options[:location] = location
  end

  add_option('-b', '--branch LOCATION', arguments) do |branch, options|
    options[:branch] = branch
  end

  add_option('-d', '--directory DIRECTORY', arguments) do |directory, options|
    options[:directory] = directory
  end
end

Instance Attribute Details

#outputObject

Returns the value of attribute output.



9
10
11
# File 'lib/rubygems/commands/specific_install_command.rb', line 9

def output
  @output
end

Instance Method Details

#argumentsObject



32
33
34
35
36
# File 'lib/rubygems/commands/specific_install_command.rb', line 32

def arguments
  "LOCATION like http://github.com/rdp/ruby_tutorials_core or git://github.com/rdp/ruby_tutorials_core.git or http://host/gem_name.gem\n" +
  "BRANCH (optional) like beta, or new-feature\n" +
  "DIRECTORY (optional) This will change the directory in the downloaded source directory before building the gem."
end

#break_unless_git_presentObject



60
61
62
63
64
# File 'lib/rubygems/commands/specific_install_command.rb', line 60

def break_unless_git_present
  unless system("which git") || system("where git")
    abort("Please install git before using a git based link for specific_install")
  end
end

#change_to_branch(branch) ⇒ Object



213
214
215
216
# File 'lib/rubygems/commands/specific_install_command.rb', line 213

def change_to_branch(branch)
  system("git checkout #{branch}")
  system("git branch")
end

#descriptionObject



11
12
13
# File 'lib/rubygems/commands/specific_install_command.rb', line 11

def description
  "Allows you to install an 'edge' gem straight from its github repository or from a web site"
end

#determine_source_and_installObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/rubygems/commands/specific_install_command.rb', line 66

def determine_source_and_install
  case @loc
  when /^https?(.*)\.gem$/
    install_gem
  when /\.git$/
    break_unless_git_present
    install_git
  when /^https?(.*)$/
    break_unless_git_present
    install_http_repo
  when %r(.*/.*)
    break_unless_git_present
    install_shorthand
  else
    warn 'Error: must end with .git to be a git repository' +
      'or be in shorthand form: rdp/specific_install'
  end
end

#download(full_url, output_name) ⇒ Object



128
129
130
131
132
133
# File 'lib/rubygems/commands/specific_install_command.rb', line 128

def download( full_url, output_name )
  File.open(output_name, "wb") do |output_file|
    uri = URI.parse(full_url)
    output_file.write(uri.read)
  end
end

#executeObject



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rubygems/commands/specific_install_command.rb', line 42

def execute
  @loc ||= set_location
  @branch ||= set_branch if set_branch
  if @loc.nil?
    raise ArgumentError, "No location received. Use like `gem specific_install -l http://example.com/rdp/specific_install`"
  end
  Dir.mktmpdir do |dir|
    if subdir = options[:directory]
      abort("Subdir '#{subdir}' is not a valid directory") unless valid_subdir?(subdir)
      @top_dir = dir
      @src_dir = File.join(dir, subdir)
    else
      @top_dir = @src_dir = dir
    end
    determine_source_and_install
  end
end

#find_or_build_gemObject



182
183
184
185
186
187
188
189
190
191
# File 'lib/rubygems/commands/specific_install_command.rb', line 182

def find_or_build_gem
  if gemspec_exists?
    gemspec = Gem::Specification.load(gemspec_file)
    Gem::Package.build gemspec
  elsif gemfile
    gemfile
  else
    nil
  end
end

#gem_nameObject



108
109
110
# File 'lib/rubygems/commands/specific_install_command.rb', line 108

def gem_name
  @gem_name ||= @loc.split("/").last
end

#gemfile(name = '**/*.gem') ⇒ Object



205
206
207
208
209
210
211
# File 'lib/rubygems/commands/specific_install_command.rb', line 205

def gemfile(name = '**/*.gem')
  if Dir[name].empty?
    false
  else
    Dir[name][0]
  end
end

#gemspec_exists?(name = "*.gemspec") ⇒ Boolean

Returns:

  • (Boolean)


197
198
199
200
201
202
203
# File 'lib/rubygems/commands/specific_install_command.rb', line 197

def gemspec_exists?(name = "*.gemspec")
  if gemspec_file(name)
    File.exists?(gemspec_file(name))
  else
    false
  end
end

#gemspec_file(name = "*.gemspec") ⇒ Object



193
194
195
# File 'lib/rubygems/commands/specific_install_command.rb', line 193

def gemspec_file(name = "*.gemspec")
  Dir[name][0]
end

#install_from_git(dir) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/rubygems/commands/specific_install_command.rb', line 135

def install_from_git(dir)
  Dir.chdir @top_dir do
    change_to_branch(@branch) if @branch
    system("git submodule update --init --recursive") # issue 25
  end

  Dir.chdir dir do
    # reliable method
    if install_gemspec
      success_message
      exit 0
    end

    # legacy methods
    ['', 'rake gemspec', 'rake gem', 'rake build', 'rake package'].each do |command|
      puts "attempting #{command}..."
      system command
      if install_gemspec
        success_message
        exit 0
      end
    end
  end
end

#install_gemObject



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rubygems/commands/specific_install_command.rb', line 85

def install_gem
  Dir.chdir @top_dir do
    output.puts "downloading #{@loc}"
    download(@loc, gem_name)

    if install_gemspec
      success_message
    else
      output.puts "Failed"
    end
  end
end

#install_gemspecObject



172
173
174
175
176
177
178
179
180
# File 'lib/rubygems/commands/specific_install_command.rb', line 172

def install_gemspec
  gem = find_or_build_gem
  if gem
    inst = Gem::DependencyInstaller.new
    inst.install gem
  else
    nil
  end
end

#install_gitObject



112
113
114
115
116
117
118
# File 'lib/rubygems/commands/specific_install_command.rb', line 112

def install_git
  output.puts 'git installing from ' + @loc

  redirect_for_specs = ENV.fetch( "SPECIFIC_INSTALL_SPEC" ) { "" }
  system("git clone #{@loc} #{@top_dir} #{redirect_for_specs}")
  install_from_git(@src_dir)
end

#install_http_repoObject



98
99
100
101
102
103
104
105
106
# File 'lib/rubygems/commands/specific_install_command.rb', line 98

def install_http_repo
  output.puts 'http installing from ' + @loc

  @loc = [@loc, '.git'].join unless @loc[/\.git$/]

  redirect_for_specs = ENV.fetch( "SPECIFIC_INSTALL_SPEC" ) { "" }
  system("git clone #{@loc} #{@top_dir} #{redirect_for_specs}")
  install_from_git(@src_dir)
end

#install_shorthandObject



120
121
122
123
124
125
126
# File 'lib/rubygems/commands/specific_install_command.rb', line 120

def install_shorthand
  output.puts "Installing from [email protected]:#{@loc}.git"

  redirect_for_specs = ENV.fetch( "SPECIFIC_INSTALL_SPEC" ) { "" }
  system("git clone [email protected]:#{@loc}.git #{@top_dir} #{redirect_for_specs}")
  install_from_git(@src_dir)
end

#set_branchObject



164
165
166
# File 'lib/rubygems/commands/specific_install_command.rb', line 164

def set_branch
  options[:branch] || options[:args][1]
end

#set_locationObject



160
161
162
# File 'lib/rubygems/commands/specific_install_command.rb', line 160

def set_location
  options[:location] || options[:args][0]
end

#success_messageObject



168
169
170
# File 'lib/rubygems/commands/specific_install_command.rb', line 168

def success_message
  output.puts 'Successfully installed'
end

#usageObject



38
39
40
# File 'lib/rubygems/commands/specific_install_command.rb', line 38

def usage
  "#{program_name} [LOCATION] [BRANCH] (or command line options for the same)"
end

#valid_subdir?(subdir) ⇒ Boolean

Returns:

  • (Boolean)


221
222
223
224
225
# File 'lib/rubygems/commands/specific_install_command.rb', line 221

def valid_subdir?(subdir)
  !subdir.empty? &&
    subdir !~ DOTDOT_REGEX &&
    subdir !~ ABS_REGEX
end