keycutter 0.1.0

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.
@@ -0,0 +1,8 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ *.swp
5
+ .DS_Store
6
+ Gemfile.lock
7
+ test_credentials
8
+ xstub.cache*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm gemset use keycutter
@@ -0,0 +1,4 @@
1
+ == Changelog
2
+
3
+ === 0.1.0
4
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem "rake"
7
+ gem "cucumber"
8
+ gem "aruba"
9
+ gem "rspec"
10
+ gem "fakeweb"
11
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Josh French
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,58 @@
1
+ Keycutter
2
+ =========
3
+
4
+ Multiple gemcutter accounts? Manage your keys with ease. Keycutter adds account
5
+ management to rubygems, so you can manage gems for multiple accounts or
6
+ organizations.
7
+
8
+ Installation
9
+ ------------
10
+
11
+ gem install keycutter
12
+
13
+ Usage
14
+ -----
15
+
16
+ Start by adding your current API key. You can name it whatever you want:
17
+
18
+ $ gem keys --add personal
19
+ Email:
20
+ Password:
21
+
22
+ You'll be prompted for your Rubygems.org email and password. If you manage gems
23
+ for your company or an open-source organization, add those too:
24
+
25
+ $ gem keys --add company
26
+ $ gem keys --add project
27
+
28
+ You can view your current keys:
29
+
30
+ $ gem keys --list
31
+
32
+ *** CURRENT KEYS ***
33
+
34
+ company
35
+ * personal
36
+ project
37
+
38
+ Your currently active key is marked.
39
+
40
+ To switch to a different account before pushing a gem:
41
+
42
+ $ gem keys --use company
43
+
44
+ You can also remove a key:
45
+
46
+ $ gem keys --remove project
47
+
48
+ Help is available from the command line:
49
+
50
+ $ gem keys --help
51
+
52
+ TODO
53
+ ----
54
+
55
+ * Add auto-detection of existing API key and create a default key name
56
+ * Rubygems 1.3.7 doesn't support gemcutter-compatible hosts, although this has
57
+ been added to edge. Update `keys --add` to take a `--host` option when the next
58
+ version of rubygems is released.
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'bundler'
4
+ Bundler.setup
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ require 'cucumber/rake/task'
8
+ Cucumber::Rake::Task.new do |t|
9
+ t.cucumber_opts = %w{--format pretty}
10
+ end
11
+
12
+ task :default => :cucumber
13
+
14
+ require 'rspec/core/rake_task'
15
+ task :spec do
16
+ RSpec::Core::RakeTask.new do |spec|
17
+ spec.rspec_opts = %w{--color --format progress}
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ @fakeweb
2
+
3
+ Feature: Adding keys
4
+ As a developer
5
+ I want to add an API key
6
+ So I can push gems as a different user
7
+
8
+ Scenario Outline: Adding a new key
9
+ Given a valid gemcutter account
10
+ When I run "gem keys <command> <key>" interactively
11
+ And I type "josh@vitamin-j.com"
12
+ And I type "12345"
13
+ Then the output should contain "Added <key> rubygems API key"
14
+ And I should have a "<key>" rubygems key
15
+ And the "<key>" rubygems key should be the response body
16
+
17
+ Examples:
18
+ |command|key |
19
+ |-a |personal|
20
+ |--add |work |
21
+
22
+ Scenario: Adding a key with bad credentials
23
+ Given an invalid gemcutter account
24
+ When I run "gem keys -a bogus" interactively
25
+ And I type "josh@vitamin-j.com"
26
+ And I type "12345"
27
+ Then the output should contain "Access denied"
28
+ And I should not have a "bogus" rubygems key
@@ -0,0 +1,47 @@
1
+ Feature: Default commands
2
+ As a new user
3
+ I want to find out what my options are
4
+ So I can put keycutter to best use
5
+
6
+ Scenario: Installing the gem
7
+ When I run "gem q"
8
+ Then the output should contain "keycutter"
9
+
10
+ Scenario: Calling the plugin with no options
11
+ Given I have the following rubygems keys:
12
+ |name |key |
13
+ |personal|11111111111111111111111111111111|
14
+ |work |22222222222222222222222222222222|
15
+ |oss_1 |33333333333333333333333333333333|
16
+ |oss_2 |44444444444444444444444444444444|
17
+ And my current rubygems key is "personal"
18
+ When I run "gem keys"
19
+ Then the output should contain:
20
+ """
21
+ *** CURRENT KEYS ***
22
+
23
+ oss_1
24
+ oss_2
25
+ * personal
26
+ work
27
+ """
28
+
29
+ Scenario Outline: Using the list option
30
+ Given I have the following rubygems keys:
31
+ |name |key |
32
+ |personal|11111111111111111111111111111111|
33
+ |work |22222222222222222222222222222222|
34
+ And my current rubygems key is "work"
35
+ When I run "gem keys <option>"
36
+ Then the output should contain:
37
+ """
38
+ *** CURRENT KEYS ***
39
+
40
+ personal
41
+ * work
42
+ """
43
+
44
+ Examples:
45
+ |option |
46
+ |-l |
47
+ |--list |
@@ -0,0 +1,25 @@
1
+ Feature: Remove API keys
2
+ As a developer
3
+ I want to remove an old API key
4
+ So I can get rid of cruft
5
+
6
+ Background:
7
+ Given I have the following rubygems keys:
8
+ |name |key |
9
+ |personal|11111111111111111111111111111111|
10
+ |work |22222222222222222222222222222222|
11
+
12
+ Scenario Outline:
13
+ When I run "gem keys <command> <key>"
14
+ Then the output should contain "Removed <key> rubygems API key"
15
+ And I should not have a "<key>" rubygems key
16
+
17
+ Examples:
18
+ |command |key |
19
+ |-r |personal|
20
+ |--remove|work |
21
+
22
+ Scenario: Removing a bogus key
23
+ When I run "gem keys -r bogus"
24
+ Then the output should contain "No such rubygems API key"
25
+ And the exit status should be 1
@@ -0,0 +1,41 @@
1
+ Given /^I have the following rubygems keys:$/ do |table|
2
+ accounts = table.hashes.inject({}) do |hash,row|
3
+ hash[row[:name]] = row[:key]
4
+ hash
5
+ end
6
+ Gem.configuration.rubygems_accounts = accounts
7
+ end
8
+
9
+ Given /^my current rubygems key is "([^"]*)"$/ do |key|
10
+ Gem.configuration.rubygems_api_key = Gem.configuration.rubygems_accounts[key]
11
+ end
12
+
13
+ Given /^a valid gemcutter account$/ do
14
+ @response = {:body => '3'*32}
15
+ DRb.start_service "druby://localhost:3333", [:get, "https://rubygems.org/api/v1/api_key", @response]
16
+ end
17
+
18
+ Given /^an invalid gemcutter account$/ do
19
+ @response = {:body => "HTTP Basic: Access denied", :status => ["401", "Not Authorized"]}
20
+ DRb.start_service "druby://localhost:3333", [:get, "https://rubygems.org/api/v1/api_key", @response]
21
+ end
22
+
23
+ Then /^my current rubygems key should be "([^"]*)"$/ do |key|
24
+ Gem.configuration.load_rubygems_api_key
25
+ Gem.configuration.rubygems_api_key.should == Gem.configuration.rubygems_accounts[key]
26
+ end
27
+
28
+ Then /^I should have a "([^"]*)" rubygems key$/ do |key|
29
+ Gem.configuration.load_rubygems_accounts
30
+ Gem.configuration.rubygems_accounts.should have_key(key)
31
+ end
32
+
33
+ Then /^I should not have a "([^"]*)" rubygems key$/ do |key|
34
+ Gem.configuration.load_rubygems_accounts
35
+ Gem.configuration.rubygems_accounts.should_not have_key(key)
36
+ end
37
+
38
+ Then /^the "([^"]*)" rubygems key should be the response body$/ do |key|
39
+ Gem.configuration.load_rubygems_accounts
40
+ Gem.configuration.rubygems_accounts[key].should == @response[:body]
41
+ end
@@ -0,0 +1,4 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../../lib')
2
+
3
+ require 'aruba/cucumber'
4
+ require 'keycutter'
@@ -0,0 +1,8 @@
1
+ Before '@fakeweb' do
2
+ require 'drb'
3
+ set_env 'FAKEWEB', 'test'
4
+ end
5
+
6
+ After '@fakeweb' do
7
+ DRb.stop_service
8
+ end
@@ -0,0 +1,18 @@
1
+ AfterConfiguration do
2
+ `rake build`
3
+ `gem install pkg/keycutter-#{Keycutter::VERSION}.gem`
4
+ end
5
+
6
+ Before do
7
+ @original_api_key = Gem.configuration.rubygems_api_key
8
+ @original_accounts = Gem.configuration.rubygems_accounts
9
+ end
10
+
11
+ After do
12
+ Gem.configuration.rubygems_api_key = @original_api_key
13
+ Gem.configuration.rubygems_accounts = @original_accounts
14
+ end
15
+
16
+ at_exit do
17
+ `gem uninstall keycutter -v #{Keycutter::VERSION}`
18
+ end
@@ -0,0 +1,29 @@
1
+ Feature: Using gem keys
2
+ As an open source developer
3
+ I want to switch between rubygems API keys
4
+ In order to push all of my sweet gems
5
+
6
+ Background:
7
+ Given I have the following rubygems keys:
8
+ |name |key |
9
+ |personal|11111111111111111111111111111111|
10
+ |work |22222222222222222222222222222222|
11
+
12
+ Scenario Outline: Using a different key
13
+ Given my current rubygems key is "work"
14
+ When I run "gem keys <command> <key>"
15
+ Then the output should contain "Now using <key> rubygems API key"
16
+ And my current rubygems key should be "<key>"
17
+
18
+ Examples:
19
+ |command|key |
20
+ |-u |personal|
21
+ |--use |personal|
22
+ |-u |work |
23
+
24
+ Scenario: Using a bogus key
25
+ Given my current rubygems key is "personal"
26
+ When I run "gem keys -u bogus"
27
+ Then the output should contain "No such rubygems API key. You can add it with: gem keys -a bogus"
28
+ And the exit status should be 1
29
+ And my current rubygems key should be "personal"
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "keycutter/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "keycutter"
7
+ s.version = Keycutter::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Josh French"]
10
+ s.email = ["josh@vitamin-j.com"]
11
+ s.homepage = "http://github.com/joshfrench/keycutter"
12
+ s.summary = %q{Gemcutter key management}
13
+ s.description = %q{Multiple gemcutter accounts? Manage your keys with ease.}
14
+
15
+ s.rubyforge_project = "keycutter"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
19
+ s.require_paths = ["lib"]
20
+ end
@@ -0,0 +1,8 @@
1
+ require 'keycutter/version'
2
+ require 'keycutter/configuration'
3
+ require 'keycutter/keys_command'
4
+ require 'keycutter/testing' if ENV['FAKEWEB']
5
+
6
+ module Keycutter
7
+
8
+ end
@@ -0,0 +1,27 @@
1
+ require 'rubygems/config_file'
2
+
3
+ class Gem::ConfigFile
4
+ def rubygems_accounts
5
+ @rubygems_accounts || load_rubygems_accounts
6
+ end
7
+
8
+ def rubygems_accounts=(accounts)
9
+ config = load_file(credentials_path).merge(:rubygems_accounts => accounts)
10
+
11
+ dirname = File.dirname(credentials_path)
12
+ Dir.mkdir(dirname) unless File.exists?(dirname)
13
+
14
+ require 'yaml'
15
+
16
+ File.open(credentials_path, 'w') do |f|
17
+ f.write config.to_yaml
18
+ end
19
+
20
+ @rubygems_accounts = accounts
21
+ end
22
+
23
+ def load_rubygems_accounts
24
+ credentials_hash = File.exists?(credentials_path) ? load_file(credentials_path) : @hash
25
+ @rubygems_accounts = credentials_hash[:rubygems_accounts] || {}
26
+ end
27
+ end
@@ -0,0 +1,93 @@
1
+ require 'rubygems/command'
2
+ require 'rubygems/gemcutter_utilities'
3
+
4
+ class Gem::Commands::KeysCommand < Gem::Command
5
+ include Gem::GemcutterUtilities
6
+
7
+ def initialize
8
+ super 'keys', "Adds management for multiple gemcutter accounts"
9
+
10
+ add_option '-l', '--list', 'List keys' do |value,options|
11
+ options[:list] = value
12
+ end
13
+
14
+ add_option '-u', '--use KEYNAME', 'Use the given API key' do |value,options|
15
+ options[:use] = value
16
+ end
17
+
18
+ add_option '-r', '--remove KEYNAME', 'Remove the given API key' do |value,options|
19
+ options[:remove] = value
20
+ end
21
+
22
+ add_option '-a', '--add KEYNAME', 'Add an API key with the given name' do |value,options|
23
+ options[:add] = value
24
+ end
25
+ end
26
+
27
+ def arguments
28
+ "KEYNAME name of a Rubygems API key"
29
+ end
30
+
31
+ def defaults_str
32
+ "--list"
33
+ end
34
+
35
+ def usage
36
+ "#{program_name} [options] [KEYNAME]"
37
+ end
38
+
39
+ def execute
40
+ options[:list] = !(options[:use] || options[:remove] || options[:add])
41
+
42
+ if options[:add] then
43
+ say "Enter your RubyGems.org credentials."
44
+ say "Don't have an account yet? Create one at http://rubygems.org/sign_up"
45
+
46
+ email = ask " Email: "
47
+ password = ask_for_password "Password: "
48
+ say
49
+
50
+ response = rubygems_api_request :get, "api/v1/api_key" do |request|
51
+ request.basic_auth email, password
52
+ end
53
+
54
+ with_response response do |resp|
55
+ accounts = Gem.configuration.rubygems_accounts.merge(options[:add] => resp.body)
56
+ Gem.configuration.rubygems_accounts = accounts
57
+ say "Added #{options[:add]} rubygems API key"
58
+ end
59
+ end
60
+
61
+ if options[:remove] then
62
+ accounts = Gem.configuration.rubygems_accounts
63
+ if accounts.has_key? options[:remove]
64
+ accounts.delete(options[:remove])
65
+ Gem.configuration.rubygems_accounts = accounts
66
+ say "Removed #{options[:remove]} rubygems API key"
67
+ else
68
+ say "No such rubygems API key"
69
+ terminate_interaction 1
70
+ end
71
+ end
72
+
73
+ if options[:use] then
74
+ if Gem.configuration.rubygems_accounts.has_key? options[:use]
75
+ Gem.configuration.rubygems_api_key = Gem.configuration.rubygems_accounts[options[:use]]
76
+ say "Now using #{options[:use]} rubygems API key"
77
+ else
78
+ say "No such rubygems API key. You can add it with: gem keys -a #{options[:use]}"
79
+ terminate_interaction 1
80
+ end
81
+ end
82
+
83
+ if options[:list] then
84
+ say "*** CURRENT KEYS ***"
85
+ say
86
+ accounts = Gem.configuration.rubygems_accounts.sort
87
+ accounts.each do |account|
88
+ name, key = account
89
+ say "%2s %s" % [Gem.configuration.rubygems_api_key[key] && '*', name]
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,8 @@
1
+ require 'drb'
2
+ require 'fakeweb'
3
+
4
+ DRb.start_service
5
+ remote = DRbObject.new(nil, "druby://localhost:3333")
6
+
7
+ FakeWeb.allow_net_connect = false
8
+ FakeWeb.register_uri *remote
@@ -0,0 +1,3 @@
1
+ module Keycutter
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems/command_manager'
2
+
3
+ require 'keycutter'
4
+ Gem::CommandManager.instance.register_command :keys
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Gem::ConfigFile do
4
+ before do
5
+ @credentials = File.dirname(__FILE__) + '/../test_credentials'
6
+ @config = Gem::ConfigFile.new([])
7
+ @config.stub(:credentials_path) { @credentials }
8
+ end
9
+
10
+ describe "#rubygems_accounts" do
11
+ it "should load from credentials file" do
12
+ credentials = {:rubygems_accounts => {'personal' => '1'*32, 'work' => '2'*32}}
13
+ File.open(@credentials, 'w') { |f| f.write credentials.to_yaml }
14
+ @config.rubygems_accounts.should == credentials[:rubygems_accounts]
15
+ end
16
+ end
17
+
18
+ describe "#rubygems_accounts=" do
19
+ it "should write to credentials file" do
20
+ File.open(@credentials, 'w') { |f| f.write '' }
21
+ accounts = {'personal' => '1'*32, 'work' => '2'*32}
22
+ @config.rubygems_accounts = accounts
23
+
24
+ File.read(@credentials).should == {:rubygems_accounts => accounts}.to_yaml
25
+ end
26
+
27
+ it "should preserve existing credentials" do
28
+ api_key = {:rubygems_api_key => '0'*32}
29
+ File.open(@credentials, 'w') { |f| f.write api_key.to_yaml }
30
+
31
+ accounts = {'personal' => '1'*32, 'work' => '2'*32}
32
+ @config.rubygems_accounts = accounts
33
+
34
+ credentials = YAML.load_file(@credentials)
35
+ credentials[:rubygems_api_key].should == '0'*32
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,4 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../../lib')
2
+
3
+ require 'rspec/mocks'
4
+ require 'keycutter'
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: keycutter
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Josh French
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-19 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Multiple gemcutter accounts? Manage your keys with ease.
23
+ email:
24
+ - josh@vitamin-j.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - .gitignore
33
+ - .rvmrc
34
+ - CHANGELOG
35
+ - Gemfile
36
+ - MIT-LICENSE
37
+ - README.md
38
+ - Rakefile
39
+ - features/add.feature
40
+ - features/default.feature
41
+ - features/remove.feature
42
+ - features/step_definitions/keycutter_steps.rb
43
+ - features/support/env.rb
44
+ - features/support/fakeweb.rb
45
+ - features/support/hooks.rb
46
+ - features/use.feature
47
+ - keycutter.gemspec
48
+ - lib/keycutter.rb
49
+ - lib/keycutter/configuration.rb
50
+ - lib/keycutter/keys_command.rb
51
+ - lib/keycutter/testing.rb
52
+ - lib/keycutter/version.rb
53
+ - lib/rubygems_plugin.rb
54
+ - spec/configuration_spec.rb
55
+ - spec/spec_helper.rb
56
+ has_rdoc: true
57
+ homepage: http://github.com/joshfrench/keycutter
58
+ licenses: []
59
+
60
+ post_install_message:
61
+ rdoc_options: []
62
+
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 3
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ requirements: []
84
+
85
+ rubyforge_project: keycutter
86
+ rubygems_version: 1.3.7
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Gemcutter key management
90
+ test_files:
91
+ - features/add.feature
92
+ - features/default.feature
93
+ - features/remove.feature
94
+ - features/step_definitions/keycutter_steps.rb
95
+ - features/support/env.rb
96
+ - features/support/fakeweb.rb
97
+ - features/support/hooks.rb
98
+ - features/use.feature
99
+ - spec/configuration_spec.rb
100
+ - spec/spec_helper.rb