gemfury 0.1.1 → 0.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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
-