shelltoad 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,8 +1,15 @@
1
1
  source :gemcutter
2
2
 
3
- gem 'activeresource'
4
- gem 'jeweler'
5
3
  gem "rake"
4
+ gem 'activesupport'
5
+ # We use some hash extensions -
6
+ # #from_xml and #with_indifferent_access from activesupport
7
+ # By some unknown reason these extensions require i18n
8
+ gem "i18n"
9
+
10
+ group :development do
11
+ gem 'jeweler'
12
+ end
6
13
 
7
14
  group :test do
8
15
  gem 'rspec'
data/Gemfile.lock CHANGED
@@ -1,34 +1,33 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- activeresource (2.3.8)
5
- activesupport (= 2.3.8)
6
- activesupport (2.3.8)
4
+ activesupport (3.0.5)
7
5
  diff-lcs (1.1.2)
8
6
  fakeweb (1.3.0)
9
7
  git (1.2.5)
8
+ i18n (0.5.0)
10
9
  jeweler (1.5.2)
11
10
  bundler (~> 1.0.0)
12
11
  git (>= 1.2.5)
13
12
  rake
14
- mocha (0.9.10)
15
- rake
13
+ mocha (0.9.12)
16
14
  rake (0.8.7)
17
- rspec (2.4.0)
18
- rspec-core (~> 2.4.0)
19
- rspec-expectations (~> 2.4.0)
20
- rspec-mocks (~> 2.4.0)
21
- rspec-core (2.4.0)
22
- rspec-expectations (2.4.0)
15
+ rspec (2.5.0)
16
+ rspec-core (~> 2.5.0)
17
+ rspec-expectations (~> 2.5.0)
18
+ rspec-mocks (~> 2.5.0)
19
+ rspec-core (2.5.1)
20
+ rspec-expectations (2.5.0)
23
21
  diff-lcs (~> 1.1.2)
24
- rspec-mocks (2.4.0)
22
+ rspec-mocks (2.5.0)
25
23
 
26
24
  PLATFORMS
27
25
  ruby
28
26
 
29
27
  DEPENDENCIES
30
- activeresource
28
+ activesupport
31
29
  fakeweb
30
+ i18n
32
31
  jeweler
33
32
  mocha
34
33
  rake
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
1
  require 'rubygems'
2
+ require "bundler"
3
+ Bundler.setup
2
4
  require 'rake'
3
- require 'spec/rake/spectask'
5
+ require 'rspec/core/rake_task'
4
6
 
5
- Spec::Rake::SpecTask.new(:spec) do |spec|
6
- spec.libs << 'lib' << 'spec'
7
- spec.spec_files = FileList['spec/**/*_spec.rb']
7
+ RSpec::Core::RakeTask.new(:spec) do |spec|
8
8
  end
9
9
 
10
10
  begin
data/Readme.textile CHANGED
@@ -9,6 +9,16 @@ with the application name and access key:
9
9
  <pre><code>project: myapp
10
10
  key: c285743ecbc285743ecbc285743ecbc285743ecb</code></pre>
11
11
 
12
+ h3. Commands
13
+
14
+ * errors, ers - list all unresolved errors, this is the default
15
+ * error, er [number] - display information about given error. Shortcut: shelltoad [number]
16
+ * resolve, rv [number] - mark error as resolved in Hoptoad
17
+ * commit, ci [number] - do commit to vcs with the information on the specified error and mark error resolved in Hoptoad
18
+
19
+ Shelltoad supports 'magicfind' in all commands:
20
+ You don't need to type whole error id - just last three numbers is enough.
21
+
12
22
  h3. Usage
13
23
 
14
24
  <pre><code>$ shelltoad
@@ -29,5 +39,9 @@ ActiveRecord::StatementInvalid: PGError: ERROR: duplicate key value violates uni
29
39
 
30
40
 
31
41
  # Do changes you want
32
- $ shelltoad commit 713</code></pre>
42
+ $ git add .
43
+ #only git is supported right now
44
+ $ shelltoad commit 713
45
+ [dev 47f09ec] http://xxx.hoptoadapp.com//errors/4023713
46
+ 1 files changed, 1 insertions(+), 1 deletions(-)</code></pre>
33
47
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.2.2
@@ -3,22 +3,33 @@ class Shelltoad::Command
3
3
  def self.run(command, *args)
