rbytes 0.0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,387 @@
1
+ # Copied from https://github.com/rails/rails/blob/38275763257221e381cd4e37958ce1413fd0433c/railties/lib/rails/generators/actions.rb
2
+ module Rails
3
+ module Actions
4
+ # Adds an entry into +Gemfile+ for the supplied gem.
5
+ #
6
+ # gem "rspec", group: :test
7
+ # gem "technoweenie-restful-authentication", lib: "restful-authentication", source: "http://gems.github.com/"
8
+ # gem "rails", "3.0", git: "https://github.com/rails/rails"
9
+ # gem "RedCloth", ">= 4.1.0", "< 4.2.0"
10
+ # gem "rspec", comment: "Put this comment above the gem declaration"
11
+ def gem(*args, **options)
12
+ name, *versions = args
13
+
14
+ # Set the message to be shown in logs. Uses the git repo if one is given,
15
+ # otherwise use name (version).
16
+ parts, message = [quote(name)], name.dup
17
+
18
+ # Output a comment above the gem declaration.
19
+ comment = options.delete(:comment)
20
+
21
+ if versions = versions.any? ? versions : options.delete(:version)
22
+ _versions = Array(versions)
23
+ _versions.each do |version|
24
+ parts << quote(version)
25
+ end
26
+ message << " (#{_versions.join(", ")})"
27
+ end
28
+ message = options[:git] if options[:git]
29
+
30
+ log :gemfile, message
31
+
32
+ parts << quote(options) unless options.empty?
33
+
34
+ in_root do
35
+ str = []
36
+ if comment
37
+ comment.each_line do |comment_line|
38
+ str << indentation
39
+ str << "# #{comment_line}"
40
+ end
41
+ str << "\n"
42
+ end
43
+ str << indentation
44
+ str << "gem #{parts.join(", ")}"
45
+ append_file_with_newline "Gemfile", str.join, verbose: false
46
+ end
47
+ end
48
+
49
+ # Wraps gem entries inside a group.
50
+ #
51
+ # gem_group :development, :test do
52
+ # gem "rspec-rails"
53
+ # end
54
+ def gem_group(*names, **options, &block)
55
+ str = names.map(&:inspect)
56
+ str << quote(options) unless options.empty?
57
+ str = str.join(", ")
58
+ log :gemfile, "group #{str}"
59
+
60
+ in_root do
61
+ append_file_with_newline "Gemfile", "\ngroup #{str} do", force: true
62
+ with_indentation(&block)
63
+ append_file_with_newline "Gemfile", "end", force: true
64
+ end
65
+ end
66
+
67
+ def github(repo, options = {}, &block)
68
+ str = [quote(repo)]
69
+ str << quote(options) unless options.empty?
70
+ str = str.join(", ")
71
+ log :github, "github #{str}"
72
+
73
+ in_root do
74
+ if @indentation.zero?
75
+ append_file_with_newline "Gemfile", "\ngithub #{str} do", force: true
76
+ else
77
+ append_file_with_newline "Gemfile", "#{indentation}github #{str} do", force: true
78
+ end
79
+ with_indentation(&block)
80
+ append_file_with_newline "Gemfile", "#{indentation}end", force: true
81
+ end
82
+ end
83
+
84
+ # Add the given source to +Gemfile+
85
+ #
86
+ # If block is given, gem entries in block are wrapped into the source group.
87
+ #
88
+ # add_source "http://gems.github.com/"
89
+ #
90
+ # add_source "http://gems.github.com/" do
91
+ # gem "rspec-rails"
92
+ # end
93
+ def add_source(source, options = {}, &block)
94
+ log :source, source
95
+
96
+ in_root do
97
+ if block
98
+ append_file_with_newline "Gemfile", "\nsource #{quote(source)} do", force: true
99
+ with_indentation(&block)
100
+ append_file_with_newline "Gemfile", "end", force: true
101
+ else
102
+ prepend_file "Gemfile", "source #{quote(source)}\n", verbose: false
103
+ end
104
+ end
105
+ end
106
+
107
+ # Adds a line inside the Application class for <tt>config/application.rb</tt>.
108
+ #
109
+ # If options <tt>:env</tt> is specified, the line is appended to the corresponding
110
+ # file in <tt>config/environments</tt>.
111
+ #
112
+ # environment do
113
+ # "config.asset_host = 'cdn.provider.com'"
114
+ # end
115
+ #
116
+ # environment(nil, env: "development") do
117
+ # "config.asset_host = 'localhost:3000'"
118
+ # end
119
+ def environment(data = nil, options = {})
120
+ sentinel = "class Application < Rails::Application\n"
121
+ env_file_sentinel = "Rails.application.configure do\n"
122
+ data ||= yield if block_given?
123
+
124
+ in_root do
125
+ if options[:env].nil?
126
+ inject_into_file "config/application.rb", optimize_indentation(data, 4), after: sentinel, verbose: false
127
+ else
128
+ Array(options[:env]).each do |env|
129
+ inject_into_file "config/environments/#{env}.rb", optimize_indentation(data, 2), after: env_file_sentinel, verbose: false
130
+ end
131
+ end
132
+ end
133
+ end
134
+ alias_method :application, :environment
135
+
136
+ # Run a command in git.
137
+ #
138
+ # git :init
139
+ # git add: "this.file that.rb"
140
+ # git add: "onefile.rb", rm: "badfile.cxx"
141
+ def git(commands = {})
142
+ if commands.is_a?(Symbol)
143
+ run "git #{commands}"
144
+ else
145
+ commands.each do |cmd, options|
146
+ run "git #{cmd} #{options}"
147
+ end
148
+ end
149
+ end
150
+
151
+ # Create a new file in the <tt>vendor/</tt> directory. Code can be specified
152
+ # in a block or a data string can be given.
153
+ #
154
+ # vendor("sekrit.rb") do
155
+ # sekrit_salt = "#{Time.now}--#{3.years.ago}--#{rand}--"
156
+ # "salt = '#{sekrit_salt}'"
157
+ # end
158
+ #
159
+ # vendor("foreign.rb", "# Foreign code is fun")
160
+ def vendor(filename, data = nil)
161
+ log :vendor, filename
162
+ data ||= yield if block_given?
163
+ create_file("vendor/#{filename}", optimize_indentation(data), verbose: false)
164
+ end
165
+
166
+ # Create a new file in the <tt>lib/</tt> directory. Code can be specified
167
+ # in a block or a data string can be given.
168
+ #
169
+ # lib("crypto.rb") do
170
+ # "crypted_special_value = '#{rand}--#{Time.now}--#{rand(1337)}--'"
171
+ # end
172
+ #
173
+ # lib("foreign.rb", "# Foreign code is fun")
174
+ def lib(filename, data = nil)
175
+ log :lib, filename
176
+ data ||= yield if block_given?
177
+ create_file("lib/#{filename}", optimize_indentation(data), verbose: false)
178
+ end
179
+
180
+ # Create a new +Rakefile+ with the provided code (either in a block or a string).
181
+ #
182
+ # rakefile("bootstrap.rake") do
183
+ # project = ask("What is the UNIX name of your project?")
184
+ #
185
+ # <<-TASK
186
+ # namespace :#{project} do
187
+ # task :bootstrap do
188
+ # puts "I like boots!"
189
+ # end
190
+ # end
191
+ # TASK
192
+ # end
193
+ #
194
+ # rakefile('seed.rake', 'puts "Planting seeds"')
195
+ def rakefile(filename, data = nil)
196
+ log :rakefile, filename
197
+ data ||= yield if block_given?
198
+ create_file("lib/tasks/#{filename}", optimize_indentation(data), verbose: false)
199
+ end
200
+
201
+ # Create a new initializer with the provided code (either in a block or a string).
202
+ #
203
+ # initializer("globals.rb") do
204
+ # data = ""
205
+ #
206
+ # ['MY_WORK', 'ADMINS', 'BEST_COMPANY_EVAR'].each do |const|
207
+ # data << "#{const} = :entp\n"
208
+ # end
209
+ #
210
+ # data
211
+ # end
212
+ #
213
+ # initializer("api.rb", "API_KEY = '123456'")
214
+ def initializer(filename, data = nil)
215
+ log :initializer, filename
216
+ data ||= yield if block_given?
217
+ create_file("config/initializers/#{filename}", optimize_indentation(data), verbose: false)
218
+ end
219
+
220
+ # Generate something using a generator from Rails or a plugin.
221
+ # The second parameter is the argument string that is passed to
222
+ # the generator or an Array that is joined.
223
+ #
224
+ # generate(:authenticated, "user session")
225
+ def generate(what, *args)
226
+ log :generate, what
227
+
228
+ options = args.extract_options!
229
+ options[:abort_on_failure] = !options[:inline]
230
+
231
+ rails_command "generate #{what} #{args.join(" ")}", options
232
+ end
233
+
234
+ # Runs the supplied rake task (invoked with 'rake ...')
235
+ #
236
+ # rake("db:migrate")
237
+ # rake("db:migrate", env: "production")
238
+ # rake("gems:install", sudo: true)
239
+ # rake("gems:install", capture: true)
240
+ def rake(command, options = {})
241
+ execute_command :rake, command, options
242
+ end
243
+
244
+ # Runs the supplied rake task (invoked with 'rails ...')
245
+ #
246
+ # rails_command("db:migrate")
247
+ # rails_command("db:migrate", env: "production")
248
+ # rails_command("gems:install", sudo: true)
249
+ # rails_command("gems:install", capture: true)
250
+ def rails_command(command, options = {})
251
+ if options[:inline]
252
+ log :rails, command
253
+ command, *args = Shellwords.split(command)
254
+ in_root do
255
+ silence_warnings do
256
+ ::Rails::Command.invoke(command, args, **options)
257
+ end
258
+ end
259
+ else
260
+ execute_command :rails, command, options
261
+ end
262
+ end
263
+
264
+ # Make an entry in Rails routing file <tt>config/routes.rb</tt>
265
+ #
266
+ # route "root 'welcome#index'"
267
+ # route "root 'admin#index'", namespace: :admin
268
+ def route(routing_code, namespace: nil)
269
+ namespace = Array(namespace)
270
+ namespace_pattern = route_namespace_pattern(namespace)
271
+ routing_code = namespace.reverse.reduce(routing_code) do |code, name|
272
+ "namespace :#{name} do\n#{rebase_indentation(code, 2)}end"
273
+ end
274
+
275
+ log :route, routing_code
276
+
277
+ in_root do
278
+ if namespace_match = match_file("config/routes.rb", namespace_pattern)
279
+ base_indent, *, existing_block_indent = namespace_match.captures.compact.map(&:length)
280
+ existing_line_pattern = /^ {,#{existing_block_indent}}\S.+\n?/
281
+ routing_code = rebase_indentation(routing_code, base_indent + 2).gsub(existing_line_pattern, "")
282
+ namespace_pattern = /#{Regexp.escape namespace_match.to_s}/
283
+ end
284
+
285
+ inject_into_file "config/routes.rb", routing_code, after: namespace_pattern, verbose: false, force: false
286
+
287
+ if behavior == :revoke && namespace.any? && namespace_match
288
+ empty_block_pattern = /(#{namespace_pattern})((?:\s*end\n){1,#{namespace.size}})/
289
+ gsub_file "config/routes.rb", empty_block_pattern, verbose: false, force: true do |matched|
290
+ beginning, ending = empty_block_pattern.match(matched).captures
291
+ ending.sub!(/\A\s*end\n/, "") while !ending.empty? && beginning.sub!(/^ *namespace .+ do\n\s*\z/, "")
292
+ beginning + ending
293
+ end
294
+ end
295
+ end
296
+ end
297
+
298
+ # Reads the given file at the source root and prints it in the console.
299
+ #
300
+ # readme "README"
301
+ def readme(path)
302
+ log File.read(find_in_source_paths(path))
303
+ end
304
+
305
+ private
306
+
307
+ # Define log for backwards compatibility. If just one argument is sent,
308
+ # invoke say, otherwise invoke say_status. Differently from say and
309
+ # similarly to say_status, this method respects the quiet? option given.
310
+ def log(*args) # :doc:
311
+ if args.size == 1
312
+ say args.first.to_s unless options.quiet?
313
+ else
314
+ args << ((behavior == :invoke) ? :green : :red)
315
+ say_status(*args)
316
+ end
317
+ end
318
+
319
+ # Runs the supplied command using either "rake ..." or "rails ..."
320
+ # based on the executor parameter provided.
321
+ def execute_command(executor, command, options = {}) # :doc:
322
+ log executor, command
323
+ sudo = (options[:sudo] && !Gem.win_platform?) ? "sudo " : ""
324
+ config = {
325
+ env: {"RAILS_ENV" => (options[:env] || ENV["RAILS_ENV"] || "development")},
326
+ verbose: false,
327
+ capture: options[:capture],
328
+ abort_on_failure: options[:abort_on_failure]
329
+ }
330
+
331
+ in_root { run("#{sudo}#{Shellwords.escape Gem.ruby} bin/#{executor} #{command}", config) }
332
+ end
333
+
334
+ # Always returns value in double quotes.
335
+ def quote(value) # :doc:
336
+ if value.respond_to? :each_pair
337
+ return value.map do |k, v|
338
+ "#{k}: #{quote(v)}"
339
+ end.join(", ")
340
+ end
341
+ return value.inspect unless value.is_a? String
342
+
343
+ "\"#{value.tr("'", '"')}\""
344
+ end
345
+
346
+ # Returns optimized string with indentation
347
+ def optimize_indentation(value, amount = 0) # :doc:
348
+ return "#{value}\n" unless value.is_a?(String)
349
+ "#{value.strip_heredoc.indent(amount).chomp}\n"
350
+ end
351
+ alias_method :rebase_indentation, :optimize_indentation
352
+
353
+ # Indent the +Gemfile+ to the depth of @indentation
354
+ def indentation # :doc:
355
+ " " * @indentation
356
+ end
357
+
358
+ # Manage +Gemfile+ indentation for a DSL action block
359
+ def with_indentation(&block) # :doc:
360
+ @indentation += 1
361
+ instance_eval(&block)
362
+ ensure
363
+ @indentation -= 1
364
+ end
365
+
366
+ # Append string to a file with a newline if necessary
367
+ def append_file_with_newline(path, str, options = {})
368
+ gsub_file path, /\n?\z/, options do |match|
369
+ match.end_with?("\n") ? "" : "\n#{str}\n"
370
+ end
371
+ end
372
+
373
+ def match_file(path, pattern)
374
+ File.read(path).match(pattern) if File.exist?(path)
375
+ end
376
+
377
+ def route_namespace_pattern(namespace)
378
+ namespace.each_with_index.reverse_each.reduce(nil) do |pattern, (name, i)|
379
+ cummulative_margin = "\\#{i + 1}[ ]{2}"
380
+ blank_or_indented_line = "^[ ]*\n|^#{cummulative_margin}.*\n"
381
+ "(?:(?:#{blank_or_indented_line})*?^(#{cummulative_margin})namespace :#{name} do\n#{pattern})?"
382
+ end.then do |pattern|
383
+ /^( *).+\.routes\.draw do *\n#{pattern}/
384
+ end
385
+ end
386
+ end
387
+ end
@@ -0,0 +1,21 @@
1
+ # Stub `Rails.application` to have a correct application name
2
+ module Rails
3
+ class << self
4
+ def application
5
+ return unless File.exist?("config/application.rb")
6
+
7
+ File.read("config/application.rb").then do |contents|
8
+ contents.match(/^module (\S+)\s*$/)
9
+ end.then do |matches|
10
+ next unless matches
11
+
12
+ Module.new.then do |mod|
13
+ Object.const_set(matches[1], mod)
14
+ app_class = Class.new
15
+ mod.const_set(:Application, app_class)
16
+ app_class.new
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Rbytes < Thor
4
+ desc "template", "Load and run generator from RailsBytes"
5
+ def template(url)
6
+ puts "Run template from: #{url}"
7
+
8
+ # require gems typically used in templates
9
+ require "bundler"
10
+
11
+ Base.new.apply(url)
12
+ end
13
+
14
+ <%= include "core_ext", indent: 2 %>
15
+
16
+ class Base < Thor::Group
17
+ <%= include "rails_application_stub", indent: 4 %>
18
+ <%= include "rails_actions", indent: 4 %>
19
+
20
+ include Thor::Actions
21
+ include Rails::Actions
22
+
23
+ # Custom methods defined on AppGenerator
24
+ # https://github.com/rails/rails/blob/38275763257221e381cd4e37958ce1413fd0433c/railties/lib/rails/generators/rails/app/app_generator.rb#L558
25
+ def file(*args, &block)
26
+ create_file(*args, &block)
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbytes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-16 00:00:00.000000000 Z
11
+ date: 2023-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -63,8 +77,18 @@ files:
63
77
  - CHANGELOG.md
64
78
  - LICENSE.txt
65
79
  - README.md
80
+ - bin/rbytes
66
81
  - lib/rbytes.rb
67
- - lib/rbytes/version.rb
82
+ - lib/ruby_bytes/cli.rb
83
+ - lib/ruby_bytes/compiler.rb
84
+ - lib/ruby_bytes/publisher.rb
85
+ - lib/ruby_bytes/test_case.rb
86
+ - lib/ruby_bytes/thor.rb
87
+ - lib/ruby_bytes/version.rb
88
+ - templates/rbytes/core_ext.rb
89
+ - templates/rbytes/rails_actions.rb
90
+ - templates/rbytes/rails_application_stub.rb
91
+ - templates/rbytes/rbytes.rb
68
92
  homepage: http://github.com/palkan/rbytes
69
93
  licenses:
70
94
  - MIT
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rbytes # :nodoc:
4
- VERSION = "0.0.1"
5
- end