codefumes 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,12 @@
1
+ == 0.1.5 2009-09-26
2
+
3
+ * Added visibility support to Claim class
4
+ * Updated Claim#create to use PUT request instead of POST
5
+ * Updated cf_claim_project to support -p/--private flag(s)
6
+ * Renamed store_codefumes_credentials to cf_store_credentials
7
+ * Added cf_release_project executable for releasing/deleting project claims
8
+ * Added ConfigFile#api_key
9
+
1
10
  == 0.1.4 2009-09-26
2
11
 
3
12
  * Updated require statements executables
data/Manifest.txt CHANGED
@@ -3,8 +3,11 @@ Manifest.txt
3
3
  README.txt
4
4
  Rakefile
5
5
  bin/cf_claim_project
6
- bin/store_codefumes_credentials
6
+ bin/cf_release_project
7
+ bin/cf_store_credentials
7
8
  lib/cf_claim_project/cli.rb
9
+ lib/cf_release_project/cli.rb
10
+ lib/cf_store_credentials/cli.rb
8
11
  lib/codefumes.rb
9
12
  lib/codefumes/api.rb
10
13
  lib/codefumes/claim.rb
@@ -12,18 +15,24 @@ lib/codefumes/commit.rb
12
15
  lib/codefumes/config_file.rb
13
16
  lib/codefumes/payload.rb
14
17
  lib/codefumes/project.rb
15
- lib/store_codefumes_credentials/cli.rb
16
18
  spec/cf_claim_project/cli_spec.rb
19
+ spec/cf_release_project/cli_spec.rb
20
+ spec/cf_store_credentials/cli_spec.rb
17
21
  spec/codefumes/api_spec.rb
18
22
  spec/codefumes/claim_spec.rb
19
23
  spec/codefumes/commit_spec.rb
20
24
  spec/codefumes/config_file_spec.rb
21
25
  spec/codefumes/payload_spec.rb
22
26
  spec/codefumes/project_spec.rb
23
- spec/codefumes_service_stubs.rb
27
+ spec/codefumes_service_helpers.rb
28
+ spec/fixtures/commit.xml
29
+ spec/fixtures/commit_with_custom_attrs.xml
30
+ spec/fixtures/multiple_commits.xml
31
+ spec/fixtures/payload.xml
32
+ spec/fixtures/project.xml
33
+ spec/fixtures/project_update.xml
24
34
  spec/spec.opts
25
35
  spec/spec_helper.rb
26
- spec/store_codefumes_credentials/cli_spec.rb
27
36
  tasks/rspec.rake
28
37
  website/index.html
29
38
  website/stylesheets/screen.css
data/Rakefile CHANGED
@@ -22,7 +22,7 @@ $hoe = Hoe.spec('codefumes') do
22
22
  self.summary = "A client-side implementation of the CodeFumes.com API."
23
23
  self.extra_dev_deps = [['jscruggs-metric_fu', ">= 1.1.5"],
24
24
  ['rubigen', ">= 1.5.2"],
25
- ['fakeweb', ">= 1.2.0"]
25
+ ['fakeweb', ">= 1.2.6"]
26
26
  ]
27
27
  self.extra_deps = [['httparty','>= 0.4.3']]
28
28
  developer('Tom Kersten', 'tom.kersten@cosyntech.com')
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2009-10-2.
4
+ # Copyright (c) 2009. All rights reserved.
5
+
6
+ require 'rubygems'
7
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/codefumes")
8
+ require "cf_release_project/cli"
9
+
10
+ CfReleaseProject::CLI.execute(STDOUT, ARGV)
@@ -5,6 +5,6 @@
5
5
 
6
6
  require 'rubygems'
7
7
  require File.expand_path(File.dirname(__FILE__) + "/../lib/codefumes")
8
- require File.expand_path(File.dirname(__FILE__) + "/../lib/store_codefumes_credentials/cli")
8
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/cf_store_credentials/cli")
9
9
 
10
- StoreCodefumesCredentials::CLI.execute(STDOUT, ARGV)
10
+ CfStoreCredentials::CLI.execute(STDOUT, ARGV)
@@ -2,9 +2,10 @@ require 'optparse'
2
2
  require 'codefumes/config_file'
3
3
  include CodeFumes
4
4
 
5
- module CfClaimProject
6
- class CLI
5
+ module CfClaimProject #:nodoc:
6
+ class CLI #:nodoc:
7
7
  @attempt_to_claim_all = false
8
+ @private_project = false
8
9
 
