datapimp 0.0.1 → 1.0.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/.gitignore +2 -0
- data/Gemfile +6 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +4 -18
- data/README.md +199 -17
- data/Rakefile +24 -0
- data/bin/datapimp +18 -0
- data/datapimp.gemspec +27 -7
- data/lib/datapimp/cli/01_extensions.rb +25 -0
- data/lib/datapimp/cli/config.rb +24 -0
- data/lib/datapimp/cli/setup.rb +35 -0
- data/lib/datapimp/cli/sync.rb +29 -0
- data/lib/datapimp/cli.rb +49 -0
- data/lib/datapimp/clients/amazon.rb +172 -0
- data/lib/datapimp/clients/dropbox.rb +178 -0
- data/lib/datapimp/clients/github.rb +59 -0
- data/lib/datapimp/clients/google.rb +145 -0
- data/lib/datapimp/configuration.rb +210 -0
- data/lib/datapimp/core_ext.rb +5 -0
- data/lib/datapimp/data_sources/dropbox.rb +8 -0
- data/lib/datapimp/data_sources/excel.rb +5 -0
- data/lib/datapimp/data_sources/github.rb +5 -0
- data/lib/datapimp/data_sources/google.rb +5 -0
- data/lib/datapimp/data_sources/json.rb +5 -0
- data/lib/datapimp/data_sources/nokogiri.rb +5 -0
- data/lib/datapimp/data_sources.rb +10 -0
- data/lib/datapimp/sync/dropbox_delta.rb +67 -0
- data/lib/datapimp/sync/dropbox_folder.rb +10 -0
- data/lib/datapimp/sync/google_drive_folder.rb +5 -0
- data/lib/datapimp/sync.rb +30 -0
- data/lib/datapimp/version.rb +1 -1
- data/lib/datapimp.rb +30 -2
- data/packaging/wrapper.sh +32 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/test_helpers.rb +7 -0
- data/tasks/distribution/configuration.rb +15 -0
- data/tasks/distribution/executable.rb +28 -0
- data/tasks/distribution/package.rb +85 -0
- data/tasks/distribution/package_helpers.rb +12 -0
- data/tasks/distribution/release.rb +49 -0
- data/tasks/distribution/release_notes.erb +14 -0
- data/tasks/distribution/release_notes.rb +62 -0
- data/tasks/distribution/tarball.rb +47 -0
- data/tasks/distribution/travelling_ruby.rb +87 -0
- data/tasks/package.rake +41 -0
- data/tasks/upload.rake +40 -0
- metadata +300 -26
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Datapimp
|
5
|
+
class Configuration
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
DefaultSettings = {
|
9
|
+
manifest_filename: "datapimp.json",
|
10
|
+
|
11
|
+
github_username: '',
|
12
|
+
github_organization: '',
|
13
|
+
github_app_key: '',
|
14
|
+
github_app_secret: '',
|
15
|
+
github_access_token: '',
|
16
|
+
|
17
|
+
dnsimple_api_token: '',
|
18
|
+
dnsimple_username: '',
|
19
|
+
|
20
|
+
dropbox_app_key: '',
|
21
|
+
dropbox_app_secret: '',
|
22
|
+
dropbox_app_type: 'sandbox',
|
23
|
+
dropbox_client_token: '',
|
24
|
+
dropbox_client_secret: '',
|
25
|
+
|
26
|
+
aws_access_key_id: '',
|
27
|
+
aws_secret_access_key: '',
|
28
|
+
|
29
|
+
google_client_id: '',
|
30
|
+
google_client_secret: '',
|
31
|
+
google_refresh_token: '',
|
32
|
+
google_access_token: ''
|
33
|
+
}
|
34
|
+
|
35
|
+
def self.method_missing(meth, *args, &block)
|
36
|
+
if instance.respond_to?(meth)
|
37
|
+
return instance.send meth, *args, &block
|
38
|
+
end
|
39
|
+
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def method_missing(meth, *args, &block)
|
44
|
+
if current.key?(meth.to_s)
|
45
|
+
return current.fetch(meth)
|
46
|
+
end
|
47
|
+
|
48
|
+
super
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize!(fresh=false)
|
52
|
+
return if home_config_path.exist? && !fresh
|
53
|
+
|
54
|
+
FileUtils.mkdir_p home_config_path.dirname
|
55
|
+
|
56
|
+
home_config_path.open("w+") do |fh|
|
57
|
+
fh.write(DefaultSettings.to_json)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def manifest_filename
|
62
|
+
"datapimp.json"
|
63
|
+
end
|
64
|
+
|
65
|
+
def dnsimple_setup?
|
66
|
+
dnsimple_api_token.to_s.length > 0 && dnsimple_username.to_s.length > 0
|
67
|
+
end
|
68
|
+
|
69
|
+
def dropbox_setup?
|
70
|
+
dropbox_app_key.to_s.length > 0 && dropbox_app_secret.to_s.length > 0
|
71
|
+
end
|
72
|
+
|
73
|
+
def google_setup?
|
74
|
+
google_client_secret.to_s.length > 0 && google_client_id.to_s.length > 0
|
75
|
+
end
|
76
|
+
|
77
|
+
def amazon_setup?
|
78
|
+
aws_access_key_id.to_s.length > 0 && aws_secret_access_key.to_s.length > 0
|
79
|
+
end
|
80
|
+
|
81
|
+
def show
|
82
|
+
current.each do |p|
|
83
|
+
key, value = p
|
84
|
+
|
85
|
+
unless key == 'sites_directory'
|
86
|
+
puts "#{key}: #{ value.inspect }"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def primary_config
|
92
|
+
cwd_config_path.exist? ? cwd_config : home_config
|
93
|
+
end
|
94
|
+
|
95
|
+
def get(setting)
|
96
|
+
setting = setting.to_s.downcase
|
97
|
+
primary_config[setting]
|
98
|
+
end
|
99
|
+
|
100
|
+
def set(setting, value, persist = true, options={})
|
101
|
+
setting = setting.to_s.downcase
|
102
|
+
primary_config[setting] = value
|
103
|
+
save! if persist == true
|
104
|
+
value
|
105
|
+
end
|
106
|
+
|
107
|
+
def apply_all(options={})
|
108
|
+
current.merge!(options)
|
109
|
+
end
|
110
|
+
|
111
|
+
def unset(setting, persist = true)
|
112
|
+
primary_config.delete(setting)
|
113
|
+
save! if persist == true
|
114
|
+
end
|
115
|
+
|
116
|
+
def defaults
|
117
|
+
DefaultSettings.dup
|
118
|
+
end
|
119
|
+
|
120
|
+
def current(using_environment = true)
|
121
|
+
@current ||= calculate_config(using_environment)
|
122
|
+
end
|
123
|
+
|
124
|
+
def calculate_config(using_environment = true)
|
125
|
+
@current = defaults.merge(home_config.merge(cwd_config.merge(applied_config))).to_mash
|
126
|
+
|
127
|
+
(defaults.keys + home_config.keys + cwd_config.keys).uniq.each do |key|
|
128
|
+
upper = key.to_s.upcase
|
129
|
+
if ENV[upper]
|
130
|
+
@current[key] = ENV[upper]
|
131
|
+
end
|
132
|
+
end if using_environment
|
133
|
+
|
134
|
+
@current
|
135
|
+
end
|
136
|
+
|
137
|
+
def apply_config(hash={})
|
138
|
+
applied_config.merge!(hash)
|
139
|
+
current.merge(applied_config)
|
140
|
+
end
|
141
|
+
|
142
|
+
def apply_config_from_path(path)
|
143
|
+
path = Pathname(path)
|
144
|
+
parsed = JSON.parse(path.read) rescue {}
|
145
|
+
applied_config.merge!(parsed)
|
146
|
+
nil
|
147
|
+
end
|
148
|
+
|
149
|
+
def save!
|
150
|
+
save_home_config
|
151
|
+
save_cwd_config
|
152
|
+
@current = nil
|
153
|
+
true
|
154
|
+
end
|
155
|
+
|
156
|
+
def save_cwd_config
|
157
|
+
return nil unless cwd_config_path.exist?
|
158
|
+
|
159
|
+
File.open(cwd_config_path, 'w+') do |fh|
|
160
|
+
fh.write JSON.generate(cwd_config.to_hash)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def save_home_config
|
165
|
+
File.open(home_config_path, 'w+') do |fh|
|
166
|
+
fh.write JSON.generate(home_config.to_hash)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# Applied config is configuration values passed in context
|
171
|
+
# usually from the cli, but also in the unit tests
|
172
|
+
def applied_config
|
173
|
+
@applied_config ||= {}
|
174
|
+
end
|
175
|
+
|
176
|
+
def cwd_config
|
177
|
+
@cwd_config ||= begin
|
178
|
+
(cwd_config_path.exist? rescue false) ? JSON.parse(cwd_config_path.read) : {}
|
179
|
+
rescue
|
180
|
+
{}
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def home_config
|
185
|
+
initialize! unless home_config_path.exist?
|
186
|
+
|
187
|
+
@home_config ||= begin
|
188
|
+
(home_config_path.exist? rescue false) ? JSON.parse(home_config_path.read) : {}
|
189
|
+
rescue
|
190
|
+
{}
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def home_config_path= value
|
195
|
+
@home_config_path = Pathname(value)
|
196
|
+
end
|
197
|
+
|
198
|
+
def home_config_path
|
199
|
+
@home_config_path || Pathname(ENV['HOME']).join(".datapimp", manifest_filename)
|
200
|
+
end
|
201
|
+
|
202
|
+
def cwd_config_path= value
|
203
|
+
@cwd_config_path = Pathname(value)
|
204
|
+
end
|
205
|
+
|
206
|
+
def cwd_config_path
|
207
|
+
@cwd_config_path || Pathname(Datapimp.pwd).join(manifest_filename)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# The `Datapimp::Dataources` module houses the various
|
2
|
+
# types of remote data stores we are reading and converting into
|
3
|
+
# a JSON array of objects that gets cached on our filesystem.
|
4
|
+
module Datapimp
|
5
|
+
module DataSources
|
6
|
+
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
Dir[Datapimp.lib.join("datapimp/data_sources/**/*.rb")].each {|f| require(f) }
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Datapimp
|
2
|
+
module Sync
|
3
|
+
class DropboxDelta
|
4
|
+
|
5
|
+
attr_accessor :client,
|
6
|
+
:data,
|
7
|
+
:cursor,
|
8
|
+
:entries,
|
9
|
+
:path_prefix
|
10
|
+
|
11
|
+
def initialize(client, cursor, path_prefix=nil)
|
12
|
+
@client = client
|
13
|
+
@cursor = cursor
|
14
|
+
@path_prefix = path_prefix
|
15
|
+
end
|
16
|
+
|
17
|
+
def processed!
|
18
|
+
# TODO
|
19
|
+
# Should update cursor
|
20
|
+
end
|
21
|
+
|
22
|
+
def entries
|
23
|
+
return @entries if @entries
|
24
|
+
fetch
|
25
|
+
@entries
|
26
|
+
end
|
27
|
+
|
28
|
+
def _dropbox_delta at=nil
|
29
|
+
at ||= cursor
|
30
|
+
response = client.delta(at, path_prefix)
|
31
|
+
self.cursor = response["cursor"]
|
32
|
+
response
|
33
|
+
end
|
34
|
+
|
35
|
+
def data
|
36
|
+
@data ||= fetch
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_reset path_prefix, cursor
|
40
|
+
end
|
41
|
+
|
42
|
+
def fetch
|
43
|
+
return @response if @response
|
44
|
+
|
45
|
+
response = _dropbox_delta
|
46
|
+
|
47
|
+
if response["reset"] == true
|
48
|
+
on_reset(path_prefix, cursor)
|
49
|
+
end
|
50
|
+
|
51
|
+
self.entries = {}.to_mash
|
52
|
+
|
53
|
+
response["entries"].each do |entry|
|
54
|
+
path, meta = entry
|
55
|
+
self.entries[path] = meta
|
56
|
+
end
|
57
|
+
|
58
|
+
if response["has_more"] == true
|
59
|
+
# TODO Implement
|
60
|
+
end
|
61
|
+
|
62
|
+
@response = response
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# The `Datapimp::Sync` module will delegate to the underlying service layer
|
2
|
+
# which we are pushing or pulling files and data from. It will wrap the client
|
3
|
+
# implementation we are using.
|
4
|
+
module Datapimp
|
5
|
+
module Sync
|
6
|
+
def self.data_source_types
|
7
|
+
%w(dropbox amazon github google json excel nokogiri)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.amazon(options={})
|
11
|
+
require 'datapimp/clients/amazon'
|
12
|
+
Datapimp::Clients::Amazon.client(options)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.dropbox(options={})
|
16
|
+
require 'datapimp/clients/dropbox'
|
17
|
+
Datapimp::Clients::Dropbox.client(options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.github(options={})
|
21
|
+
require 'datapimp/clients/github'
|
22
|
+
Datapimp::Clients::Github.client(options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.google(options={})
|
26
|
+
require 'datapimp/clients/google'
|
27
|
+
Datapimp::Clients::Google.client(options)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/datapimp/version.rb
CHANGED
data/lib/datapimp.rb
CHANGED
@@ -1,5 +1,33 @@
|
|
1
|
-
require
|
1
|
+
require 'ostruct'
|
2
|
+
require 'set'
|
3
|
+
require 'pathname'
|
4
|
+
require 'hashie'
|
5
|
+
require 'datapimp/core_ext'
|
2
6
|
|
3
7
|
module Datapimp
|
4
|
-
|
8
|
+
def self.config
|
9
|
+
Datapimp::Configuration.instance
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.pwd
|
13
|
+
Pathname(ENV.fetch('DATAPIMP_PWD') { Dir.pwd })
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.lib
|
17
|
+
Pathname(File.dirname(__FILE__))
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.method_missing(meth, *args, &block)
|
21
|
+
case
|
22
|
+
when %w(dropbox amazon github google).include?(meth.to_s)
|
23
|
+
Datapimp::Sync.send(meth, *args, &block)
|
24
|
+
else
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
5
28
|
end
|
29
|
+
|
30
|
+
require 'datapimp/version'
|
31
|
+
require 'datapimp/configuration'
|
32
|
+
require 'datapimp/data_sources'
|
33
|
+
require 'datapimp/sync'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
export DATAPIMP_PWD=$PWD
|
4
|
+
set -e
|
5
|
+
|
6
|
+
TARGET_FILE=$0
|
7
|
+
|
8
|
+
cd `dirname $TARGET_FILE`
|
9
|
+
TARGET_FILE=`basename $TARGET_FILE`
|
10
|
+
|
11
|
+
# Iterate down a (possible) chain of symlinks
|
12
|
+
while [ -L "$TARGET_FILE" ]
|
13
|
+
do
|
14
|
+
TARGET_FILE=`readlink $TARGET_FILE`
|
15
|
+
cd `dirname $TARGET_FILE`
|
16
|
+
TARGET_FILE=`basename $TARGET_FILE`
|
17
|
+
done
|
18
|
+
|
19
|
+
# Compute the canonicalized name by finding the physical path
|
20
|
+
# for the directory we're in and appending the target file.
|
21
|
+
PHYS_DIR=`pwd -P`
|
22
|
+
RESULT=$PHYS_DIR/$TARGET_FILE
|
23
|
+
|
24
|
+
# Figure out where this script is located.
|
25
|
+
SELFDIR=$(dirname "$RESULT")
|
26
|
+
|
27
|
+
# Tell Bundler where the Gemfile and gems are.
|
28
|
+
export BUNDLE_GEMFILE="$SELFDIR/lib/app/Gemfile"
|
29
|
+
unset BUNDLE_IGNORE_CONFIG
|
30
|
+
|
31
|
+
# Run the actual app using the bundled Ruby interpreter.
|
32
|
+
exec "$SELFDIR/lib/ruby/bin/ruby" -rbundler/setup "$SELFDIR/lib/app/bin/datapimp" "$@"
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rack/test'
|
2
|
+
require 'pry'
|
3
|
+
require 'datapimp'
|
4
|
+
|
5
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
6
|
+
|
7
|
+
module Datapimp
|
8
|
+
def self.spec_root
|
9
|
+
Pathname(File.dirname(__FILE__))
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.dummy_path
|
13
|
+
spec_root.join("dummy")
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.fixtures_path
|
17
|
+
spec_root.join("support","fixtures")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
Skypager::Site.directory = {}
|
22
|
+
|
23
|
+
RSpec.configure do |config|
|
24
|
+
config.mock_with :rspec
|
25
|
+
config.order = :random
|
26
|
+
|
27
|
+
config.include Rack::Test
|
28
|
+
config.include Requests::JsonHelpers, type: :request
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Distribution
|
2
|
+
class << self
|
3
|
+
attr_accessor :configuration
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.configure
|
7
|
+
self.configuration ||= Configuration.new
|
8
|
+
yield configuration
|
9
|
+
end
|
10
|
+
|
11
|
+
class Configuration
|
12
|
+
attr_accessor :package_name, :packaging_dir, :version, :rb_version,
|
13
|
+
:native_extensions
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Dir[File.join(Dir.pwd, 'tasks', '**', '*.rb')].each { |f| require f }
|
2
|
+
|
3
|
+
module Distribution
|
4
|
+
class Executable
|
5
|
+
include PackageHelpers
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
attr_reader :package
|
9
|
+
|
10
|
+
def_delegators :@package, :dir, :package_name
|
11
|
+
|
12
|
+
def initialize(package)
|
13
|
+
@package = package
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.create(package)
|
17
|
+
executable = new(package)
|
18
|
+
executable.copy_wrapper
|
19
|
+
executable
|
20
|
+
end
|
21
|
+
|
22
|
+
def copy_wrapper
|
23
|
+
print_to_console 'Creating exexutable...'
|
24
|
+
|
25
|
+
FileUtils.cp 'packaging/wrapper.sh', "#{dir}/#{package_name}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
Dir[File.join(Dir.pwd, 'tasks', '**', '*.rb')].each { |f| require f }
|
5
|
+
|
6
|
+
module Distribution
|
7
|
+
class Package
|
8
|
+
extend Forwardable
|
9
|
+
include PackageHelpers
|
10
|
+
|
11
|
+
attr_reader :config, :dir, :tarball, :package, :arch, :root
|
12
|
+
|
13
|
+
def_delegators :@config, :version, :rb_version, :package_name,
|
14
|
+
:packaging_dir, :native_extensions
|
15
|
+
|
16
|
+
def initialize(arch)
|
17
|
+
abort 'Ruby 2.1.x required' if RUBY_VERSION !~ /^2\.1\./
|
18
|
+
|
19
|
+
@arch = arch
|
20
|
+
@config = ::Distribution.configuration
|
21
|
+
@dir = "#{package_name}-#{version}-#{arch}"
|
22
|
+
@package = self
|
23
|
+
@root = File.expand_path '.'
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.create(args)
|
27
|
+
new(*args).build
|
28
|
+
end
|
29
|
+
|
30
|
+
def build
|
31
|
+
initialize_install_dir
|
32
|
+
copy_datapimp
|
33
|
+
install_ruby_and_gems
|
34
|
+
create_executable
|
35
|
+
post_cleanup
|
36
|
+
@tarball = create_tarball
|
37
|
+
clean_dir
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def clean_dir
|
43
|
+
FileUtils.cd root do
|
44
|
+
FileUtils.remove_dir(dir, true) if Dir.exist? dir
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def post_cleanup
|
49
|
+
print_to_console 'Cleaning up...'
|
50
|
+
|
51
|
+
files = ["#{packaging_dir}/traveling-ruby-#{rb_version}-#{arch}.tar.gz"]
|
52
|
+
|
53
|
+
files.each { |file| FileUtils.rm file if File.exist? file }
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_tarball
|
57
|
+
Tarball.new self
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_executable
|
61
|
+
Executable.create self
|
62
|
+
end
|
63
|
+
|
64
|
+
def install_ruby_and_gems
|
65
|
+
TravellingRuby.install self
|
66
|
+
end
|
67
|
+
|
68
|
+
def initialize_install_dir
|
69
|
+
clean_dir
|
70
|
+
|
71
|
+
FileUtils.cd root do
|
72
|
+
FileUtils.mkdir_p "#{dir}/lib/app"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def copy_datapimp
|
77
|
+
print_to_console 'Copying datapimp...'
|
78
|
+
|
79
|
+
%w(datapimp.gemspec Gemfile Gemfile.lock lib bin)
|
80
|
+
.each do |folder|
|
81
|
+
FileUtils.cp_r File.join(root, folder), "#{dir}/lib/app"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
Dir[File.join(Dir.pwd, 'tasks', '**', '*.rb')].each { |f| require f }
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
require 'octokit'
|
5
|
+
require 'pathname'
|
6
|
+
|
7
|
+
module Distribution
|
8
|
+
class Release
|
9
|
+
extend Forwardable
|
10
|
+
include PackageHelpers
|
11
|
+
|
12
|
+
attr_reader :tarball, :github, :package
|
13
|
+
|
14
|
+
def_delegators :@tarball, :package, :version, :file
|
15
|
+
|
16
|
+
def initialize(tarball)
|
17
|
+
@tarball = tarball
|
18
|
+
@github = Octokit::Client.new access_token: ENV['OCTODOWN_TOKEN']
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.create(tarball)
|
22
|
+
release = new(tarball)
|
23
|
+
release.create_new_release
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_new_release
|
27
|
+
print_to_console 'Publishing release to GitHub...'
|
28
|
+
github.create_release(
|
29
|
+
'datapimp/datapimp',
|
30
|
+
"v#{version}",
|
31
|
+
name: "v#{version}",
|
32
|
+
body: ReleaseNotes.new.content
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def upload_asset
|
37
|
+
print_to_console 'Uploading to GitHub...'
|
38
|
+
github.upload_asset find_upload_url, file
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def find_upload_url
|
44
|
+
Octokit.releases('datapimp/datapimp').find do |n|
|
45
|
+
n.tag_name == "v#{version}"
|
46
|
+
end[:url]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|