Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce API version namespaces and implement Gems::V2.info #66

Merged
merged 3 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ require 'gems'
# Return some basic information about rails.
Gems.info 'rails'

# Return some basic information about rails version 7.0.6.
Gems::V2.info 'rails', '7.0.6'

# Return an array of active gems that match the query.
Gems.search 'cucumber'

Expand Down
31 changes: 11 additions & 20 deletions lib/gems.rb
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
require 'gems/abstract_client'

require 'gems/v1'
require 'gems/v2'

require 'gems/client'
require 'gems/configuration'

module Gems
extend Configuration
class << self
# Alias for Gems::Client.new
#
# @return [Gems::Client]
def new(options = {})
Gems::Client.new(options)
end

# Delegate to Gems::Client
def method_missing(method, *args, &block)
return super unless new.respond_to?(method)
new.send(method, *args, &block)
end

def respond_to?(method_name, include_private = false)
new.respond_to?(method_name, include_private) || super(method_name, include_private)
end
include AbstractClient

def respond_to_missing?(method_name, include_private = false)
new.respond_to?(method_name, include_private) || super(method_name, include_private)
end
# Alias for Gems::Client.new
#
# @return [Gems::Client]
def self.new(options = {})
Gems::Client.new(options)
end
end
27 changes: 27 additions & 0 deletions lib/gems/abstract_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module Gems
module AbstractClient
def self.included(base)
base.extend(ClassMethods)
end

module ClassMethods
def new(options = {})
raise NotImplementedError.new
end

# Delegate to Gems::Client
def method_missing(method, *args, &block)
return super unless new.respond_to?(method)
new.send(method, *args, &block)
end

def respond_to?(method_name, include_private = false)
new.respond_to?(method_name, include_private) || super(method_name, include_private)
end

def respond_to_missing?(method_name, include_private = false)
new.respond_to?(method_name, include_private) || super(method_name, include_private)
end
end
end
end
308 changes: 1 addition & 307 deletions lib/gems/client.rb
Original file line number Diff line number Diff line change
@@ -1,310 +1,4 @@
require 'date'
require 'gems/configuration'
require 'gems/request'
require 'json'

module Gems
class Client
include Gems::Request
attr_accessor(*Configuration::VALID_OPTIONS_KEYS)

def initialize(options = {})
options = Gems.options.merge(options)
Configuration::VALID_OPTIONS_KEYS.each do |key|
send("#{key}=", options[key])
end
end

# Returns some basic information about the given gem
#
# @authenticated false
# @param gem_name [String] The name of a gem.
# @return [Hash]
# @example
# Gems.info 'rails'
def info(gem_name)
response = get("/api/v1/gems/#{gem_name}.json")
JSON.parse(response)
rescue JSON::ParserError
{}
end

# Returns an array of active gems that match the query
#
# @authenticated false
# @param query [String] A term to search for.
# @param options [Hash] A customizable set of options.
# @option options [Integer] :page
# @return [Array<Hash>]
# @example
# Gems.search 'cucumber'
def search(query, options = {})
response = get('/api/v1/search.json', options.merge(:query => query))
JSON.parse(response)
end

# List all gems that you own
#
# @authenticated true
# @param user_handle [String] The handle of a user.
# @return [Array]
# @example
# Gems.gems
def gems(user_handle = nil)
response = user_handle ? get("/api/v1/owners/#{user_handle}/gems.json") : get('/api/v1/gems.json')
JSON.parse(response)
end

# Submit a gem to RubyGems.org or another host
#
# @authenticated true
# @param gem [File] A built gem.
# @param host [String] A RubyGems compatible host to use.
# @return [String]
# @example
# Gems.push File.new 'pkg/gemcutter-0.2.1.gem'
def push(gem, host = Configuration::DEFAULT_HOST)
post('/api/v1/gems', gem.read, 'application/octet-stream', host)
end

# Remove a gem from RubyGems.org's index
#
# @authenticated true
# @param gem_name [String] The name of a gem.
# @param gem_version [String] The version of a gem.
# @param options [Hash] A customizable set of options.
# @option options [String] :platform
# @return [String]
# @example
# Gems.yank "gemcutter", "0.2.1", {:platform => "x86-darwin-10"}
def yank(gem_name, gem_version = nil, options = {})
gem_version ||= info(gem_name)['version']
delete('/api/v1/gems/yank', options.merge(:gem_name => gem_name, :version => gem_version))
end

# Update a previously yanked gem back into RubyGems.org's index
#
# @authenticated true
# @param gem_name [String] The name of a gem.
# @param gem_version [String] The version of a gem.
# @param options [Hash] A customizable set of options.
# @option options [String] :platform
# @return [String]
# @example
# Gems.unyank "gemcutter", "0.2.1", {:platform => "x86-darwin-10"}
def unyank(gem_name, gem_version = nil, options = {})
gem_version ||= info(gem_name)['version']
put('/api/v1/gems/unyank', options.merge(:gem_name => gem_name, :version => gem_version))
end

# Returns an array of gem version details
#
# @authenticated false
# @param gem_name [String] The name of a gem.
# @return [Hash]
# @example
# Gems.versions 'coulda'
def versions(gem_name)
response = get("/api/v1/versions/#{gem_name}.json")
JSON.parse(response)
end

# Returns an hash of gem latest version
#
# @authenticated false
# @param gem_name [String] The name of a gem.
# @return [Hash]
# @example
# Gems.latest_version 'coulda'
def latest_version(gem_name)
response = get("/api/v1/versions/#{gem_name}/latest.json")
JSON.parse(response)
end

