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 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
- def terminate(message)
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(1)
18
+ exit(status)
12
19
  end
13
20
 
14
- def success(message)
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(0)
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
- file = current_path.join(args.first)
19
- terminate "Hmm, no file in #{file}" unless file.file?
18
+ files = Pathname.glob(args).select(&:file?)
19
+ terminate "Hmm, no files found!" if files.empty?
20
20
 
21
21
  authenticate!
22
- vault = current_vault(options)
23
- response = conn.post("/vaults/#{vault}/gems", :params => { "rubygem[file]" => file.open('rb') })
24
- success "#{response['original_name']} was successfully added to vault '#{vault}'."
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
@@ -39,6 +39,7 @@ command :"gems:add" do |c|
39
39
  c.option '--vault VAULT', 'Specify a vault'
40
40
  c.when_called Gemical::Commands::Gems, :create
41
41
  end
42
+ alias_command :push, :'gems:add'
42
43
 
43
44
  command :"gems:remove" do |c|
44
45
  c.syntax = 'gemical gems:remove GEM VERSION [options]'
data/lib/gemical/vault.rb CHANGED
@@ -2,6 +2,8 @@ class Gemical::Vault < String
2
2
 
3
3
  attr_reader :token
4
4
 
5
+ # Constructor
6
+ # @param [Hash] with "token" and "name" keys
5
7
  def initialize(hash)
6
8
  @token = hash["token"]
7
9
  super hash["name"]
@@ -2,7 +2,7 @@ module Gemical
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 0
5
- TINY = 2
5
+ TINY = 3
6
6
  PRE = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
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.2
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-11-12 00:00:00.000000000 Z
12
+ date: 2011-12-15 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: commander
16
- requirement: &14809440 !ruby/object:Gem::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: *14809440
24
+ version_requirements: *7740460
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rest-client
27
- requirement: &14808980 !ruby/object:Gem::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: *14808980
35
+ version_requirements: *7739960
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: multi_json
38
- requirement: &14808520 !ruby/object:Gem::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: *14808520
46
+ version_requirements: *7739400
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
- requirement: &14808080 !ruby/object:Gem::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: *14808080
57
+ version_requirements: *7738640
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rspec
60
- requirement: &14807560 !ruby/object:Gem::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: *14807560
68
+ version_requirements: *7737920
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: webmock
71
- requirement: &14807060 !ruby/object:Gem::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: *14807060
79
+ version_requirements: *7737140
80
80
  description: Manage your private Gems through the command line.
81
81
  email: info@blacksquaremedia.com
82
82
  executables: