gemfury 0.1.1 → 0.2.0.beta1

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/bin/fury CHANGED
@@ -7,4 +7,4 @@ require 'rubygems'
7
7
  require 'gemfury'
8
8
  require 'gemfury/command'
9
9
 
10
- Gemfury::Command.start
10
+ Gemfury::Command::App.start
@@ -0,0 +1,34 @@
1
+ require 'faraday'
2
+
3
+ # @private
4
+ module Faraday
5
+ # @private
6
+ class Request::MultipartWithFile < Faraday::Middleware
7
+ def call(env)
8
+ if env[:body].is_a?(Hash)
9
+ env[:body].each do |key, value|
10
+ if value.is_a?(File)
11
+ env[:body][key] = Faraday::UploadIO.new(value, mime_type(value), value.path)
12
+ end
13
+ end
14
+ end
15
+
16
+ @app.call(env)
17
+ end
18
+
19
+ private
20
+
21
+ def mime_type(file)
22
+ case file.path
23
+ when /\.jpe?g/i
24
+ 'image/jpeg'
25
+ when /\.gif$/i
26
+ 'image/gif'
27
+ when /\.png$/i
28
+ 'image/png'
29
+ else
30
+ 'application/octet-stream'
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/gemfury.rb CHANGED
@@ -1,3 +1,33 @@
1
+ require 'multi_json'
2
+ require 'faraday_middleware'
3
+ require 'faraday/request/multipart_with_file'
4
+
5
+ require 'gemfury/version'
1
6
  require 'gemfury/const'
7
+ require 'gemfury/error'
2
8
  require 'gemfury/platform'
3
- require 'gemfury/client'
9
+ require 'gemfury/auth'
10
+ require 'gemfury/configuration'
11
+ require 'gemfury/client'
12
+
13
+ module Gemfury
14
+ extend Configuration
15
+ class << self
16
+ # Alias for Gemfury::Client.new
17
+ #
18
+ # @return [Gemfury::Client]
19
+ def new(options={})
20
+ Gemfury::Client.new(options)
21
+ end
22
+
23
+ # Delegate to Twitter::Client
24
+ def method_missing(method, *args, &block)
25
+ return super unless new.respond_to?(method)
26
+ new.send(method, *args, &block)
27
+ end
28
+
29
+ def respond_to?(method, include_private = false)
30
+ new.respond_to?(method, include_private) || super(method, include_private)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ module Gemfury
2
+ module Auth
3
+
4
+ private
5
+ def authenticated?
6
+ self.user_api_key && !self.user_api_key.empty?
7
+ end
8
+
9
+ def ensure_authorization!
10
+ raise Unauthorized unless authenticated?
11
+ end
12
+ end
13
+ end
@@ -1,27 +1,81 @@
1
- require 'multi_json'
2
- require 'faraday_middleware'
3
-
4
1
  module Gemfury
5
- module Client
6
- ::Faraday::Request::JSON.adapter = ::MultiJson
2
+ class Client
3
+ include Gemfury::Auth
4
+ attr_accessor *Configuration::VALID_OPTIONS_KEYS
5
+
6
+ # Creates a new API
7
+ def initialize(options={})
8
+ options = Gemfury.options.merge(options)
9
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
10
+ send("#{key}=", options[key])
11
+ end
12
+ end
13
+
14
+ # Verify gem version
15
+ def check_version
16
+ response = connection.get('status/version')
17
+ ensure_successful_response!(response)
18
+
19
+ current = Gem::Version.new(Gemfury::VERSION)
20
+ latest = Gem::Version.new(response.body['version'])
21
+
22
+ unless latest.eql?(current)
23
+ raise InvalidGemVersion.new('Please update your gem')
24
+ end
25
+ end
26
+
27
+ # Uploading a gem file
28
+ def push_gem(gem_file, options = {})
29
+ ensure_authorization!
30
+ response = connection.post('gems', options.merge(
31
+ :gem_file => gem_file
32
+ ))
33
+
34
+ ensure_successful_response!(response)
35
+ end
36
+
37
+ # Get Authentication token via email/password
38
+ def get_access_token(email, password, options = {})
39
+ response = connection.post('access_token', options.merge(
40
+ :email => email, :password => password
41
+ ))
42
+
43
+ ensure_successful_response!(response)
44
+ response.body['access_token']
45
+ end
7
46
 