# Returns the total number of downloads for a particular gem
#
# @authenticated false
# @param gem_name [String] The name of a gem.
# @param gem_version [String] The version of a gem.
# @return [Hash]
# @example
# Gems.total_downloads 'rails_admin', '0.0.1'
def total_downloads(gem_name = nil, gem_version = nil)
response = gem_name ? get("/api/v1/downloads/#{gem_name}-#{gem_version || info(gem_name)['version']}.json") : get('/api/v1/downloads.json')
JSON.parse(response, :symbolize_names => true)
end

# Returns an array containing the top 50 downloaded gem versions of all time
#
# @authenticated false
# @return [Array]
# @example
# Gems.most_downloaded
def most_downloaded
response = get('/api/v1/downloads/all.json')
JSON.parse(response)['gems']
end

# Returns the number of downloads by day for a particular gem version
#
# @authenticated false
# @param gem_name [String] The name of a gem.
# @param gem_version [String] The version of a gem.
# @param from [Date] Search start date.
# @param to [Date] Search end date.
# @return [Hash]
# @example
# Gems.downloads 'coulda', '0.6.3', Date.today - 30, Date.today
def downloads(gem_name, gem_version = nil, from = nil, to = Date.today)
gem_version ||= info(gem_name)['version']
response = from ? get("/api/v1/versions/#{gem_name}-#{gem_version}/downloads/search.json", :from => from.to_s, :to => to.to_s) : get("/api/v1/versions/#{gem_name}-#{gem_version}/downloads.json")
JSON.parse(response)
end

# View all owners of a gem that you own
#
# @authenticated true
# @param gem_name [String] The name of a gem.
# @return [Array]
# @example
# Gems.owners 'gemcutter'
def owners(gem_name)
response = get("/api/v1/gems/#{gem_name}/owners.json")
JSON.parse(response)
end

# Add an owner to a RubyGem you own, giving that user permission to manage it
#
# @authenticated true
# @param gem_name [String] The name of a gem.
# @param owner [String] The email address of the user you want to add.
# @return [String]
# @example
# Gems.add_owner 'gemcutter', '[email protected]'
def add_owner(gem_name, owner)
post("/api/v1/gems/#{gem_name}/owners", :email => owner)
end

# Remove a user's permission to manage a RubyGem you own
#
# @authenticated true
# @param gem_name [String] The name of a gem.
# @param owner [String] The email address of the user you want to remove.
# @return [String]
# @example
# Gems.remove_owner 'gemcutter', '[email protected]'
def remove_owner(gem_name, owner)
delete("/api/v1/gems/#{gem_name}/owners", :email => owner)
end

# List the webhooks registered under your account
#
# @authenticated true
# @return [Hash]
# @example
# Gems.web_hooks
def web_hooks
response = get('/api/v1/web_hooks.json')
JSON.parse(response)
end

# Create a webhook
#
# @authenticated true
# @param gem_name [String] The name of a gem. Specify "*" to add the hook to all gems.
# @param url [String] The URL of the web hook.
# @return [String]
# @example
# Gems.add_web_hook 'rails', 'http://example.com'
def add_web_hook(gem_name, url)
post('/api/v1/web_hooks', :gem_name => gem_name, :url => url)
end

# Remove a webhook
#
# @authenticated true
# @param gem_name [String] The name of a gem. Specify "*" to remove the hook from all gems.
# @param url [String] The URL of the web hook.
# @return [String]
# @example
# Gems.remove_web_hook 'rails', 'http://example.com'
def remove_web_hook(gem_name, url)
delete('/api/v1/web_hooks/remove', :gem_name => gem_name, :url => url)
end

# Test fire a webhook
#
# @authenticated true
# @param gem_name [String] The name of a gem. Specify "*" to fire the hook for all gems.
# @param url [String] The URL of the web hook.
# @return [String]
# @example
# Gems.fire_web_hook 'rails', 'http://example.com'
def fire_web_hook(gem_name, url)
post('/api/v1/web_hooks/fire', :gem_name => gem_name, :url => url)
end

# Returns the 50 gems most recently added to RubyGems.org (for the first time)
#
# @authenticated false
# @param options [Hash] A customizable set of options.
# @return [Array]
# @example
# Gem.latest
def latest(options = {})
response = get('/api/v1/activity/latest.json', options)
JSON.parse(response)
end

# Returns the 50 most recently updated gems
#
# @authenticated false
# @param options [Hash] A customizable set of options.
# @return [Array]
# @example
# Gem.just_updated
def just_updated(options = {})
response = get('/api/v1/activity/just_updated.json', options)
JSON.parse(response)
end

# Retrieve your API key using HTTP basic auth
#
# @authenticated true
# @return [String]
# @example
# Gems.configure do |config|
# config.username = '[email protected]'
# config.password = 'schwwwwing'
# end
# Gems.api_key
def api_key
get('/api/v1/api_key')
end

# Returns an array of hashes for all versions of given gems
#
# @authenticated false
# @param gems [Array] A list of gem names
# @return [Array]
# @example
# Gems.dependencies 'rails', 'thor'
def dependencies(*gems)
response = get('/api/v1/dependencies', :gems => gems.join(','))
Marshal.load(response)
end

# Returns an array of all the reverse dependencies to the given gem.
#
# @authenticated false
# @param gem_name [String] The name of a gem
# @param options [Hash] A customizable set of options.
# @return [Array]
# @example
# Gems.reverse_dependencies 'money'
def reverse_dependencies(gem_name, options = {})
response = get("/api/v1/gems/#{gem_name}/reverse_dependencies.json", options)
JSON.parse(response)
end
class Client < V1::Client
end
end
Loading
Loading