9
10
  def self.execute(stdout, arguments=[])
10
11
  @stdout = stdout
@@ -21,7 +22,7 @@ module CfClaimProject
21
22
  end
22
23
 
23
24
  @stdout.print "Claiming...'#{public_key}': "
24
- @stdout.puts Claim.create(project, @users_api_key) ? 'Success!' : 'Denied.'
25
+ @stdout.puts Claim.create(project, @users_api_key, visibility) ? 'Success!' : 'Denied.'
25
26
  end
26
27
 
27
28
  @stdout.puts ""
@@ -32,7 +33,9 @@ module CfClaimProject
32
33
  def self.parse_cli_arguments!(arguments)
33
34
  OptionParser.new do |opts|
34
35
  opts.banner = <<-BANNER.gsub(/^ /,'')
35
- This application is wonderful because...
36
+ Used to 'claim' a project on CodeFumes.com. The claim request has a
37
+ "visibility" attribute as well, which defaults to "public", but can
38
+ be set to "private" using the -p/--private flag.
36
39
 
37
40
  Usage: #{File.basename($0)} [options]
38
41
 
@@ -40,8 +43,15 @@ module CfClaimProject
40
43
  BANNER
41
44
  opts.separator ""
42
45
  opts.on("-a", "--all", String,
43
- "Attempt to claim all projects in your CodeFumes config file"
46
+ "Attempt to claim all projects in your CodeFumes config file."
44
47
  ) {@attempt_to_claim_all = true}
48
+ opts.on("-p", "--private", String,
49
+ "Claims the project(s) as a 'private' project."
50
+ ) {@private_project = true}
51
+ opts.on("-l", "--local",
52
+ "Send requests to localhost. (Testing/Development)") { CodeFumes::API.mode(:local) }
53
+ opts.on("-t", "--test",
54
+ "Send requests to test.codefumes.com. (Testing/Development)") { CodeFumes::API.mode(:test) }
45
55
  opts.on("-h", "--help",
46
56
  "Show this help message.") { @stdout.puts opts; exit(1) }
47
57
  opts.parse!(arguments)
@@ -59,6 +69,10 @@ module CfClaimProject
59
69
  @attempt_to_claim_all == true
60
70
  end
61
71
 
72
+ def self.visibility
73
+ @private_project == true ? :private : :public
74
+ end
75
+
62
76
  def self.print_missing_arguments_message
63
77
  @stdout.puts "You must specify either a public key of a project, or -a/--all to"
64
78
  @stdout.puts "claim all projects in your CodeFumes config file"
@@ -67,7 +81,7 @@ module CfClaimProject
67
81
  end
68
82
 
69
83
  def self.retrieve_users_credentials_or_exit
70
- @users_api_key = ConfigFile.credentials[:api_key]
84
+ @users_api_key = ConfigFile.api_key
71
85
  return @users_api_key unless @users_api_key.nil?
72
86
  @stdout.puts "No API key saved in your CodeFumes config file!"
73
87
  @stdout.puts ""
@@ -0,0 +1,76 @@
1
+ require 'optparse'
2
+ include CodeFumes
3
+
4
+ module CfReleaseProject #:nodoc:
5
+ class CLI #:nodoc:
6
+ def self.execute(stdout, arguments=[])
7
+ @stdout = stdout
8
+ @users_api_key = ConfigFile.api_key
9
+ parse_cli_options(arguments)
10
+
11
+ @public_keys.each do |public_key|
12
+ project = Project.find(public_key)
13
+
14
+ if project.nil?
15
+ @stdout.puts "Releasing...'#{public_key}': Not found"
16
+ next
17
+ end
18
+
19
+ @stdout.print "Releasing...'#{public_key}': "
20
+ @stdout.puts Claim.destroy(project, @users_api_key) ? 'Success!' : 'Denied.'
21
+ end
22
+
23
+ @stdout.puts ""
24
+ stdout.puts "Done."
25
+ end
26
+
27
+ private
28
+ def self.parse_cli_options(arguments)
29
+ parser = OptionParser.new do |opts|
30
+ opts.banner = <<-BANNER.gsub(/^ /,'')
31
+ Removes the claim of ownership on a CodeFumes project, making
32
+ the project visible to the public and possible for other users
33
+ to claim.
34
+
35
+ Usage: #{File.basename($0)} [PROJECT_PUBLIC_KEY]
36
+
37
+ Options are:
38
+ BANNER
39
+ opts.separator ""
40
+ opts.on("-a", "--all",
41
+ "Release all projects listed in your CodeFumes config file."
42
+ ) {@attempt_to_release_all = true}
43
+ opts.on("-l", "--local",
44
+ "Send requests to localhost. (Testing/Development)") { CodeFumes::API.mode(:local) }
45
+ opts.on("-t", "--test",
46
+ "Send requests to test.codefumes.com. (Testing/Development)") { CodeFumes::API.mode(:test) }
47
+ opts.on("-h", "--help",
48
+ "Show this help message."
49
+ ) {@stdout.puts opts; exit}
50
+ opts.parse!(arguments)
51
+
52
+ @public_keys = release_all_projects_flag_set? ? ConfigFile.public_keys : arguments.compact
53
+ if @public_keys.empty?
54
+ print_missing_arguments_message
55
+ exit
56
+ end
57
+
58
+ if arguments.empty?
59
+ @stdout.puts "No public key specified"
60
+ @stdout.puts opts; exit
61
+ end
62
+ end
63
+ end
64
+
65
+ def self.release_all_projects_flag_set?
66
+ @attempt_to_release_all == true
67
+ end
68
+
69
+ def self.print_missing_arguments_message
70
+ @stdout.puts "You must specify either a public key of a project, or -a/--all to"
71
+ @stdout.puts "claim all projects in your CodeFumes config file"
72
+ @stdout.puts ""
73
+ @stdout.puts "Exiting."
74
+ end
75
+ end
76
+ end
@@ -1,7 +1,7 @@
1
1
  require 'optparse'
