gemical 0.0.2 → 0.0.3
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/lib/gemical/auth.rb +27 -0
- data/lib/gemical/commands/base.rb +31 -4
- data/lib/gemical/commands/gems.rb +15 -5
- data/lib/gemical/configuration.rb +14 -0
- data/lib/gemical/import.rb +1 -0
- data/lib/gemical/vault.rb +2 -0
- data/lib/gemical/version.rb +1 -1
- metadata +14 -14
data/lib/gemical/auth.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
class Gemical::Auth
|
2
2
|
include Gemical::Singleton
|
3
3
|
|
4
|
+
# @return [Gemical::Configuration]
|
5
|
+
# The configuration
|
4
6
|
def configuration
|
5
7
|
Gemical.configuration
|
6
8
|
end
|
7
9
|
|
10
|
+
# Verifies account, asks for credentials if not setup
|
11
|
+
# @return [Hash]
|
12
|
+
# Account information
|
8
13
|
def verify_account!
|
9
14
|
@verified_account ||= if credentials
|
10
15
|
get_account
|
@@ -15,6 +20,9 @@ class Gemical::Auth
|
|
15
20
|
end
|
16
21
|
end
|
17
22
|
|
23
|
+
# Verifies account, asks for primary choice if not setup
|
24
|
+
# @return [Hash]
|
25
|
+
# Vault information
|
18
26
|
def verify_vault!
|
19
27
|
verify_account!
|
20
28
|
|
@@ -25,6 +33,8 @@ class Gemical::Auth
|
|
25
33
|
end
|
26
34
|
end
|
27
35
|
|
36
|
+
# @return [Array<Gemical::Vault>]
|
37
|
+
# Available vaults
|
28
38
|
def vaults
|
29
39
|
verify_account!
|
30
40
|
@vaults ||= Gemical.connection.get("/vaults").map do |hash|
|
@@ -32,16 +42,22 @@ class Gemical::Auth
|
|
32
42
|
end
|
33
43
|
end
|
34
44
|
|
45
|
+
# @return [[String, String]]
|
46
|
+
# Username and password
|
35
47
|
def credentials
|
36
48
|
return nil unless configuration.credentials?
|
37
49
|
pair = configuration.credentials.read.split(/\s+/)[0..1]
|
38
50
|
pair if pair.size == 2 && pair.all? {|v| string_value?(v) }
|
39
51
|
end
|
40
52
|
|
53
|
+
# @return [Array]
|
54
|
+
# Basic authentication credentials, for API request
|
41
55
|
def basic_auth
|
42
56
|
[credentials.last, 'x'] if credentials
|
43
57
|
end
|
44
58
|
|
59
|
+
# @return [String]
|
60
|
+
# The user's primary vault setting
|
45
61
|
def primary_vault
|
46
62
|
return nil unless configuration.primary_vault?
|
47
63
|
value = configuration.primary_vault.read.split(/\s+/).first
|
@@ -50,12 +66,18 @@ class Gemical::Auth
|
|
50
66
|
|
51
67
|
private
|
52
68
|
|
69
|
+
# @return [Hash]
|
70
|
+
# Retrieved account info from the API
|
53
71
|
def get_account
|
54
72
|
Gemical.connection.get("/account")
|
55
73
|
rescue Gemical::Connection::HTTPUnauthorized
|
56
74
|
renew_credentials?
|
57
75
|
end
|
58
76
|
|
77
|
+
# Collects user credentials and tries to retrieve account information
|
78
|
+
# from the API
|
79
|
+
# @return [Hash]
|
80
|
+
# Retrieved account info from the API
|
59
81
|
def collect_credentials(attempt = 1)
|
60
82
|
email = ask('Email: ')
|
61
83
|
pass = password
|
@@ -76,6 +98,7 @@ class Gemical::Auth
|
|
76
98
|
end
|
77
99
|
end
|
78
100
|
|
101
|
+
# Asks the user if he wants to renew credentials
|
79
102
|
def renew_credentials?
|
80
103
|
say_warning "\nYour stored credentials seem to be outdated."
|
81
104
|
if agree("Do you want to re-authenticate your account? ")
|
@@ -86,11 +109,13 @@ class Gemical::Auth
|
|
86
109
|
end
|
87
110
|
end
|
88
111
|
|
112
|
+
# Fetch vault
|
89
113
|
def get_vault(name)
|
90
114
|
ensure_vaults!
|
91
115
|
vaults.find {|v| v == name }
|
92
116
|
end
|
93
117
|
|
118
|
+
# Collect user's preference about primary vault
|
94
119
|
def collect_vault(message, save = true)
|
95
120
|
ensure_vaults!
|
96
121
|
say_warning "\n#{message}"
|
@@ -99,6 +124,7 @@ class Gemical::Auth
|
|
99
124
|
get_vault(name)
|
100
125
|
end
|
101
126
|
|
127
|
+
# Ensure user has vaults, or exit
|
102
128
|
def ensure_vaults!
|
103
129
|
return unless vaults.empty?
|
104
130
|
say_error "You have no vaults associated with your account."
|
@@ -106,6 +132,7 @@ class Gemical::Auth
|
|
106
132
|
exit(1)
|
107
133
|
end
|
108
134
|
|
135
|
+
# @return [Boolean] true, if the value is a non-empty string
|
109
136
|
def string_value?(value)
|
110
137
|
value.is_a?(String) && !value.strip.empty?
|
111
138
|
end
|
@@ -2,20 +2,39 @@ class Gemical::Commands::Base
|
|
2
2
|
|
3
3
|
protected
|
4
4
|
|
5
|
+
# @return [Pathname]
|
6
|
+
# The current working path
|
5
7
|
def current_path
|
6
8
|
@current_path ||= Pathname.new(File.expand_path('.'))
|
7
9
|
end
|
8
10
|
|
9
|
-
|
11
|
+
# Output error message and exit
|
12
|
+
# @param [String] message
|
13
|
+
# Message to be printed in the console as an error
|
14
|
+
# @param [Integer] status
|
15
|
+
# Exit status, defaults to 1
|
16
|
+
def terminate(message, status = 1)
|
10
17
|
say_error message
|
11
|
-
exit(
|
18
|
+
exit(status)
|
12
19
|
end
|
13
20
|
|
14
|
-
|
21
|
+
# Output success message and exit
|
22
|
+
# @param [String] message
|
23
|
+
# Message to be printed to the console
|
24
|
+
# @param [Integer] status
|
25
|
+
# Exit status, defaults to 0
|
26
|
+
def success(message, status = 0)
|
15
27
|
say_ok message
|
16
|
-
exit(
|
28
|
+
exit(status)
|
17
29
|
end
|
18
30
|
|
31
|
+
# Expands API errors to messages
|
32
|
+
# @param [Array] errors
|
33
|
+
# Original errors
|
34
|
+
# @param [Hash] mappings
|
35
|
+
# Message mapptings
|
36
|
+
# @return [String]
|
37
|
+
# Full error messages
|
19
38
|
def full_errors(errors, mappings = {})
|
20
39
|
errors.map do |attr, messages|
|
21
40
|
name = mappings[attr] || attr
|
@@ -25,18 +44,26 @@ class Gemical::Commands::Base
|
|
25
44
|
end.join(', ')
|
26
45
|
end
|
27
46
|
|
47
|
+
# Authenticate the user
|
28
48
|
def authenticate!
|
29
49
|
Gemical.auth.verify_account!
|
30
50
|
end
|
31
51
|
|
52
|
+
# Connection accessor
|
32
53
|
def conn
|
33
54
|
Gemical.connection
|
34
55
|
end
|
35
56
|
|
57
|
+
# @param [Commander::Command::Options]
|
58
|
+
# The parsed command line options
|
59
|
+
# @return [String]
|
60
|
+
# The current vault name
|
36
61
|
def current_vault(options)
|
37
62
|
options.vault || primary_vault
|
38
63
|
end
|
39
64
|
|
65
|
+
# @return [String]
|
66
|
+
# The user's primary name
|
40
67
|
def primary_vault
|
41
68
|
Gemical.auth.verify_vault!
|
42
69
|
end
|
@@ -15,13 +15,14 @@ class Gemical::Commands::Gems < Gemical::Commands::Base
|
|
15
15
|
def create(args, options)
|
16
16
|
terminate "Please provide a GEM file." unless args.first.is_a?(String)
|
17
17
|
|
18
|
-
|
19
|
-
terminate "Hmm, no
|
18
|
+
files = Pathname.glob(args).select(&:file?)
|
19
|
+
terminate "Hmm, no files found!" if files.empty?
|
20
20
|
|
21
21
|
authenticate!
|
22
|
-
vault
|
23
|
-
|
24
|
-
|
22
|
+
vault = current_vault(options)
|
23
|
+
files.each do |file|
|
24
|
+
upload(file, vault)
|
25
|
+
end
|
25
26
|
rescue Gemical::Connection::HTTPNotFound
|
26
27
|
terminate "Sorry, no such vault '#{vault}'."
|
27
28
|
rescue Gemical::Connection::HTTPUnprocessable => e
|
@@ -43,4 +44,13 @@ class Gemical::Commands::Gems < Gemical::Commands::Base
|
|
43
44
|
"Sorry, #{full_errors(e.response)}"
|
44
45
|
end
|
45
46
|
|
47
|
+
private
|
48
|
+
|
49
|
+
def upload(file, vault)
|
50
|
+
res = conn.post("/vaults/#{vault}/gems", :params => { "rubygem[file]" => file.open('rb') })
|
51
|
+
say_ok "#{res['original_name']} was successfully added to vault '#{vault}'."
|
52
|
+
rescue Gemical::Connection::HTTPUnprocessable => e
|
53
|
+
say_error "Sorry, #{full_errors(e.response, 'name' => 'gem')} (#{file.basename})"
|
54
|
+
end
|
55
|
+
|
46
56
|
end
|
@@ -9,36 +9,48 @@ class Gemical::Configuration
|
|
9
9
|
@home = ENV['HOME']
|
10
10
|
end
|
11
11
|
|
12
|
+
# @return [Pathname] credentials store
|
12
13
|
def root
|
13
14
|
@root ||= Pathname.new File.join(@home, ".gemical")
|
14
15
|
end
|
15
16
|
|
17
|
+
# @return [Pathname] credentials storage file
|
16
18
|
def credentials
|
17
19
|
root.join('credentials')
|
18
20
|
end
|
19
21
|
|
22
|
+
# @return [Pathname] primary vault storage file
|
20
23
|
def primary_vault
|
21
24
|
root.join('primary_vault')
|
22
25
|
end
|
23
26
|
|
27
|
+
# @return [Boolean] true, if configuration root exists
|
24
28
|
def root?
|
25
29
|
root.directory? && root.readable?
|
26
30
|
end
|
27
31
|
|
32
|
+
# @return [Boolean] true, if credentials are available
|
28
33
|
def credentials?
|
29
34
|
readable_file? credentials
|
30
35
|
end
|
31
36
|
|
37
|
+
# @return [Boolean] true, if primary vault is available
|
32
38
|
def primary_vault?
|
33
39
|
readable_file? primary_vault
|
34
40
|
end
|
35
41
|
|
42
|
+
# Create a configuration root directory
|
36
43
|
def create_root!
|
37
44
|
return if root?
|
38
45
|
FileUtils.mkdir_p root
|
39
46
|
FileUtils.chmod_R 0700, root
|
40
47
|
end
|
41
48
|
|
49
|
+
# Write a file
|
50
|
+
# @param [Symbol] symbol
|
51
|
+
# Either :credentials or :primary_vault
|
52
|
+
# @param [Array] lines
|
53
|
+
# Lines to write
|
42
54
|
def write!(symbol, *lines)
|
43
55
|
create_root!
|
44
56
|
send(symbol).open "w", 0600 do |file|
|
@@ -48,6 +60,8 @@ class Gemical::Configuration
|
|
48
60
|
|
49
61
|
private
|
50
62
|
|
63
|
+
# @param [Pathname] path
|
64
|
+
# @return [Boolean] true, if file is readable
|
51
65
|
def readable_file?(path)
|
52
66
|
root? && path.file? && path.readable?
|
53
67
|
end
|
data/lib/gemical/import.rb
CHANGED
data/lib/gemical/vault.rb
CHANGED
data/lib/gemical/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gemical
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-12-15 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: commander
|
16
|
-
requirement: &
|
16
|
+
requirement: &7740460 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *7740460
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rest-client
|
27
|
-
requirement: &
|
27
|
+
requirement: &7739960 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *7739960
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: multi_json
|
38
|
-
requirement: &
|
38
|
+
requirement: &7739400 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *7739400
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
|
-
requirement: &
|
49
|
+
requirement: &7738640 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *7738640
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rspec
|
60
|
-
requirement: &
|
60
|
+
requirement: &7737920 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *7737920
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: webmock
|
71
|
-
requirement: &
|
71
|
+
requirement: &7737140 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *7737140
|
80
80
|
description: Manage your private Gems through the command line.
|
81
81
|
email: info@blacksquaremedia.com
|
82
82
|
executables:
|