8
47
  private
9
- def client(raw = false)
48
+ def connection(options = {})
10
49
  options = {
11
- :url => "http://#{Const.host}",
50
+ :url => self.endpoint,
12
51
  :ssl => { :verify => false },
13
52
  :headers => {
14
- 'Accept' => 'application/json',
15
- 'Content-Type' => 'application/json; charset=utf-8'
53
+ :accept => 'application/json',
54
+ :user_agent => user_agent
16
55
  }
17
- }
56
+ }.merge(options)
57
+
58
+ if self.user_api_key
59
+ options[:headers][:authorization] = self.user_api_key
60
+ end
18
61
 
19
62
  Faraday.new(options) do |builder|
20
- builder.use Faraday::Request::JSON
63
+ builder.use Faraday::Request::MultipartWithFile
64
+ builder.use Faraday::Request::Multipart
65
+ builder.use Faraday::Request::UrlEncoded
21
66
  #builder.use Faraday::Response::Logger
22
67
  builder.use Faraday::Response::ParseJson
23
68
  builder.adapter :net_http
24
69
  end
25
70
  end
71
+
72
+ def ensure_successful_response!(response)
73
+ unless response.success?
74
+ raise(case response.status
75
+ when 401 then Gemfury::Unauthorized
76
+ else Gemfury::Error
77
+ end)
78
+ end
79
+ end
26
80
  end
27
81
  end
@@ -1,39 +1,10 @@
1
1
  require 'thor'
2
+ require 'yaml'
2
3
  require 'launchy'
3
4
  require 'highline'
4
5
 
5
- module Gemfury
6
- class Command < Thor
7
- include Gemfury::Client
6
+ module Gemfury::Command; end
8
7
 
9
- desc "push GEM" ,"upload a new version of a gem"
10
- def push(*gems)
11
- if gems.empty?
12
- shell.say "Problem: No gems specified", :red
13
- help(:push)
14
- return
15
- end
8
+ require 'gemfury/command/authorization'
9
+ require 'gemfury/command/app'
16
10
 