2
2
 
3
- module StoreCodefumesCredentials
4
- class CLI
3
+ module CfStoreCredentials #:nodoc:
4
+ class CLI #:nodoc:
5
5
  def self.execute(stdout, arguments=[])
6
6
  @stdout = stdout
7
7
  parse_command_line_options!(arguments)
data/lib/codefumes/api.rb CHANGED
@@ -5,16 +5,21 @@ module CodeFumes
5
5
  format :xml
6
6
 
7
7
  BASE_URIS = {
8
- :production => 'http://www.codefumes.com/api/v1/xml',
8
+ :production => 'http://codefumes.com/api/v1/xml',
9
9
  :test => 'http://test.codefumes.com/api/v1/xml',
10
- :local => 'http://localhost:3000/api/v1/xml'
11
- }
10
+ :local => 'http://codefumes.com.local/api/v1/xml'
11
+ } #:nodoc:
12
12
 
13
+ # Set the connection base for all server requests. Valid options
14
+ # are +:production+ and +:test+, which connect to
15
+ # http://codefumes.com and http://test.codefumes.com (respectively).
16
+ #
17
+ # +:local+ is also technically supported, but provided for local
18
+ # testing and likely only useful for CodeFumes.com developers.
13
19
  def self.mode(mode)
14
20
  base_uri(BASE_URIS[mode]) if BASE_URIS[mode]
15
21
  end
16
22
 
17
23
  mode(:production)
18
-
19
24
  end
20
25
  end
@@ -1,22 +1,55 @@
1
1
  module CodeFumes
2
2
  class Claim < CodeFumes::API
3
3
  attr_accessor :created_at
4
+ SUPPORTED_VISIBILITIES = [:public, :private]
4
5
 
5
6
  # Attempts to claim the specified Project instance using the
6
7
  # supplied API key.
7
8
  #
9
+ # +visibility+ defaults to +:public+. Valid options are +public+
10
+ # and +private+.
11
+ #
8
12
  # Similar to Project#claim, but more explicit.
9
13
  #
10
- # Returns true if the request is successful.
14
+ # Returns +true+ if the request is successful, or if the project
15
+ # was already owned by the user associated with the privided API
16
+ # key.
17
+ #
18
+ # Returns +false+ in all other cases.
19
+ def self.create(project, api_key, visibility = :public)
20
+ unless SUPPORTED_VISIBILITIES.include?(visibility.to_sym)
21
+ msg = "Unsupported visibility supplied (#{visibility.to_s}). "
22
+ msg << "Valid options are: #{SUPPORTED_VISIBILITIES.join(', ')}"
23
+ raise ArgumentError, msg
24
+ end
25
+
26
+ auth_args = {:username => project.public_key, :password => project.private_key}
27
+
28
+ uri = "/projects/#{project.public_key}/claim"
29
+ response = put(uri, :query => {:api_key => api_key, :visibility => visibility}, :basic_auth => auth_args)
30
+
31
+ case response.code
32
+ when 200 : true
33
+ else false
34
+ end
35
+ end
36
+
37
+ # Removes a claim on the specified Project instance using the
38
+ # supplied API key, releasing ownership. If the project was a
39
+ # "private" project, this method will convert it to "public".
40
+ #
41
+ # Returns true if the request was successful or there was not
42
+ # an existing owner (the action is idempotent).
11
43
  #
