rien 0.0.3 → 0.0.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 41db30d7cf5c9e875f8d5a6d501d31a870f86db9c6ced2df28b653e3702eb3d2
4
- data.tar.gz: 8d80bc19aaebb6598ff34d31c14948974f69157d5d1c5c897d3c834a5ea11377
3
+ metadata.gz: '0094436a546c52a481feb6536ee79b3fa8927c8ec06e23c31b78fad3d24ecb8d'
4
+ data.tar.gz: a1de8fccd8397e1ba2494480e083ef9e0c8f5a7f19ddbe179f0e2ec3b2da6196
5
5
  SHA512:
6
- metadata.gz: eaf3df6e327068cd266cebbf20568458561b7e455380da5274d70dc488dfab3a0c2a5d52e0e4f112738f590df37a79bfbe86d3e72de81dc72fab2f0fa1a6c711
7
- data.tar.gz: a3d37be26849827cb354b13719b2c32ecd0cc747a9f7615dcebc073b688d9c47575af25b518ebaed24bde660d27d76f99a617141ec8c397e0048c089b7466d28
6
+ metadata.gz: f068ad7e92c3920d79bdf09079350eed7494f0046abd9d3b233bd2650b3606ea8b880eb2e79be16da7e5fb18c37b3b705a556cee46dfd9f72e004aaf503d3f7b
7
+ data.tar.gz: 21550da29e351feb4e6cbb43317d0cb7259fc12f3ab2bd48e032aa0848931afb810b94e663a3079af31a9c78cb9361b398579a9cbed3db1aab5615f10197b624
@@ -0,0 +1,102 @@
1
+ # Rien
2
+
3
+ Ruby IR Encoding Gem (Experimental)
4
+
5
+ # Example
6
+
7
+ ```
8
+ Usage: rien [options]
9
+ -e, --encode [FILE] Encode specific ruby file
10
+ -p, --pack [DIR] Pack ruby directory into encoded files
11
+ -o, --out [FILE/DIR] Indicate the output of the encoded file(s)
12
+ -u, --use-rienfile Use Rienfile to configure, override other options
13
+ -s, --silent-mode Suppress all prompts asking for user input
14
+ -t, --tmpdir [DIR] Select a temp directory to store intermediate results
15
+ ```
16
+
17
+ ## Encode Mode
18
+
19
+ Encode single ruby file
20
+
21
+ ```ruby
22
+ # hello.rb
23
+
24
+ puts "Hello Rien"
25
+ ```
26
+
27
+ ```
28
+ rien -e hello.rb -o encoded.rb
29
+
30
+ ruby encoded.rb # => Hello Rien
31
+ ```
32
+
33
+ ## Pack Mode
34
+
35
+ ### Compile all .rb files in the directory
36
+
37
+ ```
38
+ rien -p source -o output
39
+ ```
40
+
41
+ ### Use Rienfile to configure
42
+
43
+ When using `Rienfile` to configure, other options from CLI will be ignored
44
+
45
+ Put a `Rienfile` in your project directory
46
+
47
+ ```ruby
48
+ # source/Rienfile
49
+
50
+ Rien.configure do |config|
51
+ # The syntax is the same as glob used in class Dir
52
+ # [Optional] includes all files by default
53
+ config.includes = ["app/**/*", "lib/**/*"]
54
+ # [Optional] excludes nothing by default
55
+ config.excludes = ["**/*.py",
56
+ "lib/**/templates/**/*",
57
+ "**/init.rb"]
58
+
59
+ # [Optional] set to rien_output by default
60
+ config.output = "compiled"
61
+
62
+ # Rien will wait user to input in console when
63
+ # finding suspicious already compiled file
64
+ # set this to true to turn it off
65
+ # [Optional] set to false by default
66
+ config.silent = false
67
+
68
+ # [Optional] use Dir.tmpdir/rien by default
69
+ # aka. /tmp/rien for linux
70
+ config.tmpdir = "tmpdir/rien"
71
+
72
+ end
73
+ ```
74
+
75
+ and then
76
+
77
+ ```
78
+ rien -p source -u
79
+ ```
80
+ ### Files to be excluded
81
+
82
+ #### Read file and eval
83
+
84
+ Real world code from [redmine/config/initializers/00-core_plugins.rb
85
+ ](https://github.com/redmine/redmine/blob/master/config/initializers/00-core_plugins.rb#L14)
86
+
87
+ ```ruby
88
+ eval(File.read(initializer), binding, initializer)
89
+ ```
90
+
91
+ Compile `lib/plugins/**/init.rb` may lead to a such error in runtime
92
+ ```
93
+ init.rb:5:in `<main>': undefined local variable or method `config' for main:Object (NameError)
94
+ ```
95
+
96
+ Use `Rinefile` to exclude `lib/plugins/**/init.rb`
97
+
98
+ ### Temporary directory
99
+
100
+ Rien uses a `tmpdir` to store intermediate results and timestamps to distinguish them.
101
+
102
+ Check your `tmpdir` (`/tmp/rien` for linux by default) to clean unsuccessful build results.
data/bin/rien CHANGED
@@ -1,80 +1,5 @@
1
1
  #!/bin/ruby
2
2
 
3
- require 'optparse'
4
- require 'rien'
5
- require 'fileutils'
6
- require 'ruby-progressbar'
3
+ require "rien"
7
4
 
8
- options = {
9
- mode: :help,
10
- }
11
-
12
- parser = OptionParser.new do |opts|
13
- opts.banner = 'Usage: rien [options]'
14
- opts.on('-e', '--encode [FILE]', 'Encode specific ruby file', String) do |v|
15
- options[:mode] = :encode
16
- options[:file] = v
17
- options[:output] ||= "output.rb"
18
- end
19
-
20
- opts.on('-p', '--pack [DIR]', 'Pack ruby directory into encoded files', String) do |v|
21
- options[:mode] = :pack
22
- options[:file] = v
23
- options[:output] ||= "rien_output"
24
- end
25
-
26
- opts.on('-o' '--out [FILE/DIR]', 'Indicate the output of the encoded file(s)', String) do |v|
27
- options[:output] = v
28
- end
29
- end
30
-
31
- parser.parse!
32
-
33
- case options[:mode]
34
- when :encode
35
- encoder = Rien::Encoder.new
36
- bytes = encoder.encode_file(options[:file])
37
- generated_name = options[:output]
38
- # Check if end with .rb and no files generated existing
39
-
40
- File.open("#{generated_name}.rbc", 'wb') do |f|
41
- f.write bytes
42
- end
43
-
44
- File.open(generated_name, 'w') do |f|
45
- f.write encoder.bootstrap
46
- end
47
- when :pack
48
- source = options[:file]
49
- destination = options[:output]
50
- FileUtils.cp_r source, destination
51
- encoder = Rien::Encoder.new
52
-
53
- files = Dir.glob(File.join(destination, "**/*.rb"))
54
- progressbar = ProgressBar.create(:title => "Generating", :starting_at => 0, :total => files.length)
55
-
56
- files.each do |path|
57
- progressbar.log("Compiling: #{path}")
58
- begin
59
- bytes = encoder.encode_file(path)
60
- File.open("#{path}.rbc", 'wb') do |f|
61
- f.write bytes
62
- end
63
-
64
- # Replace file with bootstrap
65
- FileUtils.rm(path)
66
- File.open(path, 'w') do |f|
67
- f.write encoder.bootstrap
68
- end
69
-
70
- progressbar.increment
71
- rescue Exception
72
- # ignore
73
- progressbar.increment
74
- end
75
- end
76
- when :help
77
- puts parser
78
- else
79
- puts parser
80
- end
5
+ Rien::Cli.new.start
@@ -1,7 +1,13 @@
1
1
  require 'zlib'
2
2
 
3
+ require_relative 'rien/core_ext/string'
4
+
3
5
  require_relative 'rien/version'
4
6
  require_relative 'rien/const'
5
7
 
8
+ require_relative 'rien/configurable'
9
+
6
10
  require_relative 'rien/decoder'
7
11
  require_relative 'rien/encoder'
12
+
13
+ require_relative 'rien/cli'
@@ -0,0 +1,234 @@
1
+ require "optparse"
2
+ require "ruby-progressbar"
3
+ require "fileutils"
4
+
5
+ module Rien::CliHelper
6
+ class CliHelperStatus
7
+ attr_accessor :silent
8
+
9
+ def initialize
10
+ @silent = false
11
+ end
12
+ end
13
+
14
+ private def status
15
+ @status ||= CliHelperStatus.new
16
+ end
17
+
18
+ private def encoder
19
+ @encoder ||= Rien::Encoder.new
20
+ end
21
+
22
+ private def wait_user_on_encoded(path)
23
+ if path.match(".rbc") && !status.silent
24
+ print "\n#{path} maybe have already been encoded, continue? (a/y/n) ".yellow
25
+ user_input = STDIN.gets.chomp.downcase
26
+ if user_input == "a"
27
+ status.silent = true # skip all warnings
28
+ elsif user_input == "y"
29
+ # ignore
30
+ else
31
+ abort("Manually abort".red)
32
+ end
33
+ end
34
+ end
35
+
36
+ # Notice:
37
+ # this path must be relative path,
38
+ # or it would break after moving to another directory
39
+ private def encode(path)
40
+ wait_user_on_encoded(path)
41
+
42
+ begin
43
+ bytes = encoder.encode_file(path)
44
+ rescue Exception => e
45
+ abort "\nFailed to encode #{path}, reason:\n#{e.message}".red
46
+ end
47
+
48
+ bytes
49
+ end
50
+
51
+ private def export_single_encoded(source, output)
52
+ bytes = encode(source)
53
+
54
+ File.open("#{output}.rbc", "wb") do |f|
55
+ f.write bytes
56
+ end
57
+
58
+ File.open(output, "w") do |f|
59
+ f.write encoder.bootstrap
60
+ end
61
+ end
62
+
63
+ private def replace_with_encoded(path)
64
+ bytes = encode(path)
65
+
66
+ # Write encoded file
67
+ File.open("#{path}.rbc", "wb") do |f|
68
+ f.write bytes
69
+ end
70
+
71
+ # Replace file with bootstrap
72
+ FileUtils.rm(path)
73
+ File.open(path, "w") do |f|
74
+ f.write encoder.bootstrap
75
+ end
76
+ end
77
+
78
+ private def pack_files(paths)
79
+ progressbar = ProgressBar.create(:title => "Generating",
80
+ :starting_at => 0,
81
+ :length => 80,
82
+ :total => paths.length,
83
+ :smoothing => 0.6,
84
+ :format => "%t |%b>>%i| %p%% %a")
85
+
86
+ paths.each do |path|
87
+ progressbar.log("Compiling: #{path}")
88
+ replace_with_encoded(path) # Wirte encoded file and replace the orginal ruby source file with bootstrap
89
+ progressbar.increment
90
+ end
91
+ end
92
+
93
+ private def copy_dir(source, output)
94
+ FileUtils.mkdir_p output
95
+ FileUtils.cp_r File.join(source, "."), output
96
+ rescue Exception => e
97
+ abort("\nFailed to copy #{source} to #{output}, reason: #{e.message}".red)
98
+ end
99
+
100
+ private def move_dir(source, output)
101
+ FileUtils.mv "#{source}", output
102
+ rescue Exception => e
103
+ abort("\nFailed to move #{source} to #{output}, reason: #{e.message}".red)
104
+ end
105
+
106
+ private def pack_all_files_in_directory(source, output, tmpdir)
107
+ # Copy to temp workspace
108
+ time_stamp = Time.now.strftime("%Y%m%d%H%M%S")
109
+ temp_workspace = File.expand_path(time_stamp, tmpdir)
110
+ copy_dir(source, temp_workspace)
111
+
112
+ # Change to temp workspace
113
+ source_dir = File.absolute_path(File.dirname(source))
114
+ Dir.chdir(temp_workspace)
115
+
116
+ # Encode
117
+ files = Dir["./**/*.rb"] # pack all files
118
+ pack_files(files)
119
+
120
+ # Clean up
121
+ puts "Successed to compile and pack #{source} into #{output}\ntotal #{files.length} file(s)".green
122
+ Dir.chdir(source_dir)
123
+ move_dir(temp_workspace, output)
124
+ end
125
+
126
+ private def use_rienfile_to_pack(source)
127
+ # Eval Rienfile
128
+ begin
129
+ rienfile = File.expand_path("Rienfile", source)
130
+ load rienfile
131
+ rescue Exception => e
132
+ abort "\nFailed to load Rienfile, reason:\n#{e.message}".red
133
+ end
134
+
135
+ # Configure
136
+ status.silent = Rien.config.silent
137
+ output = Rien.config.output
138
+ tmpdir = Rien.config.tmpdir
139
+
140
+ # Copy to temp workspace
141
+ time_stamp = Time.now.strftime("%Y%m%d%H%M%S")
142
+ temp_workspace = File.expand_path(time_stamp, tmpdir)
143
+ copy_dir(source, temp_workspace)
144
+
145
+ # Change to temp workspace
146
+ source_dir = File.absolute_path(File.dirname(source))
147
+ Dir.chdir(temp_workspace)
148
+
149
+ # Encode
150
+ files = Rien.config.effective_paths
151
+ pack_files(files)
152
+
153
+ # Clean up
154
+ puts "Successed to compile and pack #{source} into #{output}\n" \
155
+ "using #{rienfile}\n" \
156
+ "total #{files.length} file(s)".green
157
+ Dir.chdir(source_dir)
158
+ move_dir(temp_workspace, output)
159
+ end
160
+ end
161
+
162
+ class Rien::Cli
163
+ include Rien::CliHelper
164
+
165
+ def initialize
166
+ @options = {
167
+ mode: :help,
168
+ }
169
+
170
+ @parser = OptionParser.new do |opts|
171
+ opts.banner = "Usage: rien [options]"
172
+ opts.on("-e", "--encode [FILE]", "Encode specific ruby file", String) do |v|
173
+ @options[:mode] = :encode
174
+ @options[:file] = v
175
+ @options[:output] ||= "output.rb"
176
+ end
177
+
178
+ opts.on("-p", "--pack [DIR]", "Pack ruby directory into encoded files", String) do |v|
179
+ @options[:mode] = :pack
180
+ @options[:file] = v
181
+ @options[:output] ||= "rien_output"
182
+ @options[:tmpdir] ||= "/tmp/rien"
183
+ end
184
+
185
+ opts.on("-o", "--out [FILE/DIR]", "Indicate the output of the encoded file(s)", String) do |v|
186
+ @options[:output] = v
187
+ end
188
+
189
+ opts.on("-u", "--use-rienfile", "Use Rienfile to configure, override other options", String) do
190
+ @options[:rienfile] = true
191
+ end
192
+
193
+ opts.on("-s", "--silent-mode", "Suppress all prompts asking for user input", String) do
194
+ @options[:silent] = true
195
+ end
196
+
197
+ opts.on("-t", "--tmpdir [DIR]", "Select a temp directory to store intermediate results", String) do |v|
198
+ @options[:tmpdir] = v
199
+ end
200
+ end
201
+ end
202
+
203
+ def start
204
+ @parser.parse!
205
+ case @options[:mode]
206
+ when :encode
207
+ source = @options[:file]
208
+ output = @options[:output]
209
+ status.silent = @options[:silent]
210
+
211
+ export_single_encoded(source, output)
212
+
213
+ puts "Successed to compile #{source} into #{output} and #{output}.rbc".green
214
+ when :pack
215
+ source = @options[:file]
216
+ abort("\nOnly directory can be packed".red) unless File.directory?(source)
217
+
218
+ use_rienfile = @options[:rienfile]
219
+ if use_rienfile # Ignore other options from CLI
220
+ use_rienfile_to_pack(source)
221
+ else # Use options from CLI
222
+ output = @options[:output]
223
+ tmpdir = @options[:tmpdir]
224
+ status.silent = @options[:silent]
225
+
226
+ pack_all_files_in_directory(source, output, tmpdir)
227
+ end
228
+ when :help
229
+ puts @parser
230
+ else
231
+ puts @parser
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,55 @@
1
+ require 'tmpdir'
2
+
3
+ module Rien::Configurable
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def config
10
+ @config ||= Configuration.new
11
+ end
12
+
13
+ def configure
14
+ yield(config)
15
+ end
16
+ end
17
+
18
+ class Configuration
19
+ attr_accessor :includes, :excludes, :output, :tmpdir, :silent
20
+
21
+ def initialize
22
+ @includes = ["**/*"] # include all paths by default
23
+ @output = "rien_output" # final result
24
+ @tmpdir = File.expand_path("rien", Dir.tmpdir) # store intermediate results
25
+ @silent = false # see cli.rb wait_user_on_encoded
26
+ end
27
+
28
+ def effective_paths
29
+ temp_paths = [] # store ruby files and directories
30
+ effective_paths = [] # only ruby files to be compiled
31
+
32
+ @includes.each do |path|
33
+ path = "./#{path}"
34
+ temp_paths += Dir[path]
35
+ end
36
+
37
+ unless excludes.nil?
38
+ @excludes.each do |path|
39
+ path = "./#{path}"
40
+ temp_paths -= Dir[path]
41
+ end
42
+ end
43
+
44
+ temp_paths.each do |path|
45
+ effective_paths.push(path) unless File.directory?(path) || path.match("Rienfile")
46
+ end
47
+
48
+ effective_paths
49
+ end
50
+ end
51
+ end
52
+
53
+ module Rien
54
+ include Rien::Configurable
55
+ end
@@ -0,0 +1,21 @@
1
+ class String
2
+ def colorize(color_code) # ANSI color code
3
+ "\e[#{color_code}m#{self}\e[0m"
4
+ end
5
+
6
+ def red
7
+ colorize(31)
8
+ end
9
+
10
+ def green
11
+ colorize(32)
12
+ end
13
+
14
+ def yellow
15
+ colorize(33)
16
+ end
17
+
18
+ def blue
19
+ colorize(34)
20
+ end
21
+ end
@@ -3,8 +3,9 @@ class Rien::Encoder
3
3
  @version = version
4
4
  end
5
5
 
6
- def encode(str)
7
- bytecode = RubyVM::InstructionSequence.compile(str, options: Rien::Const::COMPILE_OPTION)
6
+ def encode_file(path)
7
+ # RubyVM::InstructionSequence.compile(source, __FILE__, relative_path, options)
8
+ bytecode = RubyVM::InstructionSequence.compile(File.read(path), path, path, options: Rien::Const::COMPILE_OPTION)
8
9
  Zlib::Deflate.deflate(bytecode.to_binary)
9
10
  end
10
11
 
@@ -17,8 +18,4 @@ Rien::Decoder.eval("\#{__FILE__}.rbc")
17
18
  EOL
18
19
  end
19
20
 
20
- def encode_file(filepath)
21
- src = File.read(filepath)
22
- self.encode(src)
23
- end
24
21
  end
@@ -1,3 +1,3 @@
1
1
  module Rien
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rien
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - CodeRemixer
8
- autorequire:
9
- bindir:
10
- - bin
8
+ autorequire:
9
+ bindir: bin
11
10
  cert_chain: []
12
- date: 2019-08-24 00:00:00.000000000 Z
11
+ date: 2020-08-10 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: ruby-progressbar
@@ -34,19 +33,22 @@ extensions: []
34
33
  extra_rdoc_files: []
35
34
  files:
36
35
  - LICENSE
36
+ - README.md
37
37
  - bin/rien
38
38
  - lib/rien.rb
39
+ - lib/rien/cli.rb
40
+ - lib/rien/configurable.rb
39
41
  - lib/rien/const.rb
42
+ - lib/rien/core_ext/string.rb
40
43
  - lib/rien/decoder.rb
41
44
  - lib/rien/encoder.rb
42
45
  - lib/rien/version.rb
43
- - rien.gemspec
44
46
  homepage: https://github.com/coderemixer/rien
45
47
  licenses:
46
48
  - Apache-2.0
47
49
  metadata:
48
- issue_tracker: https://github.com/coderemixer/rien/issues
49
- post_install_message:
50
+ bug_tracker_uri: https://github.com/coderemixer/rien/issues
51
+ post_install_message:
50
52
  rdoc_options: []
51
53
  require_paths:
52
54
  - lib
@@ -54,15 +56,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
54
56
  requirements:
55
57
  - - ">="
56
58
  - !ruby/object:Gem::Version
57
- version: 2.4.5
59
+ version: 2.7.0
58
60
  required_rubygems_version: !ruby/object:Gem::Requirement
59
61
  requirements:
60
62
  - - ">="
61
63
  - !ruby/object:Gem::Version
62
64
  version: '0'
63
65
  requirements: []
64
- rubygems_version: 3.0.3
65
- signing_key:
66
+ rubygems_version: 3.1.2
67
+ signing_key:
66
68
  specification_version: 4
67
69
  summary: Ruby IR Encoding
68
70
  test_files: []
@@ -1,21 +0,0 @@
1
- require './lib/rien'
2
-
3
- Gem::Specification.new do |s|
4
- s.name = 'rien'
5
- s.version = Rien::VERSION
6
- s.required_ruby_version = '>=2.4.5'
7
- s.date = Time.now.strftime('%Y-%m-%d')
8
- s.summary = 'Ruby IR Encoding'
9
- s.description = 'Encode your Ruby code for distribution'
10
- s.authors = ['CodeRemixer']
11
- s.email = ['dsh0416@gmail.com']
12
- s.require_paths = ['lib']
13
- s.bindir = ['bin']
14
- s.executables = ['rien']
15
- s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|.resources)/}) } \
16
- - %w(README.md CODE_OF_CONDUCT.md CONTRIBUTING.md Gemfile Rakefile my_general.gemspec .gitignore .rspec .codeclimate.yml .rubocop.yml .travis.yml logo.png Rakefile Gemfile)
17
- s.homepage = 'https://github.com/coderemixer/rien'
18
- s.metadata = { 'issue_tracker' => 'https://github.com/coderemixer/rien/issues' }
19
- s.license = 'Apache-2.0'
20
- s.add_runtime_dependency 'ruby-progressbar', '~> 1.9'
21
- end