4
4
  case command
5
5
  when "errors", "ers", nil
6
- Shelltoad::Error.find(:all).each do |error|
7
- unless error.rails_env == "development"
8
- Shelltoad.output error.to_s
9
- end
6
+ Shelltoad::Error.all.each do |error|
7
+ output error.to_s
10
8
  end
11
9
  when "error", "er"
12
- Shelltoad.output Shelltoad::Error.magic_find(args.shift).view || "Not found"
10
+ Shelltoad::Error.magic_find(args.shift) do |error|
11
+ output error.view
12
+ end
13
13
  when "commit", "ci"
14
- if error = Shelltoad::Error.magic_find(args.shift)
15
- error.commit
16
- else
17
- Shelltoad.output "Not Found"
14
+ Shelltoad::Error.magic_find(args.shift) do |error|
15
+ output error.commit!
16
+ end
17
+ when "resolve", "rv"
18
+ Shelltoad::Error.magic_find(args.shift) do |error|
19
+ error.resolve!
20
+ output "Error #{error.id} marked as resolved"
18
21
  end
19
22
  when /^[\d]/
20
- Shelltoad.output Shelltoad::Error.magic_find(command).view || "Not found"
23
+ Shelltoad::Error.magic_find(command) do |error|
24
+ output error.view
25
+ end
21
26
  end
22
27
  return true
28
+ rescue Shelltoad::ErrorNotFound => e
29
+ output e.message
30
+ end
31
+
32
+ def self.output(*args)
33
+ Shelltoad.output(*args)
23
34
  end
24
35
  end
@@ -1,42 +1,46 @@
1
- require "active_resource"
1
+ require "active_support/core_ext/hash/conversions"
2
+ require "active_support/core_ext/hash/indifferent_access"
2
3
  require "net/http"
3
4
  require "uri"
4
5
  require "cgi"
5
6
 
6
- class Shelltoad::Error < ActiveResource::Base
7
- URL = URI.parse("http://#{::Shelltoad::Configuration.project}.hoptoadapp.com")
8
- self.site = URL.to_s
9
-
10
- class << self
11
- @@auth_token = ::Shelltoad::Configuration.key
12
-
13
- def find(*arguments)
14
- arguments = append_auth_token_to_params(*arguments)
15
- super(*arguments)
16
- end
7
+ class Shelltoad::Error
17
8
 
18
- def append_auth_token_to_params(*arguments)
19
- opts = arguments.last.is_a?(Hash) ? arguments.pop : {}
20
- opts = opts.has_key?(:params) ? opts : opts.merge(:params => {})
21
- opts[:params] = opts[:params].merge(:auth_token => @@auth_token)
22
- arguments << opts
23
- arguments
24
- end
25
- end
9
+ URL = URI.parse("http://#{::Shelltoad::Configuration.project}.hoptoadapp.com")
26
10
 
11
+ #
12
+ # Class methods
13
+ #
14
+
27
15
  def self.all(*args)
28
- self.find :all, *args
16
+ parse(http_get("/errors.xml"))[:groups].map! do |attributes|
17
+ self.new(attributes)
18
+ end
29
19
  end
30
20
 
31
21
  def self.magic_find(id)
32
- self.all(:params => {:show_resolved => true}).find do |error|
22
+ error = self.all(:show_resolved => true).find do |error|
33
23
  error.id.to_s =~ /#{id}$/
34
24
  end
25
+ raise Shelltoad::ErrorNotFound, "Error with id:#{id} not found" unless error
26
+ if block_given?
27
+ yield(error)
28
+ end
29
+ error
30
+ end
31
+
32
+ #
33
+ # API
34
+ #
35
+
36
+ def initialize(attributes)
37
+ @attributes = attributes
35
38
  end
36
39
 
37
40
  def data
38
- @data ||= Hash.from_xml(http_get("/errors/#{self.id}.xml", :auth_token => ::Shelltoad::Configuration.key)).with_indifferent_access[:group]
41
+ @data ||= self.class.parse(self.class.http_get(path('xml')))[:group]
39
42
  end
43
+
40
44
  def view
41
45
  <<-EOI
42
46
  #{data[:error_message]}
@@ -44,24 +48,75 @@ class Shelltoad::Error < ActiveResource::Base
44
48
  EOI