17
- # Collect registration info
18
- term = HighLine.new
19
- term.say(Const.welcome)
20
- email = term.ask("Email: ") do |q|
21
- q.responses[:not_valid] = Const.email_error
22
- q.validate = Const.email_regex
23
- end
24
-
25
- # Send the registration request
26
- conn = client # From Gemfury::Client
27
- resp = conn.post('/invites.json', :invite => { :email => email })
28
-
29
- # Handle the registration
30
- if resp.success?
31
- body = resp.body
32
- term.say "Thanks! Gemfury is almost ready. Please stay tuned."
33
- Launchy.open("http://#{Const.host}/invites/#{body['slug']}")
34
- else
35
- term.say "Oops! Something went wrong. Please try again", :red
36
- end
37
- end
38
- end
39
- end
@@ -0,0 +1,36 @@
1
+ class Gemfury::Command::App < Thor
2
+ include Gemfury::Command::Authorization
3
+
4
+ desc "version" ,"Check whether the gem is up-to-date"
5
+ def version
6
+ client.check_version
7
+ end
8
+
9
+ desc "push GEM" ,"upload a new version of a gem"
10
+ def push(*gems)
11
+ with_authorization do
12
+ gem_files = gems.map do |g|
13
+ File.exists?(g) ? File.new(g) : nil
14
+ end.compact
15
+
16
+ if gem_files.empty?
17
+ shell.say "Problem: No valid gems specified", :red
18
+ help(:push)
19
+ return
20
+ end
21
+
22
+ # Let's get uploading
23
+ gem_files.each do |gem_file|
24
+ shell.say "Uploading #{File.basename(gem_file)}"
25
+ client.push_gem(gem_file)
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+ def client
32
+ options = {}
33
+ options[:user_api_key] = @user_api_key if @user_api_key
34
+ Gemfury::Client.new(options)
35
+ end
36
+ end
@@ -0,0 +1,48 @@
1
+ module Gemfury::Command::Authorization
2
+ include Gemfury::Platform
3
+
4
+ private
5
+ def with_authorization(&block)
6
+ # Load up the credentials
7
+ load_credentials!
8
+
9
+ # Attempt the operation and prompt user in case of
10
+ # lack of authorization or a 401 response from the server
11
+ begin
12
+ prompt_credentials! if @user_api_key.nil?
13
+ block.call
14
+ rescue Gemfury::Unauthorized
15
+ shell.say "Oops! Authentication failure.", :red
16
+ @user_api_key = nil
17
+ retry
18
+ end
19
+ end
20
+
21
+ def prompt_credentials!
22
+ # Prompt credentials
23
+ highline = HighLine.new
24
+ highline.say 'Please enter your Gemfury credentials.'
25
+ email = highline.ask('Email: ')
26
+ passw = highline.ask('Password: ') { |q| q.echo = false }
27
+
28
+ # Request and save the API access token
29
+ if !email.empty? && !passw.empty?
30
+ @user_api_key = client.get_access_token(email, passw)
31
+ write_credentials!
32
+ end
33
+ end
34
+
35
+ def load_credentials!
36
+ conf = read_config_file
37
+ @user_api_key = conf[:gemfury_api_key] if conf[:gemfury_api_key]
38
+ end
39
+
40
+ def write_credentials!
41
+ config = read_config_file.merge(:gemfury_api_key => @user_api_key)
42
+ File.open(config_path, 'w') { |f| f.write(YAML.dump(config)) }
43
+ end
44
+
45
+ def read_config_file
46
+ File.exist?(config_path) ? YAML.load_file(config_path) : {}
47
+ end
48
+ end
@@ -0,0 +1,54 @@
1
+ module Gemfury
2
+ # Defines constants and methods related to configuration
3
+ module Configuration
4
+ # An array of valid keys in the options hash when configuring
5
+ VALID_OPTIONS_KEYS = [
6
+ :user_api_key,
7
+ :adapter,
8
+ :endpoint,
9
+ :user_agent].freeze
10
+
11
+ # The adapter that will be used to connect if none is set
12
+ DEFAULT_ADAPTER = :net_http
13
+
14
+ # The endpoint that will be used to connect if none is set
15
+ #
16
+ DEFAULT_ENDPOINT = 'https://www.gemfury.com/1/'.freeze
17
+
18
+ # The value sent in the 'User-Agent' header if none is set
19
+ DEFAULT_USER_AGENT = "Gemfury RubyGem #{Gemfury::VERSION}".freeze
20
+
21
+ # Default user API key
22
+ DEFAULT_API_KEY = nil
23
+
24
+ # @private
25
+ attr_accessor *VALID_OPTIONS_KEYS
26
+
27
+ # When this module is extended, set all configuration options to their default values
28
+ def self.extended(base)
29
+ base.reset
30
+ end
31
+
32
+ # Convenience method to allow configuration options to be set in a block
33
+ def configure
34
+ yield self
35
+ end
36
+
37
+ # Create a hash of options and their values
38
+ def options
39
+ options = {}
40
+ VALID_OPTIONS_KEYS.each{|k| options[k] = send(k)}
41
+ options
42
+ end
43
+
44
+ # Reset all configuration options to defaults
45
+ def reset
46
+ self.user_api_key = DEFAULT_API_KEY
47
+ self.adapter = DEFAULT_ADAPTER
48
+ self.endpoint = DEFAULT_ENDPOINT
49
+ self.user_agent = DEFAULT_USER_AGENT
50
+ self
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,10 @@
1
+ module Gemfury
2
+ # Base Error class
3
+ class Error < StandardError; end
4
+
5
+ # The Gemfury gem version doesn't match the one on the server
6
+ class InvalidGemVersion < Error; end
7
+
8
+ # Client#user_api_key is not defined or Gemfury returns 401
9
+ class Unauthorized < Error; end
10
+ end
@@ -4,6 +4,10 @@ module Gemfury
4
4
  on_windows? ? ENV['USERPROFILE'] : ENV['HOME']