12
44
  # Returns +false+ in all other cases.
13
- def self.create(project, api_key)
45
+ def self.destroy(project, api_key)
14
46
  auth_args = {:username => project.public_key, :password => project.private_key}
15
47
 
16
48
  uri = "/projects/#{project.public_key}/claim"
17
- response = post(uri, :query => {:api_key => api_key}, :basic_auth => auth_args)
49
+ response = delete(uri, :query => {:api_key => api_key}, :basic_auth => auth_args)
50
+
18
51
  case response.code
19
- when 201 : true
52
+ when 200 : true
20
53
  else false
21
54
  end
22
55
  end
@@ -77,6 +77,10 @@ module CodeFumes
77
77
  serialized_projects.nil? ? [] : serialized_projects.keys
78
78
  end
79
79
 
80
+ def api_key
81
+ credentials[:api_key]
82
+ end
83
+
80
84
  private
81
85
  def write(serializable_object)
82
86
  File.open(path, 'w') do |f|
@@ -108,7 +108,7 @@ module CodeFumes
108
108
  #
109
109
  # Returns +false+ in all other cases.
110
110
  def claim
111
- Claim.create(self, ConfigFile.credentials[:api_key])
111
+ Claim.create(self, ConfigFile.api_key)
112
112
  end
113
113
 
114
114
  private
data/lib/codefumes.rb CHANGED
@@ -8,5 +8,5 @@ require 'codefumes/payload'
8
8
  require 'codefumes/project'
9
9
 
10
10
  module CodeFumes
11
- VERSION = '0.1.4'
11
+ VERSION = '0.1.5'
12
12
  end
@@ -0,0 +1,41 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'cf_release_project/cli'
3
+
4
+ def delete_config_file
5
+ unless ConfigFile.path == File.expand_path('~/.codefumes_config')
6
+ File.delete(ConfigFile.path) if File.exist?(ConfigFile.path)
7
+ end
8
+ end
9
+
10
+ def execute_command(args)
11
+ @stdout_io = StringIO.new
12
+ CfReleaseProject::CLI.execute(@stdout_io, [args])
13
+ @stdout_io.rewind
14
+ @stdout = @stdout_io.read
15
+ end
16
+
17
+
18
+ describe CfReleaseProject::CLI, "execute" do
19
+ before(:each) do
20
+ @api_key = "my_credentials"
21
+ @project = Project.new(:public_key => "abc", :private_key => "382")
22
+ ConfigFile.save_project(@project)
23
+ ConfigFile.save_credentials(@api_key)
24
+ Project.stub!(:find).and_return(@project)
25
+ Claim.stub!(:destroy).with(@project, @api_key)
26
+ end
27
+
28
+ after(:all) do
29
+ delete_config_file
30
+ end
31
+
32
+ it "deletes the claim on the project" do
33
+ Claim.should_receive(:destroy).with(@project, @api_key)
34
+ execute_command(@project.public_key)
35
+ end
36
+
37
+ it "should print default output" do
38
+ execute_command(@project.public_key)
39
+ @stdout.should =~ /Done/
40
+ end
41
+ end
@@ -1,17 +1,22 @@
1
1
  require 'spec/spec_helper'
2
- require 'lib/store_codefumes_credentials/cli'
2
+ require 'lib/cf_store_credentials/cli'
3
3
 
4
- describe StoreCodefumesCredentials::CLI, "execute" do
4
+ def delete_config_file
5
+ unless ConfigFile.path == File.expand_path('~/.codefumes_config')
6
+ File.delete(ConfigFile.path) if File.exist?(ConfigFile.path)
7
+ end
8
+ end
9
+
10
+ describe CfStoreCredentials::CLI, "execute" do
5
11
  after(:all) do
6
- unless ConfigFile.path == File.expand_path('~/.codefumes_config')
7
- File.delete(ConfigFile.path) if File.exist?(ConfigFile.path)
8
- end
12
+ delete_config_file
9
13
  end
10
14
 
11
15
  before(:each) do
16
+ delete_config_file
12
17
  @api_key_value = "API_KEY#{rand(100)}"
13
18
  @stdout_io = StringIO.new