45
49
  end
46
50
 
47
- def commit
51
+ def commit!
48
52
  message = <<-EOI.gsub(/`/, "'")
49
- #{self.class.site}/errors/#{self.id}
53
+ #{url}
50
54
 
51
55
  #{self.error_message}
52
56
  EOI
53
- Shelltoad.output `git commit -m "#{message}"`
57
+ output = `git commit -m "#{message}"`
58
+ if $?.success?
59
+ resolve!
60
+ end
61
+ output
54
62
  end
55
63
 
56
- def http_get(path, params = {})
57
- query = path + "?" + params.collect { |k,v| "#{k}=#{CGI::escape(v.to_s)}" }.join('&')
58
- return Net::HTTP.get(URL.host, query)
64
+ def resolve!
65
+ return true if self.resolved?
66
+ response = Net::HTTP.post_form(
67
+ url,
68
+ :"group[resolved]" => 1,
69
+ :format => "xml",
70
+ :_method => :put,
71
+ :auth_token => ::Shelltoad::Configuration.key
72
+ )
73
+ raise "HTTP error: #{response}" unless response.is_a?(Net::HTTPSuccess)
74
+ true
59
75
  end
60
76
 
77
+
61
78
  def to_s
62
79
  "[##{self.id}] #{self.rails_env.first} #{self.error_message} #{self.file}:#{self.line_number}"
63
80
  end
64
81
 
82
+ def id
83
+ @attributes[:id]
84
+ end
85
+
86
+ def resolved?
87
+ @attributes[:resolved]
88
+ end
89
+
90
+ def method_missing(meth, *args, &blk)
91
+ if attr = @attributes[meth]
92
+ attr
93
+ else
94
+ super(meth, *args, &blk)
95
+ end
96
+ end
97
+
98
+ #
99
+ # Implementation
100
+ #
101
+
102
+ protected
103
+ def path(format = nil)
104
+ "/errors/#{self.id}" + (format ? ".#{format}" : "")
105
+ end
106
+
107
+ def url(format = nil)
108
+ URI.parse(URL.to_s + path(format))
109
+ end
110
+
111
+ def self.http_get(path, params = {})
112
+ params[:auth_token] = ::Shelltoad::Configuration.key
113
+ query = path + "?" + params.collect { |k,v| "#{k}=#{CGI::escape(v.to_s)}" }.join('&')
114
+ return Net::HTTP.get(URL.host, query)
115
+ end
116
+
117
+ def self.parse(string)
118
+ Hash.from_xml(string).with_indifferent_access
119
+ end
65
120
 
66
121
  end
67
122
 
@@ -6,3 +6,6 @@ end
6
6
 
7
7
  class Shelltoad::NoConfigfile < StandardError
8
8
  end
9
+
10
+ class Shelltoad::ErrorNotFound < StandardError
11
+ end
data/lib/shelltoad.rb CHANGED
@@ -15,7 +15,7 @@ class Shelltoad
15
15
  end
16
16
 
17
17
  def self.output(string)
18
- ::Shelltoad::STDOUT << "#{string}\n"
18
+ ::Shelltoad::STDOUT << "#{string.to_s.strip}\n"
19
19
  end
20
20
 
21
21
  def output(string)
data/shelltoad.gemspec CHANGED
@@ -5,40 +5,67 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{shelltoad}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bogdan Gusiev"]
12
- s.date = %q{2011-01-20}
12
+ s.date = %q{2011-02-26}
13
13
  s.default_executable = %q{shelltoad}
14
14
  s.description = %q{
15
15
  }
16
16
  s.email = %q{agresso@gmail.com}
17
17
  s.executables = ["shelltoad"]
18
+ s.files = [
19
+ "Gemfile",
20
+ "Gemfile.lock",
21
+ "Rakefile",
22
+ "Readme.textile",
23
+ "VERSION",
24
+ "bin/shelltoad",
25
+ "lib/shelltoad.rb",
26
+ "lib/shelltoad/command.rb",
27
+ "lib/shelltoad/configuration.rb",
28
+ "lib/shelltoad/error.rb",
29
+ "lib/shelltoad/exceptions.rb",
30
+ "shelltoad.gemspec",
31
+ "spec/assets/error.xml",
32
+ "spec/assets/errors.xml",
33
+ "spec/shelltoad/error_spec.rb",
34
+ "spec/shelltoad_spec.rb",
35
+ "spec/spec_helper.rb"
36
+ ]
18
37
  s.homepage = %q{http://github.com/railsware/shelltoad}
19
38
  s.require_paths = ["lib"]
20
39
  s.rubygems_version = %q{1.3.7}
21
40
  s.summary = %q{Command line interface for hoptoad (http://hoptoadapp.com)}
41
+ s.test_files = [
42
+ "spec/shelltoad/error_spec.rb",
43
+ "spec/shelltoad_spec.rb",
44
+ "spec/spec_helper.rb"
45
+ ]
22
46
 
23
47
  if s.respond_to? :specification_version then
24
48
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
49
  s.specification_version = 3
26
50
 
27
51
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
28
- s.add_runtime_dependency(%q<activeresource>, [">= 0"])
29
- s.add_runtime_dependency(%q<jeweler>, [">= 0"])
30
52
  s.add_runtime_dependency(%q<rake>, [">= 0"])
53
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
54
+ s.add_runtime_dependency(%q<i18n>, [">= 0"])
55
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
31
56
  s.add_runtime_dependency(%q<activeresource>, [">= 0"])
32
57
  else
33
- s.add_dependency(%q<activeresource>, [">= 0"])
34
- s.add_dependency(%q<jeweler>, [">= 0"])
35
58
  s.add_dependency(%q<rake>, [">= 0"])
59
+ s.add_dependency(%q<activesupport>, [">= 0"])
60
+ s.add_dependency(%q<i18n>, [">= 0"])
61
+ s.add_dependency(%q<jeweler>, [">= 0"])
36
62
  s.add_dependency(%q<activeresource>, [">= 0"])
37
63
  end
38
64
  else
39
- s.add_dependency(%q<activeresource>, [">= 0"])
40
- s.add_dependency(%q<jeweler>, [">= 0"])
41
65
  s.add_dependency(%q<rake>, [">= 0"])
66
+ s.add_dependency(%q<activesupport>, [">= 0"])
67
+ s.add_dependency(%q<i18n>, [">= 0"])
68
+ s.add_dependency(%q<jeweler>, [">= 0"])
42
69
  s.add_dependency(%q<activeresource>, [">= 0"])
43
70
  end
44
71
  end
@@ -2,8 +2,19 @@ require 'spec_helper'
2
2
 
3
3
  describe Shelltoad::Error do
4
4
 
5
- it "should view issue" do
6
- Shelltoad.output(Shelltoad::Error.magic_find(TEST_ERROR).view)
5
+ subject { Shelltoad::Error.magic_find(TEST_ERROR % 1000) }
6
+
7
+ its(:view) { should_not be_empty }
8
+
9
+ describe ".all" do
10
+ it "should return the list of errors" do
11
+ described_class.all.should_not be_empty
12
+ end
7
13
  end
14
+
15
+ its(:resolve!) { should be_true}
16
+
17
+ its(:url) {should == URI.parse("http://startdatelabs.hoptoadapp.com/errors/#{TEST_ERROR}")}
18
+
8
19
 
9
20
  end
@@ -10,7 +10,7 @@ describe Shelltoad do
10
10
  end
11
11
 
12
12
  describe ".run" do
13
- [["error", TEST_ERROR], "errors", "commit", TEST_ERROR].each do |command|
13
+ [["error", TEST_ERROR], "errors", "commit", TEST_ERROR, ["resolve", TEST_ERROR]].each do |command|
14
14
  describe "command:#{command.inspect}" do
15
15
  subject { Shelltoad.run(*Array(command)) }
16
16
  it { should_not be_nil }
data/spec/spec_helper.rb CHANGED
@@ -1,16 +1,16 @@
1
1
  require 'rubygems'
2
+ require "bundler"
3
+ Bundler.setup
2
4
  require "net/http"
3
- require 'spec'
4
- require 'spec/autorun'
5
+ require 'rspec'
5
6
  require "mocha"
6
- require 'active_record'
7
7
  require "fakeweb"
8
8
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__),'..','lib'))
9
9
  require "shelltoad"
10
10
 
11
11
  TEST_ERROR = 4040123
12
12
 
13
- Spec::Runner.configure do |config|
13
+ RSpec.configure do |config|
14
14
  end
15
15
 
16
16
  FakeWeb.allow_net_connect = false
@@ -24,40 +24,11 @@ FakeWeb.register_uri(
24
24
  %r|http://startdatelabs.hoptoadapp.com/errors/#{TEST_ERROR}.xml|,
25
25
  :body => File.new("spec/assets/error.xml").read
26
26
  )
27
+ FakeWeb.register_uri(
28
+ :post,
29
+ "http://startdatelabs.hoptoadapp.com/errors/4040123" ,
30
+ :body => File.read('spec/assets/error.xml')
31
+ )
27
32
 
28
33
  Shelltoad.const_set("STDOUT", "")
29
34
 
30
-
31
-
32
- class Net::HTTP
33
-
34
- alias_method :request_without_log, :request
35
-
36
- def request(request, body = nil, &block)
37
- url = "http#{"s" if self.use_ssl?}://#{self.address}:#{self.port}#{request.path}"
38
- rails_log("HTTP #{request.method}", url)
39
- rails_log("POST params", request.body) if request.is_a?(::Net::HTTP::Post)
40
- res = request_without_log(request, body, &block)
41
- rails_log("Response body", res.body) if res
42
- res
43
- end
44
-
45
- def rails_log(message, dump)
46
- if started? && defined?(Rails)
47
- Rails.logger.debug(format_log_entry(message, dump))
48
- end
49
- end
50
-
51
- def format_log_entry(message, dump = nil)
52
- if ActiveRecord::Base.colorize_logging
53
- message_color, dump_color = "4;32;1", "0;1"
54
- log_entry = " \e[#{message_color}m#{message}\e[0m "
55
- log_entry << "\e[#{dump_color}m%#{String === dump ? 's' : 'p'}\e[0m" % dump if dump
56
- log_entry
57
- else
58
- "%s %s" % [message, dump]
59
- end
60
- end
61
-
62
- end
63
-
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shelltoad
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 0
10
- version: 0.2.0
9
+ - 2
10
+ version: 0.2.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Bogdan Gusiev
@@ -15,12 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-23 00:00:00 +02:00
18
+ date: 2011-03-25 00:00:00 +02:00
19
19
  default_executable: shelltoad
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- prerelease: false
23
- name: activeresource
22
+ name: rake
24
23
  version_requirements: &id001 !ruby/object:Gem::Requirement
25
24
  none: false
26
25
  requirements:
@@ -32,9 +31,9 @@ dependencies:
32
31
  version: "0"
33
32
  requirement: *id001
34
33
  type: :runtime
35
- - !ruby/object:Gem::Dependency
36
34
  prerelease: false
37
- name: jeweler
35
+ - !ruby/object:Gem::Dependency
36
+ name: activesupport
38
37
  version_requirements: &id002 !ruby/object:Gem::Requirement
39
38
  none: false
40
39
  requirements:
@@ -46,9 +45,9 @@ dependencies:
46
45
  version: "0"
47
46
  requirement: *id002
48
47
  type: :runtime
49
- - !ruby/object:Gem::Dependency
50
48
  prerelease: false
51
- name: rake
49
+ - !ruby/object:Gem::Dependency
50
+ name: i18n
52
51
  version_requirements: &id003 !ruby/object:Gem::Requirement
53
52
  none: false
54
53
  requirements:
@@ -60,9 +59,9 @@ dependencies:
60
59
  version: "0"
61
60
  requirement: *id003
62
61
  type: :runtime
63
- - !ruby/object:Gem::Dependency
64
62
  prerelease: false
65
- name: activeresource
63
+ - !ruby/object:Gem::Dependency
64
+ name: jeweler
66
65
  version_requirements: &id004 !ruby/object:Gem::Requirement
67
66
  none: false
68
67
  requirements:
@@ -73,7 +72,22 @@ dependencies:
73
72
  - 0
74
73
  version: "0"
75
74
  requirement: *id004
75
+ type: :development
76
+ prerelease: false
77
+ - !ruby/object:Gem::Dependency
78
+ name: activeresource
79
+ version_requirements: &id005 !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ requirement: *id005
76
89
  type: :runtime
90
+ prerelease: false
77
91
  description: |
78
92
 
79
93