shelltoad 0.2.0 → 0.2.2

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