5
5
  end
6
6
 
7
+ def config_path
8
+ File.expand_path('.gem/gemfury', home_directory)
9
+ end
10
+
7
11
  def on_windows?
8
12
  RUBY_PLATFORM =~ /mswin32|mingw32/
9
13
  end
@@ -0,0 +1,3 @@
1
+ module Gemfury
2
+ VERSION = '0.2.0.beta1'
3
+ end
metadata CHANGED
@@ -1,182 +1,131 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: gemfury
3
- version: !ruby/object:Gem::Version
4
- hash: 25
5
- prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 1
10
- version: 0.1.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0.beta1
5
+ prerelease: 6
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Michael Rykov
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-05-17 00:00:00 -07:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2011-08-26 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: highline
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70289577678140 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
18
+ requirements:
27
19
  - - ~>
28
- - !ruby/object:Gem::Version
29
- hash: 15
30
- segments:
31
- - 1
32
- - 6
33
- - 0
20
+ - !ruby/object:Gem::Version
34
21
  version: 1.6.0
35
22
  type: :runtime
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: thor
39
23
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70289577678140
25
+ - !ruby/object:Gem::Dependency
26
+ name: thor
27
+ requirement: &70289577677540 !ruby/object:Gem::Requirement
41
28
  none: false
42
- requirements:
29
+ requirements:
43
30
  - - ~>
44
- - !ruby/object:Gem::Version
45
- hash: 45
46
- segments:
47
- - 0
48
- - 14
49
- - 5
31
+ - !ruby/object:Gem::Version
50
32
  version: 0.14.5
51
33
  type: :runtime
52
- version_requirements: *id002
53
- - !ruby/object:Gem::Dependency
54
- name: launchy
55
34
  prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *70289577677540
36
+ - !ruby/object:Gem::Dependency
37
+ name: launchy
38
+ requirement: &70289577677000 !ruby/object:Gem::Requirement
57
39
  none: false
58
- requirements:
40
+ requirements:
59
41
  - - ~>
60
- - !ruby/object:Gem::Version
61
- hash: 15
62
- segments:
63
- - 0
64
- - 4
65
- - 0
42
+ - !ruby/object:Gem::Version
66
43
  version: 0.4.0
67
44
  type: :runtime
68
- version_requirements: *id003
69
- - !ruby/object:Gem::Dependency
70
- name: multi_json
71
45
  prerelease: false
72
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *70289577677000
47
+ - !ruby/object:Gem::Dependency
48
+ name: multi_json
49
+ requirement: &70289577676460 !ruby/object:Gem::Requirement
73
50
  none: false
74
- requirements:
51
+ requirements:
75
52
  - - ~>
76
- - !ruby/object:Gem::Version
77
- hash: 19
78
- segments:
79
- - 1
80
- - 0
81
- - 2
53
+ - !ruby/object:Gem::Version
82
54
  version: 1.0.2
83
55
  type: :runtime
84
- version_requirements: *id004
85
- - !ruby/object:Gem::Dependency
86
- name: faraday
87
56
  prerelease: false
88
- requirement: &id005 !ruby/object:Gem::Requirement
57
+ version_requirements: *70289577676460
58
+ - !ruby/object:Gem::Dependency
59
+ name: faraday
60
+ requirement: &70289577675960 !ruby/object:Gem::Requirement
89
61
  none: false
90
- requirements:
62
+ requirements:
91
63
  - - ~>
92
- - !ruby/object:Gem::Version
93
- hash: 5
94
- segments:
95
- - 0
96
- - 6
97
- - 1
64
+ - !ruby/object:Gem::Version
98
65
  version: 0.6.1
