dears3 0.0.2
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/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +64 -0
- data/Rakefile +2 -0
- data/bin/s3 +11 -0
- data/dears3.gemspec +27 -0
- data/lib/dears3/auth.rb +64 -0
- data/lib/dears3/cli/s3.rb +39 -0
- data/lib/dears3/client.rb +101 -0
- data/lib/dears3/version.rb +3 -0
- data/lib/dears3.rb +17 -0
- metadata +139 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 74c3e62a041513e6f02777553a05aca66865bc9e
|
4
|
+
data.tar.gz: 18d8a01ef03ea76d1fa403afc4d69160bac6b911
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8df8690ad22ddfd2368f7702a69e8ff045369ae0c9fb968085c01a74e982ed677dff16b0e17e37401fd64d4da5f731582c1aedf48205c5d57833a8f7ccde8da4
|
7
|
+
data.tar.gz: 9cef82454ec4703e74bd468285ebc69d7a4f17b34241927e1caebfb3bc3ff0debf12911902ddfc4c610eab4c17ae9fcdccdda312fbd6540cbf33b6b45e87c138
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Simon Chaffetz
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# DearS3
|
2
|
+
|
3
|
+
Command line tools to mirror your current directory in an AWS bucket.
|
4
|
+
|
5
|
+
## Set up
|
6
|
+
|
7
|
+
**Installation**
|
8
|
+
|
9
|
+
Run `gem install dears3` from the command line. Only works on *NIX systems.
|
10
|
+
|
11
|
+
**AWS Credentials**
|
12
|
+
|
13
|
+
This CLI will look in your home directory for a file called ".aws.json"
|
14
|
+
that contains the JSON string of your AWS credentials.
|
15
|
+
|
16
|
+
```json
|
17
|
+
{
|
18
|
+
"access_key_id": "YOUR_ACCESS_KEY_ID",
|
19
|
+
"secret_access_key": "YOUR_SECRET_ACCESS_KEY"
|
20
|
+
}
|
21
|
+
```
|
22
|
+
|
23
|
+
To get these credentials, log into your [AWS S3 console][s3 console], click on your name in
|
24
|
+
the navigation menu and open "Security Credentials". See [here][credentials docs] for more details.
|
25
|
+
|
26
|
+
[s3 console]: https://console.aws.amazon.com/s3
|
27
|
+
[credentials docs]: http://docs.aws.amazon.com/general/latest/gr/aws-security-credentials.html
|
28
|
+
|
29
|
+
## Tasks
|
30
|
+
|
31
|
+
**s3 auth**
|
32
|
+
|
33
|
+
Prompts you for your AWS credentials and stores them in your home
|
34
|
+
directory in a file called ".aws.json".
|
35
|
+
|
36
|
+
**s3 upload**
|
37
|
+
|
38
|
+
Uploads every file in the current directory and its subdirectories to an AWS
|
39
|
+
bucket. Any file beginning with "." is ignored. It syncs to arbitary levels of
|
40
|
+
nesting so be careful with symlinks that could cause an infinite loop.
|
41
|
+
|
42
|
+
The bucket will take the name of the current directory, replacing underscores
|
43
|
+
with dashes. Note that the bucket's name must conform with DNS requirements if
|
44
|
+
you plan on publishing it as a website.
|
45
|
+
|
46
|
+
*Caution: If a bucket with that name already exists and contains files with the
|
47
|
+
same names as the files in your directory, those files will be overriden without
|
48
|
+
warning.*
|
49
|
+
|
50
|
+
Run `s3 upload --publish` to publish your uploaded files as a website.
|
51
|
+
|
52
|
+
**s3 publish**
|
53
|
+
|
54
|
+
Publishes the current directory as a website. Directory must already be uploaded
|
55
|
+
to s3. Run `s3 publish --off` to roll back.
|
56
|
+
|
57
|
+
|
58
|
+
## Contributing
|
59
|
+
|
60
|
+
1. Fork it ( https://github.com/[my-github-username]/dears3/fork )
|
61
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
62
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
63
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
64
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/s3
ADDED
data/dears3.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dears3/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dears3"
|
8
|
+
spec.version = DearS3::VERSION
|
9
|
+
spec.authors = ["7imon7ays"]
|
10
|
+
spec.homepage = "https://github.com/7imon7ays/DearS3"
|
11
|
+
spec.summary = %q{Sync an S3 bucket with your current directory.}
|
12
|
+
spec.license = "MIT"
|
13
|
+
|
14
|
+
spec.files = `git ls-files -z`.split("\x0")
|
15
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_dependency "aws-sdk", "~> 1.59.x"
|
20
|
+
spec.add_dependency "oj", "~> 2.x"
|
21
|
+
spec.add_dependency "thor", "~> 0.19.x"
|
22
|
+
spec.add_dependency "mime-types", "2.4.3"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
end
|
27
|
+
|
data/lib/dears3/auth.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
require 'oj'
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
class DearS3::Auth
|
6
|
+
include ::Thor::Shell
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@credentials = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
# TODO: Give option to upload once without storing credentials.
|
13
|
+
def connect
|
14
|
+
begin
|
15
|
+
return ::AWS::S3.new aws_credentials
|
16
|
+
rescue Errno::ENOENT
|
17
|
+
say "Credentials file not found. Please run 's3:auth' to authenticate.", :red
|
18
|
+
abort
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def authenticate
|
23
|
+
if confirm_create_credentials_file?
|
24
|
+
request_credentials
|
25
|
+
create_credentials_file!
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def aws_credentials
|
32
|
+
::Oj.load File.read credentials_path
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_credentials_file!
|
36
|
+
File.open credentials_path, "w" do |f|
|
37
|
+
f.write @credentials.to_json
|
38
|
+
f.write "\n"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def request_credentials
|
43
|
+
@credentials[:access_key_id] = ask "Please enter your AWS access key id:"
|
44
|
+
@credentials[:secret_access_key] = ask(
|
45
|
+
"Please enter your AWS secret access key:",
|
46
|
+
echo: false
|
47
|
+
)
|
48
|
+
say
|
49
|
+
end
|
50
|
+
|
51
|
+
def credentials_path
|
52
|
+
File.expand_path "~/.aws.json"
|
53
|
+
end
|
54
|
+
|
55
|
+
def confirm_create_credentials_file?
|
56
|
+
if File.exists? credentials_path
|
57
|
+
override = ask "Override existing '.aws.json' file? (y/n):"
|
58
|
+
override == "y"
|
59
|
+
else
|
60
|
+
true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module DearS3
|
4
|
+
class Cli
|
5
|
+
class S3 < Thor
|
6
|
+
desc "upload", "Deploy current and nested directories to S3"
|
7
|
+
option :publish, type: :boolean, default: false # Optionally publish to the web
|
8
|
+
def upload
|
9
|
+
s3_upload = open_connection
|
10
|
+
|
11
|
+
s3_upload.sync "."
|
12
|
+
s3_upload.configure_website if options[:publish]
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "publish", "Publish bucket as a website"
|
16
|
+
option :off, type: :boolean, default: false
|
17
|
+
def publish
|
18
|
+
s3_upload = open_connection
|
19
|
+
options[:off] ?
|
20
|
+
s3_upload.remove_website : s3_upload.configure_website
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "auth", "Save auth credentials in home directory"
|
24
|
+
def auth
|
25
|
+
s3_auth = DearS3::Auth.new
|
26
|
+
s3_auth.authenticate
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def open_connection
|
32
|
+
s3_auth = DearS3::Auth.new
|
33
|
+
s3_connection = s3_auth.connect
|
34
|
+
DearS3::Client.new s3_connection
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
require 'thor'
|
3
|
+
require 'digest/md5'
|
4
|
+
require 'mime/types'
|
5
|
+
|
6
|
+
class DearS3::Client
|
7
|
+
include ::Thor::Shell
|
8
|
+
|
9
|
+
def initialize s3_connection
|
10
|
+
@s3 = s3_connection
|
11
|
+
@bucket = nil
|
12
|
+
|
13
|
+
set_bucket
|
14
|
+
end
|
15
|
+
|
16
|
+
def sync path
|
17
|
+
say "Uploading files to bucket '#{ bucket.name }'."
|
18
|
+
walk_and_upload path
|
19
|
+
say "Done syncing bucket."
|
20
|
+
end
|
21
|
+
|
22
|
+
def configure_website
|
23
|
+
files = bucket.objects.map { |obj| obj.key }
|
24
|
+
say "Files currently in your bucket:"
|
25
|
+
say files.join(" | "), :green
|
26
|
+
index_doc = ask "Pick your bucket's index document:"
|
27
|
+
error_doc = ask "Pick your bucket's error document:"
|
28
|
+
say "Publishing your bucket. This may take a while..."
|
29
|
+
bucket.configure_website do |cfg|
|
30
|
+
cfg.index_document_suffix = index_doc
|
31
|
+
cfg.error_document_key = error_doc # TODO: Make this optional
|
32
|
+
end
|
33
|
+
say "Bucket published at #{ bucket.url }."
|
34
|
+
end
|
35
|
+
|
36
|
+
def remove_website
|
37
|
+
bucket.remove_website_configuration
|
38
|
+
say "Removed #{ bucket.name } from the web."
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
attr_accessor :bucket
|
44
|
+
attr_reader :s3
|
45
|
+
|
46
|
+
def set_bucket
|
47
|
+
# TODO: Optionally configure bucket name and enforce DNS requirements
|
48
|
+
# see https://forums.aws.amazon.com/thread.jspa?messageID=570880
|
49
|
+
bucket_name = File.basename(Dir.getwd).gsub '_', '-'
|
50
|
+
self.bucket = s3.buckets[bucket_name]
|
51
|
+
|
52
|
+
unless bucket.exists?
|
53
|
+
say "Creating bucket '#{ bucket.name }'"
|
54
|
+
s3.buckets.create(bucket.name, acl: :bucket_owner_full_control)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def walk_and_upload path
|
59
|
+
entries = Dir.entries path
|
60
|
+
entries.each do |entry|
|
61
|
+
next if entry == File.basename(__FILE__) || entry[0] == '.'
|
62
|
+
nested_entry = (path == "." ? entry : "#{ path }/#{ entry }")
|
63
|
+
if File.directory? nested_entry
|
64
|
+
walk_and_upload nested_entry
|
65
|
+
next
|
66
|
+
else
|
67
|
+
upload nested_entry
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def upload entry
|
73
|
+
new_object = bucket.objects[entry]
|
74
|
+
|
75
|
+
begin
|
76
|
+
if new_object.exists?
|
77
|
+
# Strip opening and closing "\" chars from AWS-formatted etag
|
78
|
+
etag_is_same = new_object.etag[1..-2] == ::Digest::MD5.hexdigest(File.read entry)
|
79
|
+
|
80
|
+
if etag_is_same
|
81
|
+
say "\tUnchanged: #{ entry }", :blue
|
82
|
+
return
|
83
|
+
else
|
84
|
+
# TODO: Confirm overriding files
|
85
|
+
say "\tUpdating: '#{ entry }'", :yellow
|
86
|
+
end
|
87
|
+
else
|
88
|
+
say "\tUploading: '#{ entry }'", :green
|
89
|
+
end
|
90
|
+
content_type = ::MIME::Types.type_for(entry).to_s
|
91
|
+
new_object.write File.open entry, content_type: content_type
|
92
|
+
rescue ::AWS::S3::Errors::Forbidden
|
93
|
+
say "Access denied!", :red
|
94
|
+
say "Make sure your credentials are correct and your bucket name isn't already taken by someone else."
|
95
|
+
say "Note: AWS bucket names are shared across all users."
|
96
|
+
say
|
97
|
+
abort
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
data/lib/dears3.rb
ADDED
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dears3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- 7imon7ays
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.59.x
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.59.x
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: oj
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.x
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.x
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.19.x
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.19.x
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mime-types
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.4.3
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.4.3
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.6'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.6'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description:
|
98
|
+
email:
|
99
|
+
executables:
|
100
|
+
- s3
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- Gemfile
|
105
|
+
- LICENSE.txt
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- bin/s3
|
109
|
+
- dears3.gemspec
|
110
|
+
- lib/dears3.rb
|
111
|
+
- lib/dears3/auth.rb
|
112
|
+
- lib/dears3/cli/s3.rb
|
113
|
+
- lib/dears3/client.rb
|
114
|
+
- lib/dears3/version.rb
|
115
|
+
homepage: https://github.com/7imon7ays/DearS3
|
116
|
+
licenses:
|
117
|
+
- MIT
|
118
|
+
metadata: {}
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
requirements: []
|
134
|
+
rubyforge_project:
|
135
|
+
rubygems_version: 2.2.2
|
136
|
+
signing_key:
|
137
|
+
specification_version: 4
|
138
|
+
summary: Sync an S3 bucket with your current directory.
|
139
|
+
test_files: []
|