14
- StoreCodefumesCredentials::CLI.execute(@stdout_io, [@api_key_value])
19
+ CfStoreCredentials::CLI.execute(@stdout_io, [@api_key_value])
15
20
  @stdout_io.rewind
16
21
  @stdout = @stdout_io.read
17
22
  end
@@ -9,7 +9,7 @@ describe "API" do
9
9
  end
10
10
 
11
11
  it "defaults the base uri to the production site" do
12
- APIClass.base_uri.should == 'http://www.codefumes.com/api/v1/xml'
12
+ APIClass.base_uri.should == 'http://codefumes.com/api/v1/xml'
13
13
  end
14
14
 
15
15
  context "switching modes" do
@@ -23,7 +23,7 @@ describe "API" do
23
23
 
24
24
  it "changes the base uri to the production site when switched to production mode" do
25
25
  CodeFumes::API.mode(:production)
26
- APIClass.base_uri.should == 'http://www.codefumes.com/api/v1/xml'
26
+ APIClass.base_uri.should == 'http://codefumes.com/api/v1/xml'
27
27
  end
28
28
 
29
29
  it "ignores unrecognized modes" do
@@ -33,7 +33,7 @@ describe "API" do
33
33
 
34
34
  it "changes the base uri to 'localhost:3000' when switched to local mode (for developer testing)" do
35
35
  CodeFumes::API.mode(:local)
36
- APIClass.base_uri.should == 'http://localhost:3000/api/v1/xml'
36
+ APIClass.base_uri.should == 'http://codefumes.com.local/api/v1/xml'
37
37
  end
38
38
  end
39
39
 
@@ -1,30 +1,67 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper.rb'
2
2
 
3
3
  describe Claim do
4
+ include CodeFumesServiceHelpers::Claim
5
+
4
6
  after(:all) do
5
7
  FakeWeb.allow_net_connect = false
6
8
  FakeWeb.clean_registry
7
9
  end
8
10
 
9
- before(:each) do
10
- @api_key = "USERS_API_KEY"
11
- @project = Project.new(:public_key => 'public_key_value', :private_key => 'private_key_value')
12
- @claim_uri = "http://www.codefumes.com/api/v1/xml/projects/#{@project.public_key}/claim?api_key=#{@api_key}"
11
+ before(:all) do
12
+ FakeWeb.clean_registry
13
+ FakeWeb.allow_net_connect = false
14
+ setup_fixture_base
13
15
  end
14
16
 
15
17
  describe "create" do
16
- context "with 201 Created response" do
17
- it "returns an instance of Claim with the created_at attribute set" do
18
- FakeWeb.register_uri( :post, @claim_uri, :status => ["201", "Created"], :string => "")
18
+ context "with '200 Ok' response" do
19
+ it "returns true" do
20
+ register_public_create_uri
19
21
  Claim.create(@project, @api_key).should be_true
20
22
  end
21
23
  end
22
24
 
23
- context "with Unauthorized response" do
25
+ context "with '401 Unauthorized' response" do
24
26
  it "returns false" do
25
- FakeWeb.register_uri( :post, @claim_uri, :status => ["401", "Unauthorized"], :string => "")
27
+ register_public_create_uri(["401", "Unauthorized"])
26
28
  Claim.create(@project, @api_key).should be_false
27
29
  end
28
30
  end
31
+
32
+ context "setting visibility" do
33
+ it "supports 'public'" do
34
+ register_public_create_uri
35
+ Claim.create(@project, @api_key, :public).should be_true
36
+ Claim.create(@project, @api_key).should be_true
37
+ end
38
+
39
+ it "supports 'private'" do
40
+ register_private_create_uri
41
+ Claim.create(@project, @api_key, :private).should be_true
42
+ end
43
+
44
+ it "raises an ArgumentError if an unsupported visibility type is provided" do
45
+ lambda {
46
+ Claim.create(@project, @api_key, :unsupported_visibility)
47
+ }.should raise_error(ArgumentError)
48
+ end
49
+ end
50
+ end
51
+
52
+ describe "destroy" do
53
+ context "with '200 Ok' response" do
54
+ it "returns true" do
55
+ register_destroy_uri
56
+ Claim.destroy(@project, @api_key).should be_true
57
+ end
58
+ end
59
+
60
+ context "with '401 Unauthorized' response" do
61
+ it "returns false" do
62
+ register_destroy_uri(["401", "Unauthorized"])
63
+ Claim.destroy(@project, @api_key).should be_false
64
+ end
65
+ end
29
66
  end
30
67
  end