keycutter 0.1.0

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