Class: Raygun::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/raygun/raygun.rb

Constant Summary collapse

CARBONFIVE_REPO =
'carbonfive/raygun-rails'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target_dir, prototype_repo) ⇒ Runner

Returns a new instance of Runner.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/raygun/raygun.rb', line 19

def initialize(target_dir, prototype_repo)
  @target_dir     = target_dir
  @app_dir        = File.expand_path(target_dir.strip.to_s)
  @app_name       = File.basename(app_dir).gsub(/\s+/, '-')
  @dash_name      = app_name.gsub('_', '-')
  @snake_name     = app_name.gsub('-', '_')
  @camel_name     = camelize(snake_name)
  @title_name     = titleize(snake_name)
  @prototype_repo = prototype_repo

  @current_ruby_version     = RUBY_VERSION
  @current_ruby_patch_level = if RUBY_VERSION < '2.1.0' # Ruby adopted semver starting with 2.1.0.
                               "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
                              else
                                "#{RUBY_VERSION}"
                              end
end

Instance Attribute Details

#app_dirObject

Returns the value of attribute app_dir.



16
17
18
# File 'lib/raygun/raygun.rb', line 16

def app_dir
  @app_dir
end

#app_nameObject

Returns the value of attribute app_name.



16
17
18
# File 'lib/raygun/raygun.rb', line 16

def app_name
  @app_name
end

#camel_nameObject

Returns the value of attribute camel_name.



16
17
18
# File 'lib/raygun/raygun.rb', line 16

def camel_name
  @camel_name
end

#current_ruby_patch_levelObject

Returns the value of attribute current_ruby_patch_level.



16
17
18
# File 'lib/raygun/raygun.rb', line 16

def current_ruby_patch_level
  @current_ruby_patch_level
end

#current_ruby_versionObject

Returns the value of attribute current_ruby_version.



16
17
18
# File 'lib/raygun/raygun.rb', line 16

def current_ruby_version
  @current_ruby_version
end

#dash_nameObject

Returns the value of attribute dash_name.



16
17
18
# File 'lib/raygun/raygun.rb', line 16

def dash_name
  @dash_name
end

#prototype_repoObject

Returns the value of attribute prototype_repo.



16
17
18
# File 'lib/raygun/raygun.rb', line 16

def prototype_repo
  @prototype_repo
end

#snake_nameObject

Returns the value of attribute snake_name.



16
17
18
# File 'lib/raygun/raygun.rb', line 16

def snake_name
  @snake_name
end

#target_dirObject

Returns the value of attribute target_dir.



16
17
18
# File 'lib/raygun/raygun.rb', line 16

def target_dir
  @target_dir
end

#title_nameObject

Returns the value of attribute title_name.



16
17
18
# File 'lib/raygun/raygun.rb', line 16

def title_name
  @title_name
end

Class Method Details

.parse(args) ⇒ Object



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/raygun/raygun.rb', line 232

def self.parse(args)
  raygun = nil

  options = OpenStruct.new
  options.target_dir     = nil
  options.prototype_repo = CARBONFIVE_REPO

  parser = OptionParser.new do |opts|
    opts.banner = "Usage: raygun [options] NEW_APP_DIRECTORY"

    opts.on('-h', '--help', "Show raygun usage") do
      usage_and_exit(opts)
    end
    opts.on('-p', '--prototype [github_repo]', "Prototype github repo (e.g. carbonfive/raygun-rails).") do |prototype|
      options.prototype_repo = prototype
    end
  end

  begin
    parser.parse!
    options.target_dir = ARGV.first

    raise OptionParser::InvalidOption if options.target_dir.nil?

    raygun = Raygun::Runner.new(options.target_dir, options.prototype_repo)

  rescue OptionParser::InvalidOption
    usage_and_exit(parser)
  end

  raygun
end

.usage_and_exit(parser) ⇒ Object



265
266
267
268
# File 'lib/raygun/raygun.rb', line 265

def self.usage_and_exit(parser)
  puts parser
  exit 1