99
66
  type: :runtime
100
- version_requirements: *id005
101
- - !ruby/object:Gem::Dependency
102
- name: faraday_middleware
103
67
  prerelease: false
104
- requirement: &id006 !ruby/object:Gem::Requirement
68
+ version_requirements: *70289577675960
69
+ - !ruby/object:Gem::Dependency
70
+ name: faraday_middleware
71
+ requirement: &70289577675360 !ruby/object:Gem::Requirement
105
72
  none: false
106
- requirements:
73
+ requirements:
107
74
  - - ~>
108
- - !ruby/object:Gem::Version
109
- hash: 1
110
- segments:
111
- - 0
112
- - 6
113
- - 3
75
+ - !ruby/object:Gem::Version
114
76
  version: 0.6.3
115
77
  type: :runtime
116
- version_requirements: *id006
117
- description: |
118
- Client library and command-line tool to manage your gems on http://gemfury.com
78
+ prerelease: false
79
+ version_requirements: *70289577675360
80
+ description: ! 'Client library and command-line tool to manage your gems on http://gemfury.com
119
81
 
82
+ '
120
83
  email: mrykov@gmail.com
121
- executables:
84
+ executables:
122
85
  - gemfury
123
86
  - fury
124
87
  extensions: []
125
-
126
88
  extra_rdoc_files: []
127
-
128
- files:
89
+ files:
129
90
  - README
130
91
  - bin/fury
131
92
  - bin/gemfury
93
+ - lib/faraday/request/multipart_with_file.rb
94
+ - lib/gemfury/auth.rb
132
95
  - lib/gemfury/client.rb
96
+ - lib/gemfury/command/app.rb
97
+ - lib/gemfury/command/authorization.rb
133
98
  - lib/gemfury/command.rb
99
+ - lib/gemfury/configuration.rb
134
100
  - lib/gemfury/const.rb
101
+ - lib/gemfury/error.rb
135
102
  - lib/gemfury/platform.rb
103
+ - lib/gemfury/version.rb
136
104
  - lib/gemfury.rb
137
- has_rdoc: false
138
105
  homepage: http://gemfury.com
139
106
  licenses: []
140
-
141
- post_install_message: |
142
- ************************************************************************
143
-
144
- Upload your first gem to start using Gemfury:
145
- fury push my-gem-1.0.gem
146
-
147
- Follow @gemfury on Twitter for announcements, updates, and news.
148
- https://twitter.com/gemfury
149
-
150
- ************************************************************************
151
-
107
+ post_install_message: ! "************************************************************************\n\n
108
+ \ Upload your first gem to start using Gemfury:\n fury push my-gem-1.0.gem\n\n
109
+ \ Follow @gemfury on Twitter for announcements, updates, and news.\n https://twitter.com/gemfury\n\n************************************************************************\n"
152
110
  rdoc_options: []
153
-
154
- require_paths:
111
+ require_paths:
155
112
  - lib
156
- required_ruby_version: !ruby/object:Gem::Requirement
113
+ required_ruby_version: !ruby/object:Gem::Requirement
157
114
  none: false
158
- requirements:
159
- - - ">="
160
- - !ruby/object:Gem::Version
161
- hash: 3
162
- segments:
163
- - 0
164
- version: "0"
165
- required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
120
  none: false
167
- requirements:
168
- - - ">="
169
- - !ruby/object:Gem::Version
170
- hash: 3
171
- segments:
172
- - 0
173
- version: "0"
121
+ requirements:
122
+ - - ! '>'
123
+ - !ruby/object:Gem::Version
124
+ version: 1.3.1
174
125
  requirements: []
175
-
176
126
  rubyforge_project:
177
- rubygems_version: 1.6.2
127
+ rubygems_version: 1.8.6
178
128
  signing_key:
179
129
  specification_version: 3
180
130
  summary: Client library and command-line tool to manage your gems on Gemfury
181
131
  test_files: []
182
-