jaxx 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.
- data/.gitignore +1 -0
- data/Guardfile +5 -0
- data/bin/jaxx-download +5 -0
- data/bin/jaxx-upload +5 -0
- data/features/download.feature +26 -0
- data/features/step_definitions/global_steps.rb +16 -0
- data/features/support/env.rb +20 -0
- data/features/upload.feature +31 -0
- data/jaxx.gemspec +3 -0
- data/lib/jaxx/cli.rb +32 -0
- data/lib/jaxx/download.rb +26 -0
- data/lib/jaxx/environment.rb +16 -5
- data/lib/jaxx/process.rb +89 -0
- data/lib/jaxx/upload.rb +21 -0
- data/lib/jaxx/version.rb +1 -1
- data/lib/jaxx.rb +15 -3
- data/spec/helpers/service.rb +2 -0
- data/spec/lib/jaxx/download_spec.rb +24 -0
- data/spec/lib/jaxx/{transaction_spec.rb → process_spec.rb} +22 -29
- data/spec/lib/jaxx/upload_spec.rb +23 -0
- data/spec/lib/jaxx_spec.rb +12 -8
- data/spec/spec_helper.rb +5 -4
- metadata +74 -9
- data/bin/jaxx +0 -18
- data/lib/jaxx/transaction.rb +0 -85
data/.gitignore
CHANGED
data/Guardfile
CHANGED
@@ -7,3 +7,8 @@ guard 'rspec' do
|
|
7
7
|
watch('spec/spec_helper.rb') { "spec" }
|
8
8
|
end
|
9
9
|
|
10
|
+
guard 'cucumber' do
|
11
|
+
watch(%r{^features/.+\.feature$})
|
12
|
+
watch(%r{^features/support/.+$}) { 'features' }
|
13
|
+
watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
|
14
|
+
end
|
data/bin/jaxx-download
ADDED
data/bin/jaxx-upload
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Feature: As a CLI user I want to download a file from S3
|
2
|
+
|
3
|
+
Scenario: Show CLI help with -h
|
4
|
+
When I run `jaxx-download -h`
|
5
|
+
Then the exit status should be 0
|
6
|
+
And the output should contain "jaxx [options]"
|
7
|
+
|
8
|
+
Scenario: Show CLI help with --help
|
9
|
+
When I run `jaxx-download --help`
|
10
|
+
Then the exit status should be 0
|
11
|
+
And the output should contain "jaxx [options]"
|
12
|
+
|
13
|
+
Scenario: Downloading a single file with missing bucket
|
14
|
+
When I run `jaxx-download --bucket `
|
15
|
+
Then the exit status should be 1
|
16
|
+
And the output should contain "bucket is required"
|
17
|
+
|
18
|
+
Scenario: Downloading a single file with missing credentials
|
19
|
+
When I run `jaxx-download --bucket foo`
|
20
|
+
Then the exit status should be 1
|
21
|
+
And the output should contain "credentials for access key and access secret required"
|
22
|
+
|
23
|
+
Scenario: Downloading a single file with missing file argument
|
24
|
+
When I run `jaxx-download --bucket foo`
|
25
|
+
Then the exit status should be 1
|
26
|
+
And the output should contain "file presence is required"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Given /^the local authentication resource is available$/ do
|
2
|
+
stub_credentials_service
|
3
|
+
Fog.mock!
|
4
|
+
end
|
5
|
+
|
6
|
+
Then /^the access key and access secret should not be empty$/ do
|
7
|
+
Jaxx.environment.credentials[:access_key].should_not be_empty
|
8
|
+
Jaxx.environment.credentials[:access_secret].should_not be_empty
|
9
|
+
end
|
10
|
+
|
11
|
+
Given /^the file "(.*?)" exists$/ do |f|
|
12
|
+
File.open f, 'w+'
|
13
|
+
end
|
14
|
+
|
15
|
+
Then /^the file should be uploaded$/ do
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
$:.unshift File.expand_path('../../../bin', __FILE__)
|
5
|
+
$:.unshift File.expand_path('../../../lib', __FILE__)
|
6
|
+
|
7
|
+
require 'jaxx'
|
8
|
+
require 'cucumber'
|
9
|
+
require 'aruba'
|
10
|
+
require 'aruba/cucumber'
|
11
|
+
require 'rspec'
|
12
|
+
require 'rspec/core'
|
13
|
+
require 'cucumber/rspec/doubles'
|
14
|
+
require File.expand_path('../../../spec/helpers/service', __FILE__)
|
15
|
+
|
16
|
+
World(ServiceHelper)
|
17
|
+
|
18
|
+
Before do
|
19
|
+
@aruba_timeout_seconds = 5
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Feature: As a CLI user I want to upload a file to S3
|
2
|
+
|
3
|
+
Scenario: Show CLI help with -h
|
4
|
+
When I run `jaxx-upload -h`
|
5
|
+
Then the exit status should be 0
|
6
|
+
And the output should contain "jaxx [options]"
|
7
|
+
|
8
|
+
Scenario: Show CLI help with --help
|
9
|
+
When I run `jaxx-upload --help`
|
10
|
+
Then the exit status should be 0
|
11
|
+
And the output should contain "jaxx [options]"
|
12
|
+
|
13
|
+
Scenario: Uploading a single file with missing bucket
|
14
|
+
When I run `jaxx-upload --bucket `
|
15
|
+
Then the exit status should be 1
|
16
|
+
And the output should contain "bucket is required"
|
17
|
+
|
18
|
+
Scenario: Uploading a single file non-existing file
|
19
|
+
When I run `jaxx-upload --file foo.txt`
|
20
|
+
Then the exit status should be 1
|
21
|
+
And the output should contain "file exists returned false"
|
22
|
+
|
23
|
+
Scenario: Uploading a single file with missing file
|
24
|
+
When I run `jaxx-upload --file`
|
25
|
+
Then the exit status should be 1
|
26
|
+
And the output should contain "file presence is required"
|
27
|
+
|
28
|
+
Scenario: Downloading a single file with missing credentials
|
29
|
+
When I run `jaxx-upload --bucket foo`
|
30
|
+
Then the exit status should be 1
|
31
|
+
And the output should contain "credentials for access key and access secret required"
|
data/jaxx.gemspec
CHANGED
@@ -21,4 +21,7 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.add_development_dependency 'guard-rspec'
|
22
22
|
gem.add_development_dependency 'rspec'
|
23
23
|
gem.add_development_dependency 'fakeweb'
|
24
|
+
gem.add_development_dependency 'cucumber'
|
25
|
+
gem.add_development_dependency 'aruba'
|
26
|
+
gem.add_development_dependency 'guard-cucumber'
|
24
27
|
end
|
data/lib/jaxx/cli.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'jaxx'
|
3
|
+
|
4
|
+
module Jaxx
|
5
|
+
module CLI
|
6
|
+
|
7
|
+
def self.execute meth, args
|
8
|
+
parser.parse!(args)
|
9
|
+
options.empty? ? (STDOUT.write(parser) and exit) : Jaxx.send(meth, options)
|
10
|
+
rescue RuntimeError => exc
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.parser
|
15
|
+
OptionParser.new do |o|
|
16
|
+
o.banner = "jaxx [options]"
|
17
|
+
|
18
|
+
o.on('-b', '--bucket [BUCKET]') { |b| options['bucket'] = b }
|
19
|
+
o.on('-k', '--access-key [ACCESS_KEY]') { |k| options['access_key'] = k }
|
20
|
+
o.on('-s', '--access-secret [ACCESS_SECRET]') { |s| options['access_secret'] = s }
|
21
|
+
o.on('-f', '--file [FILE]') { |f| options['file'] = f }
|
22
|
+
o.on('-p', '--privacy [PRIVACY]') { |p| options['privacy'] = p }
|
23
|
+
o.on('-h', '--help') { puts o }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.options
|
28
|
+
@options ||= {}
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'jaxx/process'
|
2
|
+
|
3
|
+
module Jaxx
|
4
|
+
class Download
|
5
|
+
|
6
|
+
attr_reader :process
|
7
|
+
|
8
|
+
def initialize args = {}
|
9
|
+
@process = Process.new(args)
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute
|
13
|
+
process.start do |storage|
|
14
|
+
directory = storage.directories.get(process.bucket)
|
15
|
+
File.open(File.basename(process.file), 'wb') do |file|
|
16
|
+
directory.files.get(process.file) do |chunk, byt_remain, byt_total|
|
17
|
+
file.write(chunk)
|
18
|
+
complete = (((byt_total-byt_remain).to_f/byt_total) * 100)
|
19
|
+
Jaxx.logger.info "Saving file: %.2f percent complete.\r" % complete
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
data/lib/jaxx/environment.rb
CHANGED
@@ -9,7 +9,7 @@ module Jaxx
|
|
9
9
|
DEFAULT_ARGS = {
|
10
10
|
'service_domain' => '169.254.169.254',
|
11
11
|
'service_path' => '/latest/meta-data/iam/security-credentials/default',
|
12
|
-
'service_timeout' =>
|
12
|
+
'service_timeout' => 1
|
13
13
|
}
|
14
14
|
|
15
15
|
attr_reader :service_domain, :service_path, :service_timeout
|
@@ -25,12 +25,23 @@ module Jaxx
|
|
25
25
|
def credentials
|
26
26
|
return @credentials unless @credentials.nil?
|
27
27
|
|
28
|
+
response = credential_response
|
29
|
+
|
30
|
+
@credentials = {
|
31
|
+
:access_key => response['AccessKeyId'],
|
32
|
+
:access_secret => response['SecretAccessKey'],
|
33
|
+
:code => response['Code']
|
34
|
+
}
|
35
|
+
rescue Errno::EHOSTDOWN, Errno::EHOSTUNREACH, Timeout::Error => exc
|
36
|
+
@credentials = { :access_key => nil, :access_secret => nil, :code => 'Failure' }
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def credential_response
|
28
42
|
http = Net::HTTP.new service_domain
|
29
43
|
http.open_timeout = http.read_timeout = service_timeout
|
30
|
-
|
31
|
-
@credentials = { :access_key => resp['AccessKeyId'], :access_secret => resp['SecretAccessKey'], :code => resp['Code'] }
|
32
|
-
rescue Errno::EHOSTDOWN, Errno::EHOSTUNREACH, Timeout::Error
|
33
|
-
@credentials = { :access_key => nil, :access_secret => nil, :code => 'Failure' }
|
44
|
+
JSON.parse http.get(service_path).body
|
34
45
|
end
|
35
46
|
end
|
36
47
|
end
|
data/lib/jaxx/process.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'fog'
|
2
|
+
|
3
|
+
module Jaxx
|
4
|
+
class Process
|
5
|
+
|
6
|
+
PRIVACIES = %w[public private]
|
7
|
+
|
8
|
+
attr_reader :bucket, :access_key, :access_secret, :file, :privacy, :validations
|
9
|
+
|
10
|
+
def initialize args = {}
|
11
|
+
@bucket, @access_key, @access_secret, @file, @privacy = args.values_at 'bucket', 'access_key', 'access_secret', 'file', 'privacy', 'validations'
|
12
|
+
@validations = [:bucket, :credentials, :file_presence] + (args['validations'] || [])
|
13
|
+
end
|
14
|
+
|
15
|
+
def privacy
|
16
|
+
@privacy || 'private'
|
17
|
+
end
|
18
|
+
|
19
|
+
def private?
|
20
|
+
privacy.to_s == 'private'
|
21
|
+
end
|
22
|
+
|
23
|
+
def public?
|
24
|
+
!private?
|
25
|
+
end
|
26
|
+
|
27
|
+
def credentials
|
28
|
+
return @credentials unless @credentials.nil?
|
29
|
+
|
30
|
+
key, secret = access_key.to_s, access_secret.to_s
|
31
|
+
if (key.empty? or secret.empty?) and Jaxx.environment.ami?
|
32
|
+
key, secret = Jaxx.environment.credentials.values_at :access_key, :access_secret
|
33
|
+
end
|
34
|
+
@credentials = { access_key: key, access_secret: secret }
|
35
|
+
end
|
36
|
+
|
37
|
+
def start &block
|
38
|
+
errs = errors
|
39
|
+
|
40
|
+
["Unable to process transaction", format_errors(errs)].flatten.each do |msg|
|
41
|
+
Jaxx.logger.warn msg
|
42
|
+
end and raise(RuntimeError) unless errs.empty?
|
43
|
+
|
44
|
+
block.call(storage)
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate
|
48
|
+
validations.inject({}) do |hsh, name|
|
49
|
+
validation = send("validate_#{name}")
|
50
|
+
hsh[name] = validation unless validation.nil?
|
51
|
+
hsh
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
alias :errors :validate
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def storage
|
60
|
+
@storage ||= Fog::Storage::AWS.new :aws_access_key_id => credentials[:access_key],
|
61
|
+
:aws_secret_access_key => credentials[:access_secret],
|
62
|
+
:use_iam_profile => Jaxx.environment.ami?
|
63
|
+
end
|
64
|
+
|
65
|
+
def validate_bucket
|
66
|
+
"is required" if bucket.to_s.empty?
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate_file_presence
|
70
|
+
"is required" if file.to_s.empty?
|
71
|
+
end
|
72
|
+
|
73
|
+
def validate_file_exists
|
74
|
+
"returned false" unless File.exist?(file.to_s)
|
75
|
+
end
|
76
|
+
|
77
|
+
def validate_credentials
|
78
|
+
"for access key and access secret required" if credentials[:access_key].empty? or credentials[:access_secret].empty?
|
79
|
+
end
|
80
|
+
|
81
|
+
def validate_privacy
|
82
|
+
"#{privacy} is not supported" unless PRIVACIES.include?(privacy.to_s)
|
83
|
+
end
|
84
|
+
|
85
|
+
def format_errors(errs)
|
86
|
+
errs.collect {|name, msg| [name.to_s.gsub(/_/, ' '), msg].join(' ') }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/jaxx/upload.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'jaxx/process'
|
2
|
+
|
3
|
+
module Jaxx
|
4
|
+
class Upload
|
5
|
+
|
6
|
+
attr_reader :process
|
7
|
+
|
8
|
+
def initialize args = {}
|
9
|
+
@process = Process.new(args.merge('validations' => [:privacy, :file_exists]))
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute
|
13
|
+
process.start do |storage|
|
14
|
+
directory = storage.directories.get(process.bucket)
|
15
|
+
directory ||= storage.directories.create(:key => process.bucket, :public => process.public?)
|
16
|
+
directory.files.create(:key => File.basename(process.file), :body => File.read(process.file), :public => process.public?)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/lib/jaxx/version.rb
CHANGED
data/lib/jaxx.rb
CHANGED
@@ -1,14 +1,26 @@
|
|
1
1
|
require "jaxx/version"
|
2
|
-
require "jaxx/transaction"
|
3
2
|
require "jaxx/environment"
|
3
|
+
require "jaxx/upload"
|
4
|
+
require "jaxx/download"
|
5
|
+
require "logger"
|
4
6
|
|
5
7
|
module Jaxx
|
6
8
|
|
7
|
-
def self.
|
8
|
-
Jaxx::
|
9
|
+
def self.upload args = {}
|
10
|
+
Jaxx::Upload.new(args).execute
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.download args = {}
|
14
|
+
Jaxx::Download.new(args).execute
|
9
15
|
end
|
10
16
|
|
11
17
|
def self.environment
|
12
18
|
@environment ||= Environment.new
|
13
19
|
end
|
20
|
+
|
21
|
+
def self.logger log = nil
|
22
|
+
@logger = log if log
|
23
|
+
@logger ||= Logger.new(STDOUT)
|
24
|
+
@logger
|
25
|
+
end
|
14
26
|
end
|
data/spec/helpers/service.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fog/aws/models/storage/directories'
|
3
|
+
|
4
|
+
module Jaxx
|
5
|
+
describe Download do
|
6
|
+
|
7
|
+
describe "#process" do
|
8
|
+
let(:args) { ({ 'access_key' => 'foo', 'access_secret' => 'bar', 'file' => File.expand_path('bar.txt', __FILE__), 'bucket' => 'temp' }) }
|
9
|
+
|
10
|
+
subject { described_class.new(args) }
|
11
|
+
|
12
|
+
it "sends file to storage" do
|
13
|
+
Fog.mock!
|
14
|
+
|
15
|
+
directory = double('directory', :files => double('files'))
|
16
|
+
directory.files.should_receive(:get).with(args['file'])
|
17
|
+
Fog::Storage::AWS::Directories.any_instance.stub(:get).with(args['bucket']).and_return(directory)
|
18
|
+
|
19
|
+
subject.execute
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -2,10 +2,10 @@ require 'spec_helper'
|
|
2
2
|
require 'fog/aws/models/storage/directory'
|
3
3
|
|
4
4
|
module Jaxx
|
5
|
-
describe
|
5
|
+
describe Process do
|
6
6
|
|
7
7
|
it "raises RuntimeError on invalid process" do
|
8
|
-
-> { described_class.new.
|
8
|
+
-> { described_class.new.start }.should raise_error(RuntimeError)
|
9
9
|
end
|
10
10
|
|
11
11
|
it "accepts bucket" do
|
@@ -32,31 +32,39 @@ module Jaxx
|
|
32
32
|
end
|
33
33
|
|
34
34
|
context "passing a file path" do
|
35
|
-
|
35
|
+
let(:file) { nil }
|
36
|
+
|
37
|
+
subject { described_class.new('file' => file) }
|
38
|
+
|
36
39
|
it "raises error on missing file" do
|
37
|
-
|
40
|
+
subject.errors.should include(:file_presence => "is required")
|
38
41
|
end
|
39
42
|
|
40
43
|
it "includes error when file does not exist" do
|
41
44
|
file = "foo"
|
42
|
-
|
45
|
+
subject.errors.should include(:file_presence => "is required")
|
43
46
|
end
|
44
47
|
|
45
48
|
it "includes error when path is empty" do
|
46
|
-
|
49
|
+
file = ""
|
50
|
+
subject.errors.should include(:file_presence => "is required")
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|
50
|
-
|
51
|
-
described_class.new('privacy' => 'private').privacy.should == 'private'
|
52
|
-
end
|
54
|
+
describe "privacy" do
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
-
|
56
|
+
it "accepts privacy level" do
|
57
|
+
described_class.new('privacy' => 'public', 'validations' => [:privacy]).privacy.should == 'public'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "defaults privacy level to private" do
|
61
|
+
described_class.new('validations' => [:privacy]).privacy.should == 'private'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "raises error on invalid privacy level" do
|
65
|
+
described_class.new('privacy' => 'foo', 'validations' => [:privacy]).errors.should include(:privacy => "foo is not supported")
|
66
|
+
end
|
57
67
|
|
58
|
-
it "raises error on invalid privacy level" do
|
59
|
-
described_class.new('privacy' => 'foo').errors.should include(:privacy => "foo is not supported")
|
60
68
|
end
|
61
69
|
|
62
70
|
context "non-ami environment" do
|
@@ -85,20 +93,5 @@ module Jaxx
|
|
85
93
|
end
|
86
94
|
end
|
87
95
|
|
88
|
-
describe "#process" do
|
89
|
-
let(:args) { ({ 'access_key' => 'foo', 'access_secret' => 'bar', 'file' => File.expand_path('bar.txt', __FILE__), 'bucket' => 'temp' }) }
|
90
|
-
|
91
|
-
subject { described_class.new(args) }
|
92
|
-
|
93
|
-
it "sends file to storage" do
|
94
|
-
Fog.mock!
|
95
|
-
|
96
|
-
File.stub(:exist?).with(args['file']).and_return(true)
|
97
|
-
File.should_receive(:read).with(args['file']).and_return("")
|
98
|
-
File.should_receive(:basename).with(args['file']).and_return('bar.txt')
|
99
|
-
|
100
|
-
subject.process
|
101
|
-
end
|
102
|
-
end
|
103
96
|
end
|
104
97
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jaxx
|
4
|
+
describe Upload do
|
5
|
+
|
6
|
+
describe "#process" do
|
7
|
+
let(:args) { ({ 'access_key' => 'foo', 'access_secret' => 'bar', 'file' => File.expand_path('bar.txt', __FILE__), 'bucket' => 'temp' }) }
|
8
|
+
|
9
|
+
subject { described_class.new(args) }
|
10
|
+
|
11
|
+
it "sends file to storage" do
|
12
|
+
Fog.mock!
|
13
|
+
|
14
|
+
File.stub(:exist?).with(args['file']).and_return(true)
|
15
|
+
File.should_receive(:read).with(args['file']).and_return("")
|
16
|
+
File.should_receive(:basename).with(args['file']).and_return('bar.txt')
|
17
|
+
|
18
|
+
subject.execute
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/spec/lib/jaxx_spec.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Jaxx do
|
4
|
+
|
5
|
+
it ".upload" do
|
6
|
+
upload = double 'upload'
|
7
|
+
Jaxx::Upload.should_receive(:new).and_return(upload)
|
8
|
+
upload.should_receive(:execute)
|
9
|
+
Jaxx.upload
|
10
|
+
end
|
4
11
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
Jaxx.save
|
11
|
-
end
|
12
|
-
|
12
|
+
it ".upload" do
|
13
|
+
download = double 'download'
|
14
|
+
Jaxx::Download.should_receive(:new).and_return(download)
|
15
|
+
download.should_receive(:execute)
|
16
|
+
Jaxx.download
|
13
17
|
end
|
14
18
|
|
15
19
|
describe ".environment" do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'bundler/setup'
|
3
|
-
|
3
|
+
|
4
4
|
$:.unshift File.expand_path('../lib', __FILE__)
|
5
5
|
require 'jaxx'
|
6
|
+
require 'rspec'
|
6
7
|
|
7
8
|
require_relative 'helpers/service'
|
8
9
|
|
10
|
+
Jaxx.logger Logger.new('log/test.log')
|
11
|
+
|
9
12
|
RSpec.configure do |c|
|
10
13
|
c.include ServiceHelper
|
11
|
-
c.after(:each)
|
12
|
-
FakeWeb.clean_registry
|
13
|
-
end
|
14
|
+
c.after(:each) { FakeWeb.clean_registry }
|
14
15
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jaxx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fog
|
@@ -107,11 +107,60 @@ dependencies:
|
|
107
107
|
- - ! '>='
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: cucumber
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: aruba
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: guard-cucumber
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
110
158
|
description: Command line wrapper for pushing files to S3
|
111
159
|
email:
|
112
160
|
- marcky.sharky@googlemail.com
|
113
161
|
executables:
|
114
|
-
- jaxx
|
162
|
+
- jaxx-download
|
163
|
+
- jaxx-upload
|
115
164
|
extensions: []
|
116
165
|
extra_rdoc_files: []
|
117
166
|
files:
|
@@ -122,15 +171,25 @@ files:
|
|
122
171
|
- LICENSE
|
123
172
|
- README.md
|
124
173
|
- Rakefile
|
125
|
-
- bin/jaxx
|
174
|
+
- bin/jaxx-download
|
175
|
+
- bin/jaxx-upload
|
176
|
+
- features/download.feature
|
177
|
+
- features/step_definitions/global_steps.rb
|
178
|
+
- features/support/env.rb
|
179
|
+
- features/upload.feature
|
126
180
|
- jaxx.gemspec
|
127
181
|
- lib/jaxx.rb
|
182
|
+
- lib/jaxx/cli.rb
|
183
|
+
- lib/jaxx/download.rb
|
128
184
|
- lib/jaxx/environment.rb
|
129
|
-
- lib/jaxx/
|
185
|
+
- lib/jaxx/process.rb
|
186
|
+
- lib/jaxx/upload.rb
|
130
187
|
- lib/jaxx/version.rb
|
131
188
|
- spec/helpers/service.rb
|
189
|
+
- spec/lib/jaxx/download_spec.rb
|
132
190
|
- spec/lib/jaxx/environment_spec.rb
|
133
|
-
- spec/lib/jaxx/
|
191
|
+
- spec/lib/jaxx/process_spec.rb
|
192
|
+
- spec/lib/jaxx/upload_spec.rb
|
134
193
|
- spec/lib/jaxx_spec.rb
|
135
194
|
- spec/spec_helper.rb
|
136
195
|
homepage: https://github.com/marckysharky/jaxx
|
@@ -147,7 +206,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
206
|
version: '0'
|
148
207
|
segments:
|
149
208
|
- 0
|
150
|
-
hash: -
|
209
|
+
hash: -522064426156595131
|
151
210
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
211
|
none: false
|
153
212
|
requirements:
|
@@ -156,7 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
215
|
version: '0'
|
157
216
|
segments:
|
158
217
|
- 0
|
159
|
-
hash: -
|
218
|
+
hash: -522064426156595131
|
160
219
|
requirements: []
|
161
220
|
rubyforge_project:
|
162
221
|
rubygems_version: 1.8.24
|
@@ -164,8 +223,14 @@ signing_key:
|
|
164
223
|
specification_version: 3
|
165
224
|
summary: RubyGems to allow any file to be pushed to S3 in the simplist way
|
166
225
|
test_files:
|
226
|
+
- features/download.feature
|
227
|
+
- features/step_definitions/global_steps.rb
|
228
|
+
- features/support/env.rb
|
229
|
+
- features/upload.feature
|
167
230
|
- spec/helpers/service.rb
|
231
|
+
- spec/lib/jaxx/download_spec.rb
|
168
232
|
- spec/lib/jaxx/environment_spec.rb
|
169
|
-
- spec/lib/jaxx/
|
233
|
+
- spec/lib/jaxx/process_spec.rb
|
234
|
+
- spec/lib/jaxx/upload_spec.rb
|
170
235
|
- spec/lib/jaxx_spec.rb
|
171
236
|
- spec/spec_helper.rb
|
data/bin/jaxx
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
require 'optparse'
|
4
|
-
$:.unshift File.expand_path('../../lib', __FILE__)
|
5
|
-
opts = {}
|
6
|
-
OptionParser.new do |o|
|
7
|
-
o.banner = "Jaxx file distributor: jaxx [options]"
|
8
|
-
|
9
|
-
o.on('-b', '--bucket BUCKET') { |b| opts['bucket'] = b }
|
10
|
-
o.on('-k', '--access-key [ACCESS_KEY]') { |k| opts['access_key'] = k }
|
11
|
-
o.on('-s', '--access-secret [ACCESS_SECRET]') { |s| opts['access_secret'] = s }
|
12
|
-
o.on('-f', '--file FILE') { |f| opts['file'] = f }
|
13
|
-
o.on('-p', '--privacy [PRIVACY]') { |p| opts['privacy'] = p }
|
14
|
-
o.on('-h', '--help') { puts o; exit }
|
15
|
-
end.parse!
|
16
|
-
|
17
|
-
require 'jaxx'
|
18
|
-
Jaxx.save(opts)
|
data/lib/jaxx/transaction.rb
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
require 'fog'
|
2
|
-
|
3
|
-
module Jaxx
|
4
|
-
|
5
|
-
class Transaction
|
6
|
-
|
7
|
-
PRIVACIES = %w[public private]
|
8
|
-
|
9
|
-
attr_reader :bucket, :access_key, :access_secret, :file, :privacy
|
10
|
-
|
11
|
-
def initialize args = {}
|
12
|
-
@bucket, @access_key, @access_secret, @file, @privacy = args.values_at 'bucket', 'access_key', 'access_secret', 'file', 'privacy'
|
13
|
-
end
|
14
|
-
|
15
|
-
def privacy
|
16
|
-
@privacy || 'private'
|
17
|
-
end
|
18
|
-
|
19
|
-
def private?
|
20
|
-
privacy.to_s == 'private'
|
21
|
-
end
|
22
|
-
|
23
|
-
def public?
|
24
|
-
!private?
|
25
|
-
end
|
26
|
-
|
27
|
-
def credentials
|
28
|
-
return @credentials unless @credentials.nil?
|
29
|
-
|
30
|
-
key, secret = access_key.to_s, access_secret.to_s
|
31
|
-
if Jaxx.environment.ami? and (key.empty? or secret.empty?)
|
32
|
-
creds = Jaxx.environment.credentials
|
33
|
-
key = creds[:access_key]
|
34
|
-
secret = creds[:access_secret]
|
35
|
-
end
|
36
|
-
@credentials = { access_key: key, access_secret: secret }
|
37
|
-
end
|
38
|
-
|
39
|
-
def process
|
40
|
-
errs = errors
|
41
|
-
if errs.empty?
|
42
|
-
remote_directory.files.create(:key => File.basename(file), :body => File.read(file), :public => public?)
|
43
|
-
else
|
44
|
-
raise RuntimeError, "Unable to process transaction: #{errs.inspect}"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def validate
|
49
|
-
err = {}
|
50
|
-
err[:bucket] = "is required" unless validate_bucket
|
51
|
-
err[:file] = "given cannot be processed" unless validate_file
|
52
|
-
err[:credentials] = "for access key and access secret required" unless validate_credentials
|
53
|
-
err[:privacy] = "#{privacy} is not supported" unless validate_privacy
|
54
|
-
err
|
55
|
-
end
|
56
|
-
|
57
|
-
alias :errors :validate
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
|
-
def remote_directory
|
62
|
-
s3 = Fog::Storage::AWS.new :aws_access_key_id => credentials[:access_key], :aws_secret_access_key => credentials[:access_secret], :use_iam_profile => Jaxx.environment.ami?
|
63
|
-
dir = s3.directories.get(bucket)
|
64
|
-
dir ||= s3.directories.create(:key => bucket, :public => public?)
|
65
|
-
dir
|
66
|
-
end
|
67
|
-
|
68
|
-
def validate_bucket
|
69
|
-
!bucket.to_s.empty?
|
70
|
-
end
|
71
|
-
|
72
|
-
def validate_file
|
73
|
-
!file.to_s.empty? and File.exist?(file.to_s)
|
74
|
-
end
|
75
|
-
|
76
|
-
def validate_credentials
|
77
|
-
!credentials[:access_key].empty? and !credentials[:access_secret].empty?
|
78
|
-
end
|
79
|
-
|
80
|
-
def validate_privacy
|
81
|
-
PRIVACIES.include?(privacy.to_s)
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
end
|