codefumes 0.1.4 → 0.1.5

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.
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