tara 0.1.0
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 +7 -0
- data/bin/tara +8 -0
- data/lib/tara.rb +22 -0
- data/lib/tara/archive.rb +90 -0
- data/lib/tara/archiver.rb +25 -0
- data/lib/tara/cli.rb +45 -0
- data/lib/tara/executable.rb +26 -0
- data/lib/tara/fetcher.rb +72 -0
- data/lib/tara/installer.rb +160 -0
- data/lib/tara/shell.rb +14 -0
- data/lib/tara/version.rb +5 -0
- metadata +57 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 99f4bc434bfa007f054a82265445cd9846937302
|
4
|
+
data.tar.gz: 270a01f1559d5747ecc0d50834ba1b0b98336a39
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dc93d8fc594db3d1c1f0a415166f3ac5b9151034b7f7d7fefff32b8f244c882a93c64709878b2f8d392659018592710a160457402efaafdd3b3e6819d2b43192
|
7
|
+
data.tar.gz: 156522d2729c5ca0ffe381d183030add5dd930ccda05eeb07d4efaae8cc4af147969b0397f4788231efdd694e8ec22c97a165adc33eec2a868ff4f0fa131bc8b
|
data/bin/tara
ADDED
data/lib/tara.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
require 'pathname'
|
5
|
+
require 'tmpdir'
|
6
|
+
|
7
|
+
|
8
|
+
module Tara
|
9
|
+
TaraError = Class.new(StandardError)
|
10
|
+
ExecError = Class.new(TaraError)
|
11
|
+
NotFoundError = Class.new(TaraError)
|
12
|
+
TooManyRedirectsError = Class.new(TaraError)
|
13
|
+
UnknownResponseError = Class.new(TaraError)
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'tara/archive'
|
17
|
+
require 'tara/archiver'
|
18
|
+
require 'tara/cli'
|
19
|
+
require 'tara/executable'
|
20
|
+
require 'tara/fetcher'
|
21
|
+
require 'tara/installer'
|
22
|
+
require 'tara/shell'
|
data/lib/tara/archive.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Tara
|
4
|
+
class Archive
|
5
|
+
def initialize(config={})
|
6
|
+
@config = config
|
7
|
+
@config[:app_dir] ||= Dir.pwd
|
8
|
+
@config[:app_name] ||= File.basename(@config[:app_dir])
|
9
|
+
@config[:build_dir] ||= File.join(@config[:app_dir], 'build')
|
10
|
+
@config[:target_dir] ||= @config[:build_dir]
|
11
|
+
@config[:download_dir] ||= File.join(@config[:build_dir], 'downloads')
|
12
|
+
@config[:archive_name] ||= @config[:app_name] + '.tgz'
|
13
|
+
@config[:files] ||= %w[lib/**/*.rb]
|
14
|
+
@config[:executables] ||= %w[bin/*]
|
15
|
+
@config[:target] ||= 'linux-x86_64'
|
16
|
+
@config[:traveling_ruby_version] ||= '20150210'
|
17
|
+
@config[:without_groups] ||= %w[development test]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.create(config={})
|
21
|
+
new(config).create
|
22
|
+
end
|
23
|
+
|
24
|
+
def create
|
25
|
+
Dir.mktmpdir do |tmp_dir|
|
26
|
+
project_dir = Pathname.new(@config[:app_dir])
|
27
|
+
package_dir = Pathname.new(tmp_dir)
|
28
|
+
target_dir = Pathname.new(@config[:target_dir])
|
29
|
+
install_dependencies(package_dir, fetcher)
|
30
|
+
copy_source(project_dir, package_dir)
|
31
|
+
copy_executables(project_dir, package_dir)
|
32
|
+
Dir.chdir(tmp_dir) do
|
33
|
+
create_archive(target_dir)
|
34
|
+
end
|
35
|
+
File.join(target_dir, @config[:archive_name])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
DOT_PATH = Pathname.new('.')
|
42
|
+
|
43
|
+
def copy_source(project_dir, package_dir)
|
44
|
+
@config[:files].each do |glob_string|
|
45
|
+
Pathname.glob(project_dir.join(glob_string)).each do |file|
|
46
|
+
copy_file(project_dir, package_dir, file)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def copy_executables(project_dir, package_dir)
|
52
|
+
@config[:executables].each do |executable_glob|
|
53
|
+
Pathname.glob(project_dir.join(executable_glob)).each do |executable|
|
54
|
+
copy_file(project_dir, package_dir, executable)
|
55
|
+
FileUtils.chmod(0755, package_dir.join(executable))
|
56
|
+
create_exec_wrapper(package_dir, executable)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_archive(target_dir)
|
62
|
+
Shell.exec('tar -czf %s %s' % [@config[:archive_name], Dir['*'].join(' ')])
|
63
|
+
FileUtils.mkdir_p(target_dir)
|
64
|
+
FileUtils.cp(@config[:archive_name], target_dir)
|
65
|
+
end
|
66
|
+
|
67
|
+
def fetcher
|
68
|
+
@fetcher ||= Fetcher.new(@config[:download_dir], @config[:target], @config[:traveling_ruby_version], @config).setup
|
69
|
+
end
|
70
|
+
|
71
|
+
def install_dependencies(package_dir, fetcher)
|
72
|
+
Installer.new(package_dir, fetcher, @config).execute
|
73
|
+
end
|
74
|
+
|
75
|
+
def copy_file(project_dir, package_dir, file)
|
76
|
+
rel_file = file.relative_path_from(project_dir)
|
77
|
+
unless rel_file.dirname == DOT_PATH
|
78
|
+
FileUtils.mkdir_p(package_dir.join(rel_file.dirname))
|
79
|
+
end
|
80
|
+
FileUtils.cp(project_dir.join(rel_file), package_dir.join(rel_file))
|
81
|
+
end
|
82
|
+
|
83
|
+
def create_exec_wrapper(package_dir, executable)
|
84
|
+
wrapper_path = package_dir.join(executable.basename)
|
85
|
+
ex = Executable.new(executable.basename)
|
86
|
+
File.open(wrapper_path, 'w') { |f| ex.write(f) }
|
87
|
+
FileUtils.chmod(0755, wrapper_path)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Tara
|
4
|
+
class Archiver
|
5
|
+
def initialize(options={})
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def create(options={})
|
10
|
+
Archive.create(@options.merge(options))
|
11
|
+
end
|
12
|
+
|
13
|
+
def extension
|
14
|
+
@options[:extension] || 'tgz'
|
15
|
+
end
|
16
|
+
|
17
|
+
def content_type
|
18
|
+
'application/x-gzip'
|
19
|
+
end
|
20
|
+
|
21
|
+
def metadata
|
22
|
+
@options[:metadata] || {}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/tara/cli.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
|
6
|
+
module Tara
|
7
|
+
class Cli
|
8
|
+
def initialize(argv=ARGV, io=$stderr)
|
9
|
+
@argv = argv
|
10
|
+
@io = io
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
Archive.new(parse_argv).create
|
15
|
+
0
|
16
|
+
rescue => e
|
17
|
+
@io.puts(%(Error during packaging: #{e.message} (#{e.class})))
|
18
|
+
1
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def parse_argv(options={})
|
24
|
+
parser = OptionParser.new do |opts|
|
25
|
+
opts.on('--app-name NAME', 'Name of the app') do |app_name|
|
26
|
+
options[:app_name] = app_name
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on('--app-dir APP_DIR', 'Root directory of the app') do |app_dir|
|
30
|
+
options[:app_dir] = app_dir
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on('--download-dir DOWNLOAD_DIR', 'Where to store Traveling Ruby archives') do |download_dir|
|
34
|
+
options[:download_dir] = download_dir
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on('--target TARGET', 'Target platform for archive') do |target|
|
38
|
+
options[:target] = target
|
39
|
+
end
|
40
|
+
end
|
41
|
+
parser.parse(@argv)
|
42
|
+
options
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Tara
|
4
|
+
class Executable
|
5
|
+
def initialize(name)
|
6
|
+
@name = name
|
7
|
+
end
|
8
|
+
|
9
|
+
def write(io)
|
10
|
+
io.puts(script(@name))
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def script(name)
|
16
|
+
<<-EOH.gsub(/^\s+/, '')
|
17
|
+
#!/bin/bash
|
18
|
+
set -e
|
19
|
+
SELF_DIR=$(dirname "$0")
|
20
|
+
export BUNDLE_GEMFILE="$SELF_DIR/lib/vendor/Gemfile"
|
21
|
+
unset BUNDLE_IGNORE_CONFIG
|
22
|
+
exec "$SELF_DIR/lib/ruby/bin/ruby" -rbundler/setup "$SELF_DIR/bin/#{name}" "$@"
|
23
|
+
EOH
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/tara/fetcher.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
|
5
|
+
|
6
|
+
module Tara
|
7
|
+
class Fetcher
|
8
|
+
def initialize(download_dir, target, tr_version, options={})
|
9
|
+
@download_dir = download_dir
|
10
|
+
@target = target
|
11
|
+
@tr_version = tr_version
|
12
|
+
@ruby_version = options[:ruby_version] || RUBY_VERSION
|
13
|
+
@release_url = options[:tr_release_url] || 'http://d6r77u77i8pq3.cloudfront.net/releases'
|
14
|
+
@shell = options[:shell] || Shell
|
15
|
+
end
|
16
|
+
|
17
|
+
def setup
|
18
|
+
FileUtils.mkdir_p(@download_dir)
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def fetch_ruby
|
23
|
+
local_uri = %(#{@download_dir}/ruby-#{@tr_version}-#{@ruby_version}-#{@target}.tar.gz)
|
24
|
+
fetch(ruby_remote_uri, local_uri)
|
25
|
+
end
|
26
|
+
|
27
|
+
def fetch_native_gem(name, version)
|
28
|
+
remote_uri = native_gem_remote_uri(name, version)
|
29
|
+
local_uri = %(#{@download_dir}/#{name}-#{version}-#{@tr_version}-#{@ruby_version}-#{@target}.tar.gz)
|
30
|
+
fetch(remote_uri, local_uri)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def ruby_remote_uri
|
36
|
+
@ruby_remote_uri ||= [@release_url, %(traveling-ruby-#{@tr_version}-#{@ruby_version}-#{@target}.tar.gz)].join('/')
|
37
|
+
end
|
38
|
+
|
39
|
+
def native_gem_remote_uri(name, version)
|
40
|
+
[@release_url, %(traveling-ruby-gems-#{@tr_version}-#{@ruby_version}-#{@target}/#{name}-#{version}.tar.gz)].join('/')
|
41
|
+
end
|
42
|
+
|
43
|
+
def fetch(remote_uri, local_uri, limit=10)
|
44
|
+
unless File.exist?(local_uri)
|
45
|
+
uri = URI(remote_uri)
|
46
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
47
|
+
http.request(Net::HTTP::Get.new(uri)) do |response|
|
48
|
+
case response
|
49
|
+
when Net::HTTPSuccess
|
50
|
+
File.open(local_uri, 'w') do |f|
|
51
|
+
response.read_body do |chunk|
|
52
|
+
f.write(chunk)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
when Net::HTTPRedirection
|
56
|
+
if limit > 0
|
57
|
+
fetch(response['location'], local_uri, limit - 1)
|
58
|
+
else
|
59
|
+
raise TooManyRedirectsError, %(Exhausted redirect limit, ended up at #{remote_uri})
|
60
|
+
end
|
61
|
+
when Net::HTTPNotFound
|
62
|
+
raise NotFoundError, %(#{remote_uri} doesn't exist)
|
63
|
+
else
|
64
|
+
raise UnknownResponseError, %(#{response.code} '#{response.body}' returned when fetching #{remote_uri})
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
local_uri
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Tara
|
4
|
+
class Installer
|
5
|
+
def initialize(package_dir, fetcher, options={})
|
6
|
+
@package_dir = package_dir
|
7
|
+
@fetcher = fetcher
|
8
|
+
@without_groups = options[:without_groups]
|
9
|
+
@app_dir = Pathname.new(options[:app_dir])
|
10
|
+
@shell = options[:shell] || Shell
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute
|
14
|
+
bundle_gems
|
15
|
+
extract_ruby
|
16
|
+
extract_native_gems
|
17
|
+
strip_tests
|
18
|
+
strip_docs
|
19
|
+
strip_leftovers
|
20
|
+
strip_java_files
|
21
|
+
strip_git_files
|
22
|
+
create_bundler_config
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def bundler_command
|
28
|
+
@bundler_command ||= begin
|
29
|
+
command = 'BUNDLE_IGNORE_CONFIG=1 bundle install --jobs 4 --path vendor'
|
30
|
+
command << %( --without #{@without_groups.join(' ')}) if @without_groups.any?
|
31
|
+
command
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def bundle_gems
|
36
|
+
FileUtils.mkdir_p(lib_path)
|
37
|
+
Dir.mktmpdir do |tmpdir|
|
38
|
+
copy_gem_files(Pathname.new(tmpdir))
|
39
|
+
Dir.chdir(tmpdir) do
|
40
|
+
Bundler.with_clean_env do
|
41
|
+
@shell.exec(bundler_command)
|
42
|
+
end
|
43
|
+
Dir['vendor/*/*/cache/*'].each do |cached_file|
|
44
|
+
FileUtils.rm_rf(cached_file)
|
45
|
+
end
|
46
|
+
Dir['vendor/ruby/*/extensions/*'].each do |ext_file|
|
47
|
+
FileUtils.rm_rf(ext_file)
|
48
|
+
end
|
49
|
+
@shell.exec('find vendor/ruby/*/gems -name "*.o" -exec rm {} \; 2>&1 || true')
|
50
|
+
@shell.exec('find vendor/ruby/*/gems -name "*.so" -exec rm {} \; 2>&1 || true')
|
51
|
+
@shell.exec('find vendor/ruby/*/gems -name "*.bundle" -exec rm {} \; 2>&1 || true')
|
52
|
+
FileUtils.cp_r('vendor', lib_path, preserve: true)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def extract_ruby
|
58
|
+
FileUtils.mkdir_p(ruby_path)
|
59
|
+
FileUtils.mkdir_p(ruby_vendor_path)
|
60
|
+
ruby_archive_path = @fetcher.fetch_ruby
|
61
|
+
@shell.exec(%(tar -xzf #{ruby_archive_path} -C #{ruby_path}))
|
62
|
+
end
|
63
|
+
|
64
|
+
def extract_native_gems
|
65
|
+
native_gems = find_native_gems
|
66
|
+
native_gems.each do |name, version|
|
67
|
+
gem_archive_path = @fetcher.fetch_native_gem(name, version)
|
68
|
+
@shell.exec %(tar -xzf #{gem_archive_path} -C #{ruby_vendor_path})
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def find_native_gems
|
73
|
+
gemspecs = Dir[ruby_vendor_path.join('*/specifications/*.gemspec')]
|
74
|
+
specs = gemspecs.map { |gemspec| Gem::Specification.load(gemspec) }
|
75
|
+
with_ext = specs.select { |s| s.extensions.any? }
|
76
|
+
with_ext.each_with_object({}) do |spec, hash|
|
77
|
+
hash[spec.name] = spec.version.to_s
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def copy_gem_files(path)
|
82
|
+
Dir['Gemfile', 'Gemfile.lock', '*.gemspec'].each do |file|
|
83
|
+
if File.exist?(@app_dir.join(file))
|
84
|
+
FileUtils.cp(@app_dir.join(file), path.join(File.basename(file)))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def create_bundler_config
|
90
|
+
copy_gem_files(vendor_path)
|
91
|
+
FileUtils.mkdir_p(bundle_path)
|
92
|
+
File.open(bundle_path.join('config'), 'w+') do |f|
|
93
|
+
f.puts(%(BUNDLE_PATH: .))
|
94
|
+
f.puts(%(BUNDLE_WITHOUT: #{@without_groups.join(':')})) if @without_groups.any?
|
95
|
+
f.puts(%(BUNDLE_DISABLE_SHARED_GEMS: '1'))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def strip_tests
|
100
|
+
strip_from_gems(%w[tests test spec])
|
101
|
+
end
|
102
|
+
|
103
|
+
def strip_docs
|
104
|
+
strip_from_gems(%w[doc* example* *.txt *.md *.rdoc])
|
105
|
+
end
|
106
|
+
|
107
|
+
def strip_leftovers
|
108
|
+
%w[c cpp h rl].each do |ext|
|
109
|
+
@shell.exec(%(find #{ruby_vendor_path} -name "*.#{ext}" -exec rm {} \\; 2>&1))
|
110
|
+
end
|
111
|
+
@shell.exec(%(find #{ruby_vendor_path} -name "extconf.rb" -exec rm {} \\;))
|
112
|
+
@shell.exec(%(find #{vendor_gems_glob.join('*', 'ext')} -name "Makefile" -exec rm {} \\; 2>&1))
|
113
|
+
@shell.exec(%(find #{vendor_gems_glob.join('*', 'ext')} -name "tmp" -type d 2>&1 | xargs rm -rf))
|
114
|
+
end
|
115
|
+
|
116
|
+
def strip_java_files
|
117
|
+
@shell.exec(%(find #{vendor_gems_glob} -name "*.java" -exec rm {} \\;))
|
118
|
+
end
|
119
|
+
|
120
|
+
def strip_git_files
|
121
|
+
@shell.exec(%(find #{vendor_gems_glob} -name ".git" -type d | xargs rm -rf))
|
122
|
+
@shell.exec(%(find #{bundler_gems_glob} -name ".git" -type d | xargs rm -rf))
|
123
|
+
end
|
124
|
+
|
125
|
+
def strip_from_gems(things)
|
126
|
+
things.each do |thing|
|
127
|
+
FileUtils.rm_r(Dir[vendor_gems_glob.join('*', thing)])
|
128
|
+
FileUtils.rm_r(Dir[bundler_gems_glob.join('*', thing)])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def lib_path
|
133
|
+
@lib_path ||= Pathname.new(@package_dir).join('lib')
|
134
|
+
end
|
135
|
+
|
136
|
+
def vendor_path
|
137
|
+
@vendor_path ||= lib_path.join('vendor')
|
138
|
+
end
|
139
|
+
|
140
|
+
def ruby_vendor_path
|
141
|
+
@ruby_vendor_path ||= vendor_path.join('ruby')
|
142
|
+
end
|
143
|
+
|
144
|
+
def bundle_path
|
145
|
+
@bundle_path ||= vendor_path.join('.bundle')
|
146
|
+
end
|
147
|
+
|
148
|
+
def ruby_path
|
149
|
+
@ruby_path ||= lib_path.join('ruby')
|
150
|
+
end
|
151
|
+
|
152
|
+
def bundler_gems_glob
|
153
|
+
@bundler_gems_glob ||= ruby_vendor_path.join('*', 'bundler', 'gems')
|
154
|
+
end
|
155
|
+
|
156
|
+
def vendor_gems_glob
|
157
|
+
@vendor_gems_glob ||= ruby_vendor_path.join('*', 'gems')
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
data/lib/tara/shell.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Tara
|
4
|
+
class Shell
|
5
|
+
def self.exec(command)
|
6
|
+
output = %x(#{command})
|
7
|
+
$stderr.puts(%(#{command}: #{output})) if ENV['TARA_DEBUG']
|
8
|
+
unless $?.success?
|
9
|
+
raise ExecError, %(Command `#{command}` failed with output: #{output})
|
10
|
+
end
|
11
|
+
output
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/tara/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tara
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mathias Söderberg
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-20 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Tara packs your Ruby app into a standalone archive with gems and a Ruby
|
14
|
+
runtime
|
15
|
+
email:
|
16
|
+
- mths@sdrbrg.se
|
17
|
+
executables:
|
18
|
+
- tara
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- bin/tara
|
23
|
+
- lib/tara.rb
|
24
|
+
- lib/tara/archive.rb
|
25
|
+
- lib/tara/archiver.rb
|
26
|
+
- lib/tara/cli.rb
|
27
|
+
- lib/tara/executable.rb
|
28
|
+
- lib/tara/fetcher.rb
|
29
|
+
- lib/tara/installer.rb
|
30
|
+
- lib/tara/shell.rb
|
31
|
+
- lib/tara/version.rb
|
32
|
+
homepage: http://github.com/mthssdrbrg/tara
|
33
|
+
licenses:
|
34
|
+
- BSD-3-Clause
|
35
|
+
metadata: {}
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 2.1.5
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubyforge_project:
|
52
|
+
rubygems_version: 2.4.5
|
53
|
+
signing_key:
|
54
|
+
specification_version: 4
|
55
|
+
summary: Packs your Ruby app as a standalone archive
|
56
|
+
test_files: []
|
57
|
+
has_rdoc:
|