end

Instance Method Details

#check_raygun_versionObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/raygun/raygun.rb', line 74

def check_raygun_version
  required_raygun_version =
    %x{tar xfz #{@prototype} --include "*.raygun-version" -O 2> /dev/null}.chomp ||
      ::Raygun::VERSION

  if Gem::Version.new(required_raygun_version) > Gem::Version.new(::Raygun::VERSION)
    puts  ""
    print "Hold up!".colorize(:red)
    print " This version of the raygun gem (".colorize(:light_red)
    print "#{::Raygun::VERSION})".colorize(:white)
    print " is too old to generate this application (needs ".colorize(:light_red)
    print "#{required_raygun_version}".colorize(:white)
    puts  " or newer).".colorize(:light_red)
    puts  ""
    print "Please update the gem by running ".colorize(:light_red)
    print "gem update raygun".colorize(:white)
    puts  ", and try again. Thanks!".colorize(:light_red)
    puts  ""
    exit 1
  end
end

#check_targetObject



37
38
39
40
41
42
# File 'lib/raygun/raygun.rb', line 37

def check_target
  unless Dir["#{@app_dir}/*"].empty?
    puts "Misfire! The target directory isn't empty... aim elsewhere."
    exit 1
  end
end

#clean_up_unwanted_filesObject



135
136
137
# File 'lib/raygun/raygun.rb', line 135

def clean_up_unwanted_files
  FileUtils.rm "#{app_dir}/.raygun-version", force: true
end

#configure_new_appObject



127
128
129
130
131
132
133
# File 'lib/raygun/raygun.rb', line 127

def configure_new_app
  clean_up_unwanted_files

  update_ruby_version

  initialize_git
end

#copy_prototypeObject



96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/raygun/raygun.rb', line 96

def copy_prototype
  FileUtils.mkdir_p(app_dir)

  shell "tar xfz #{@prototype} -C \"#{app_dir}\""

  # Github includes an extra directory layer in the tag tarball.
  extraneous_dir = Dir.glob("#{app_dir}/*").first
  dirs_to_move   = Dir.glob("#{extraneous_dir}/*", File::FNM_DOTMATCH)
                      .reject { |d| %w{. ..}.include?(File.basename(d)) }

  FileUtils.mv         dirs_to_move, app_dir
  FileUtils.remove_dir extraneous_dir
end

#fetch_prototypeObject



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
# File 'lib/raygun/raygun.rb', line 44

def fetch_prototype
  print "Checking for the latest application prototype...".colorize(:yellow)
  $stdout.flush

  # Check if we can connect, or fail gracefully and use the latest cached version.
  repo        = TemplateRepo.new(prototype_repo)
  name        = repo.name
  tarball_url = repo.tarball
  sha         = repo.sha

  print " #{name}.".colorize(:white)
  $stdout.flush

  cached_prototypes_dir = File.join(Dir.home, ".raygun")
  @prototype = "#{cached_prototypes_dir}/#{name.gsub('/','--')}-#{sha}.tar.gz"

  # Do we already have the tarball cached under ~/.raygun?
  if File.exists?(@prototype)
    puts " Using cached version.".colorize(:yellow)
  else
    print " Downloading...".colorize(:yellow)
    $stdout.flush

    # Download the tarball and install in the cache.
    Dir.mkdir(cached_prototypes_dir, 0755) unless Dir.exists?(cached_prototypes_dir)
    shell "curl -s -L #{tarball_url} -o #{@prototype}"
    puts " done!".colorize(:yellow)
  end
end

#initialize_gitObject



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

def initialize_git
  Dir.chdir(app_dir) do
    shell "git init"
    shell "git add -A ."
    shell "git commit -m 'Raygun-zapped skeleton.'"
  end
end


173
174
175
176
177
178
179
# File 'lib/raygun/raygun.rb', line 173

def print_next_steps
  if @prototype_repo == CARBONFIVE_REPO
    print_next_steps_carbon_five
  else
    print_next_steps_for_custom_repo
  end
end


181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/raygun/raygun.rb', line 181

def print_next_steps_carbon_five
  puts ""
  puts "Zap! Your application is ready. Next steps...".colorize(:yellow)
  puts ""
  puts "# Install updated dependencies and prepare the database".colorize(:light_green)
  puts "$".colorize(:blue) + " cd #{target_dir}".colorize(:light_blue)
  puts "$".colorize(:blue) + " ./bin/setup".colorize(:light_blue)
  puts ""
  puts "# Run the specs (they should all pass)".colorize(:light_green)
  puts "$".colorize(:blue) + " rake".colorize(:light_blue)
  puts ""
  puts "# Run the app and check things out".colorize(:light_green)
  puts "$".colorize(:blue) + " foreman start".colorize(:light_blue)
  puts "$".colorize(:blue) + " open http://localhost:3000".colorize(:light_blue)
  puts ""
  puts "Enjoy your Carbon Five flavored Rails application!".colorize(:yellow)
end


199
200
201
202
203
204
# File 'lib/raygun/raygun.rb', line 199

def print_next_steps_for_custom_repo
  puts ""
  puts "Zap! Your application is ready.".colorize(:yellow)
  puts ""
  puts "Enjoy your raygun generated application!".colorize(:yellow)
end


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/raygun/raygun.rb', line 157

def print_plan
  puts '     ____ '.colorize(:light_yellow)
  puts '    / __ \____ ___  ______ ___  ______ '.colorize(:light_yellow)
  puts '   / /_/ / __ `/ / / / __ `/ / / / __ \ '.colorize(:light_yellow)
  puts '  / _, _/ /_/ / /_/ / /_/ / /_/ / / / / '.colorize(:light_yellow)
  puts ' /_/ |_|\__,_/\__, /\__, /\__,_/_/ /_/ '.colorize(:light_yellow)
  puts '             /____//____/ '.colorize(:light_yellow)
  puts
  puts "Raygun will create new app in directory:".colorize(:yellow) + " #{target_dir}".colorize(:yellow) + "...".colorize(:yellow)
  puts
  puts "-".colorize(:blue) + " Application Name:".colorize(:light_blue) + " #{title_name}".colorize(:light_reen)
  puts "-".colorize(:blue) + " Project Template:".colorize(:light_blue) + " #{prototype_repo}".colorize(:light_reen)
  puts "-".colorize(:blue) + " Ruby Version:    ".colorize(:light_blue) + " #{@current_ruby_patch_level}".colorize(:light_reen)
  puts
end

#rename_new_appObject



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/raygun/raygun.rb', line 110

def rename_new_app
  Dir.chdir(app_dir) do
    {
      'AppPrototype'  => camel_name,
      'app-prototype' => dash_name,
      'app_prototype' => snake_name,
      'App Prototype' => title_name
    }.each do |proto_name, new_name|
      shell "find . -type f -print | xargs #{sed_i} 's/#{proto_name}/#{new_name}/g'"
    end

    %w(d f).each do |find_type|
      shell "find . -depth -type #{find_type} -name '*app_prototype*' -exec bash -c 'mv $0 ${0/app_prototype/#{snake_name}}' {} \\;"
    end
  end
end

#update_ruby_versionObject



139
140
141
142
143
144
145
146
147
# File 'lib/raygun/raygun.rb', line 139

def update_ruby_version
  prototype_ruby_patch_level = File.read(File.expand_path("#{app_dir}/.ruby-version", __FILE__)).strip
  prototype_ruby_version     = prototype_ruby_patch_level.match(/(\d\.\d\.\d).*/)[1]

  Dir.chdir(app_dir) do
    shell "#{sed_i} 's/#{prototype_ruby_patch_level}/#{@current_ruby_patch_level}/g' .ruby-version README.md"
    shell "#{sed_i} 's/#{prototype_ruby_version}/#{@current_ruby_version}/g' Gemfile"
  end
end