pt_logger 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3@pt_logger --create
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ # These are specific configuration settings required for travis-ci
2
+ # see http://travis-ci.org/evendis/pt_logger
3
+ language: ruby
4
+ rvm:
5
+ # - 1.8.7
6
+ # - 1.9.2
7
+ - 1.9.3
8
+ # - rbx-18mode
9
+ # - rbx-19mode
10
+ # - jruby-18mode
11
+ # - jruby-19mode
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pt_logger.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,10 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2, :all_on_start => false, :all_after_pass => false do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/pt_logger/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ end
10
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Paul Gallagher
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # PtLogger [![Build Status](https://secure.travis-ci.org/evendis/pt_logger.png?branch=master)](http://travis-ci.org/evendis/pt_logger)
2
+
3
+ PtLogger is a simple way to log messages to Pivotal tracker stories.
4
+
5
+ The main motivation for this is for situations where you may be facing an as-yet unreproduceable
6
+ bug or issue and you want to collect more specific information, possibly even from production environments.
7
+
8
+ What you might do is add some special instrumentation and logging. But instead of having to go check the
9
+ log files every so often, wouldn't it be nice if the information you are collecting gets automatically added
10
+ to the related Pivotal Tracker story you are working on?
11
+
12
+ That's what PtLogger is for.
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ gem 'pt_logger'
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install pt_logger
27
+
28
+ ## Contributing
29
+
30
+ 1. Fork it
31
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
32
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
33
+ 4. Push to the branch (`git push origin my-new-feature`)
34
+ 5. Create new Pull Request
35
+
36
+ ## How to run tests
37
+
38
+ Test are implemented using rspec. Run tests with <tt>rake</tt> or <tt>rake spec</tt>.
39
+
40
+ [Guard](https://rubygems.org/gems/guard) is installed as part of the development dependencies,
41
+ so to start continuous test execution on file change, start it up with <tt>bundle exec guard</tt>.
42
+
43
+ # The PtLogger Cookbook
44
+
45
+ ## How to configure PtLogger
46
+
47
+ Configuration is done using a setup block. In a Rails application, you would normally do this in
48
+ and initializer e.g. config/initializers/pt_logger.rb
49
+
50
+ PtLogger.setup do |config|
51
+ config.api_key = 'xxxxx'
52
+ config.project_id = 'yyyyy'
53
+ end
54
+
55
+ The API Key and PT project settings are global in nature. It is explicity assumed that all logging
56
+ within the project should be done with a single API Key and to the same project.
57
+
58
+ NB: there currently isn't a generator to make a config file for you
59
+
60
+ ## How to log a message with explicit story ID parameter
61
+
62
+ message_text = "this is whatever you want to log. It must be a string or support a :to_s method"
63
+ story_id = "1234"
64
+ PtLogger.log(message_text,story_id)
65
+
66
+ ## How to log a message with implicit story ID
67
+
68
+ If the PT story ID is not passed as an explicit parameter to the <tt>log</tt> method,
69
+ PtLogger will attempt to find a story ID in the message text itself.
70
+ The story ID may either be prefixed with "#" or "PT:", for example:
71
+
72
+ PtLogger.log("logging a message to PT:123456 (i.e. this will be added to Pivotal Tracker story number 123456)")
73
+ PtLogger.log("alternatively #78910 (i.e. this will be added to Pivotal Tracker story number 78910)")
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec'
3
+ require 'rspec/core/rake_task'
4
+
5
+ desc "Run all test examples"
6
+ RSpec::Core::RakeTask.new do |t|
7
+ t.rspec_opts = ["-c", "-f progress"]
8
+ t.pattern = 'spec/**/*_spec.rb'
9
+ end
10
+
11
+ task :default => :spec
12
+
13
+ require 'rdoc/task'
14
+ RDoc::Task.new do |rdoc|
15
+ rdoc.main = "README.md"
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = "PT Logger"
18
+ rdoc.rdoc_files.include('README*', 'lib/**/*.rb')
19
+ end
20
+
21
+ desc "Open an irb session preloaded with this library"
22
+ task :console do
23
+ sh "irb -rubygems -I lib -r pt_logger.rb"
24
+ end
@@ -0,0 +1,9 @@
1
+ module PtLogger
2
+
3
+ def self.log(message,story_id=nil)
4
+ if pt = PtLogger::Logger.new
5
+ pt.append_story_note(message,story_id)
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,12 @@
1
+ module PtLogger
2
+
3
+ # Pivotal Tracker credentials
4
+ mattr_accessor :api_key
5
+ mattr_accessor :project_id
6
+
7
+ # Default way to setup. Yields a block that gives access to all the config variables.
8
+ def self.setup
9
+ yield self
10
+ end
11
+
12
+ end
@@ -0,0 +1,60 @@
1
+ class PtLogger::Logger
2
+
3
+ def initialize
4
+ PivotalTracker::Client.use_ssl = true
5
+ PivotalTracker::Client.token = api_key
6
+ end
7
+
8
+ def env
9
+ Rails.env
10
+ rescue
11
+ end
12
+
13
+ def api_key
14
+ PtLogger.api_key
15
+ end
16
+
17
+ def project_id
18
+ PtLogger.project_id
19
+ end
20
+
21
+ def project
22
+ @project ||= if project_id
23
+ PivotalTracker::Project.find(project_id)
24
+ end
25
+ end
26
+
27
+ # Command: appends +message+ to PT story +story_id+.
28
+ # Does nothing if +story_id+ not defined
29
+ #
30
+ # If story_id is :infer or nil: looks for a story ID in the message (either #999999999 or PT:999999999 )
31
+ #
32
+ def append_story_note(message,story_id=nil)
33
+ if (story_id ||= :infer) == :infer
34
+ story_id = extract_story_id_from(message)
35
+ end
36
+ return unless story_id
37
+ send_story_note!("[#{prepend_text}] #{message}",story_id)
38
+ end
39
+
40
+ def extract_story_id_from(message)
41
+ if matches = /(PT:|#)(\d+)(\s|$)/i.match(message)
42
+ if matches.size > 3
43
+ matches[2].to_i
44
+ end
45
+ end
46
+ end
47
+
48
+ def prepend_text
49
+ ['PtLogger',env].compact.join('::')
50
+ end
51
+
52
+ # sends the prepared +message+ as a note on +story_id+
53
+ def send_story_note!(message,story_id)
54
+ return unless project
55
+ if story = project.stories.find(story_id)
56
+ story.notes.create(:text => message, :noted_at => Time.now) # add a new note
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,3 @@
1
+ module PtLogger
2
+ VERSION = "0.0.1"
3
+ end
data/lib/pt_logger.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "active_support/core_ext"
2
+ require "pivotal-tracker"
3
+
4
+ require "pt_logger/version"
5
+ require "pt_logger/config"
6
+ require "pt_logger/base"
7
+ require "pt_logger/logger"
data/pt_logger.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pt_logger/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "pt_logger"
8
+ gem.version = PtLogger::VERSION
9
+ gem.authors = ["Paul Gallagher"]
10
+ gem.email = ["gallagher.paul@gmail.com"]
11
+ gem.description = %q{Simple way to log messages to Pivotal tracker stories}
12
+ gem.summary = %q{Provides a simple interface for logging infomation on a Pivotal Tracker story. Optionally integrates with Rails logger.}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_runtime_dependency(%q<activesupport>, [">= 3.0.3"])
21
+ gem.add_runtime_dependency(%q<pivotal-tracker>, [">= 0.5.10"])
22
+
23
+ gem.add_development_dependency(%q<bundler>, ["> 1.1.0"])
24
+ gem.add_development_dependency(%q<rake>, ["~> 0.9.2.2"])
25
+ gem.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
26
+ gem.add_development_dependency(%q<rdoc>, ["~> 3.11"])
27
+ gem.add_development_dependency(%q<guard-rspec>, ["~> 1.2.0"])
28
+ gem.add_development_dependency(%q<rb-fsevent>, ["~> 0.9.1"])
29
+ gem.add_development_dependency(%q<vcr>, ["~> 2.4"])
30
+ gem.add_development_dependency(%q<webmock>, ["~> 1.9.0"])
31
+
32
+ end
@@ -0,0 +1,236 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://www.pivotaltracker.com/services/v3/projects/703897
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - ! '*/*; q=0.5, application/xml'
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ X-Trackertoken:
15
+ - <API_KEY>
16
+ Content-Type:
17
+ - application/xml
18
+ User-Agent:
19
+ - Ruby
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: !binary |-
24
+ T0s=
25
+ headers:
26
+ !binary "Q29udGVudC1UeXBl":
27
+ - !binary |-
28
+ YXBwbGljYXRpb24veG1sOyBjaGFyc2V0PXV0Zi04
29
+ !binary "VHJhbnNmZXItRW5jb2Rpbmc=":
30
+ - !binary |-
31
+ Y2h1bmtlZA==
32
+ !binary "U3RhdHVz":
33
+ - !binary |-
34
+ MjAw
35
+ !binary "WC1Qb3dlcmVkLUJ5":
36
+ - !binary |-
37
+ UGh1c2lvbiBQYXNzZW5nZXIgKG1vZF9yYWlscy9tb2RfcmFjaykgMy4wLjE0
38
+ !binary "U2V0LUNvb2tpZQ==":
39
+ - !binary |-
40
+ dF9zZXNzaW9uPUJBaDdDRG9QWlhod2FYSmxjMTloZEVsMU9nbFVhVzFsRFZK
41
+ TkhJQ2IlMkY4TGNCam9mUUcxaGNuTm9ZV3hmZDJsMGFGOTFkR05mWTI5bGNt
42
+ TnBiMjVHT2c5elpYTnphVzl1WDJsa0lpVmlZelF5WmpNNE9XTmxNalJpTnpZ
43
+ Mk9Ua3pNVGs1WW1Jd01qQTVOV0l4WlRvUVgyTnpjbVpmZEc5clpXNGlNV3Ny
44
+ UkZWQ2VHeEJVbWQ0YlZoQ1FrTkpVa0pzVXprMGRrNU9XblpMUm5Wb1FXcDZO
45
+ MUJrVEZkcWRUQTktLWM1YjNlMTkzZjdlMjAyMmU4YzY4NzZhYmQ2NjAwYzg2
46
+ YjZjMTg0MDc7IHBhdGg9Lzsgc2VjdXJlOyBIdHRwT25seQ==
47
+ !binary "RXRhZw==":
48
+ - !binary |-
49
+ IjAyNGYyYzhmNDlkYmI5OWQ1OTQwNGRhMWRmMzE0YzQxIg==
50
+ !binary "Q2FjaGUtQ29udHJvbA==":
51
+ - !binary |-
52
+ cHJpdmF0ZSwgbWF4LWFnZT0wLCBtdXN0LXJldmFsaWRhdGU=
53
+ !binary "WC1SdW50aW1l":
54
+ - !binary |-
55
+ OTA=
56
+ !binary "U2VydmVy":
57
+ - !binary |-
58
+ bmdpbngvMS4yLjIgKyBQaHVzaW9uIFBhc3NlbmdlciAzLjAuMTQgKG1vZF9y
59
+ YWlscy9tb2RfcmFjayk=
60
+ !binary "Q29udGVudC1FbmNvZGluZw==":
61
+ - !binary |-
62
+ Z3ppcA==
63
+ body:
64
+ encoding: ASCII-8BIT
65
+ string: !binary |-
66
+ H4sIAAAAAAAAA4VUS4+bMBC+769AnNM1kKj7kNfbHtqoh2pX6vZsOTABd42N
67
+ bJM0/75jAyHJdlsJCfubb97joY+/W5XswDpp9EOaX2dpAro0ldT1Q/rz5euH
68
+ 2/SRXdHOml9QenaVJFRW7CZb3t7dUILHgGjRAlsb1HnS3zQl8R6pHqzwaJor
69
+ 0LVvEn/o4CGV2kMNNmU5mrigRL09wCt3XljPK3Fg343GHyUXcGB26NVzVwoF
70
+ LFvki2KxpOQUDCRRlqbXnn3Zga6ko2QCgnArrfN8DmNw62ULY7SV8BCuKSuy
71
+ fEmyFcnyJMvu45f8WL9Q8r6NmE7ZWwsY5uxE9+0G7F/K8R412gEtNgq4F+7V
72
+ jbobYxQInTJve6DklBFVdqBMKf0BS9QAduUz9lrUkJhtskyO8WBJLomncU8y
73
+ lmeUTBEewcCUWnopFD9jvgEDc8icmy2vjIa5JI57w11j9iwvcIJiff7FCraU
74
+ 2IByjJLxMGDYTVF6uQtZC/9+E1dJVtznq/tVMTRRiXPNWD+hlNmjGS/KpsUe
75
+ urHQb/HA7vqNkiXbCuWwGeMtCHoHvPG+c5NsBoJ409eOC13xsjEW8GiBg8Oh
76
+ Ez50fFL6Hy2YKk3bSs9bUx3VTqFAaSEU1zWym6ZIWCsOaUj4TDwACOE7Lz5m
77
+ xaq4m958ZHZoxeiJhQC0QipWY3FE3YC97kSvPtUBvMYgcDyjPLqJBuKieEZS
78
+ sp505u0xcsYpcux5jc6HOXPHyMh5DNTic2BPew2WkngeciJzzrGtJ/doCwcY
79
+ V9Kwq94WJfidxbgOyXEf/gHwU9T2QQUAAA==
80
+ http_version:
81
+ recorded_at: Wed, 03 Apr 2013 18:55:12 GMT
82
+ - request:
83
+ method: get
84
+ uri: https://www.pivotaltracker.com/services/v3/projects/703897/stories/47387051
85
+ body:
86
+ encoding: US-ASCII
87
+ string: ''
88
+ headers:
89
+ Accept:
90
+ - ! '*/*; q=0.5, application/xml'
91
+ Accept-Encoding:
92
+ - gzip, deflate
93
+ X-Trackertoken:
94
+ - <API_KEY>
95
+ Content-Type:
96
+ - application/xml
97
+ User-Agent:
98
+ - Ruby
99
+ response:
100
+ status:
101
+ code: 200
102
+ message: !binary |-
103
+ T0s=
104
+ headers:
105
+ !binary "Q29udGVudC1UeXBl":
106
+ - !binary |-
107
+ YXBwbGljYXRpb24veG1sOyBjaGFyc2V0PXV0Zi04
108
+ !binary "VHJhbnNmZXItRW5jb2Rpbmc=":
109
+ - !binary |-
110
+ Y2h1bmtlZA==
111
+ !binary "U3RhdHVz":
112
+ - !binary |-
113
+ MjAw
114
+ !binary "WC1Qb3dlcmVkLUJ5":
115
+ - !binary |-
116
+ UGh1c2lvbiBQYXNzZW5nZXIgKG1vZF9yYWlscy9tb2RfcmFjaykgMy4wLjE0
117
+ !binary "RXRhZw==":
118
+ - !binary |-
119
+ IjQ5ZjgyMDQzODM2MjgzNzFiOTI0ZDY0NDhiYzAyOWE4Ig==
120
+ !binary "Q2FjaGUtQ29udHJvbA==":
121
+ - !binary |-
122
+ cHJpdmF0ZSwgbWF4LWFnZT0wLCBtdXN0LXJldmFsaWRhdGU=
123
+ !binary "WC1SdW50aW1l":
124
+ - !binary |-
125
+ Njc=
126
+ !binary "U2V0LUNvb2tpZQ==":
127
+ - !binary |-
128
+ dF9zZXNzaW9uPUJBaDdDRG9QWlhod2FYSmxjMTloZEVsMU9nbFVhVzFsRFZK
129
+ TkhJRHR5dGJjQmpvZlFHMWhjbk5vWVd4ZmQybDBhRjkxZEdOZlkyOWxjbU5w
130
+ YjI1R09nOXpaWE56YVc5dVgybGtJaVV3WW1KaE9HWTRaRE16WVRFM1pHSTBN
131
+ REF5WmpFMU9EZGpZV1EwT1dJeE56b1FYMk56Y21aZmRHOXJaVzRpTVdGd1N5
132
+ dGhXRVJNVTNkbVJVWTJaRXBZUTAweUwySmhWRFZ6TlZOTFJIaENiSGhRVldw
133
+ cGFrRjRPR2M5LS1jZjljYjViYWYxNWQ4Yjc1ZWQ5Yjg5MzRjNzQzMDJhMGUz
134
+ OTdlMTFkOyBwYXRoPS87IHNlY3VyZTsgSHR0cE9ubHk=
135
+ !binary "U2VydmVy":
136
+ - !binary |-
137
+ bmdpbngvMS4yLjIgKyBQaHVzaW9uIFBhc3NlbmdlciAzLjAuMTQgKG1vZF9y
138
+ YWlscy9tb2RfcmFjayk=
139
+ !binary "Q29udGVudC1FbmNvZGluZw==":
140
+ - !binary |-
141
+ Z3ppcA==
142
+ body:
143
+ encoding: ASCII-8BIT
144
+ string: !binary |-
145
+ H4sIAAAAAAAAA81VS4+bMBC+51dY3De2eSwPOd5b99JDpKanqopcmAVawNSY
146
+ zebf1zbQZBVVW2n3gMSBeXzj+WbGY/bw0jboGdRQy27n0S3xEHS5LOqu3Hlf
147
+ D5/uEu+Bb9igpTrzDUKsLpA+97Dz6k5DCcrjYRwkMYkow3XhXHolf0Kuj7eu
148
+ MQmSNGb44uEALvrRhuV5JRUwfKWxDqNqeKV1n2F8Op22ff0stWi0EvkvUNtc
149
+ thMAD5U84Us+Fmbh+agUdPo4aKGBj92QV1CMDRQMvzZZ5wKGXNW9NgXhDF9L
150
+ 1tqJFvhef5al4Y40DBoUw05rzQp+j1ZXHH+c+V6MDXoUTSPKynq9Mrq8FJiE
151
+ iqPQc00LI+q6BY/7hAaYhOZDhGZRnBGKvjweTMJ/Me7AsbeYN0P4GQ2z0J9C
152
+ XDAuRCcNjTkBoZQ4e1Y9G6ZfI9w2MyR+kKZRuvTdYTS8aP5tKdB3JFyNUAvD
153
+ IEpAT9IUrQK0P2RLm5DrNcMO6Q42YcSozSDcVHBWL1428zepm+olhv1EfUHM
154
+ DLGV/5ttSIJ47Wz9jPhZSD6E7X0QrLy3hm2URfPNeGdvU98spmmDrXSSDds0
155
+ o/Mlfh9bSu+j1bOlhvCHTDINkvVP8tWC/ldvzUNjd7V5j6f3jm/+AFeapkDA
156
+ BwAA
157
+ http_version:
158
+ recorded_at: Wed, 03 Apr 2013 18:55:13 GMT
159
+ - request:
160
+ method: post
161
+ uri: https://www.pivotaltracker.com/services/v3/projects/703897/stories/47387051/notes
162
+ body:
163
+ encoding: US-ASCII
164
+ string: ! "<?xml version=\"1.0\"?>\n<note>\n <text>[PtLogger] a test message
165
+ for the PT:47387051 story</text>\n <noted_at>2013-04-04 02:55:13 +0800</noted_at>\n</note>\n"
166
+ headers:
167
+ Accept:
168
+ - ! '*/*; q=0.5, application/xml'
169
+ Accept-Encoding:
170
+ - gzip, deflate
171
+ X-Trackertoken:
172
+ - <API_KEY>
173
+ Content-Type:
174
+ - application/xml
175
+ Content-Length:
176
+ - '153'
177
+ User-Agent:
178
+ - Ruby
179
+ response:
180
+ status:
181
+ code: 200
182
+ message: !binary |-
183
+ T0s=
184
+ headers:
185
+ !binary "Q29udGVudC1UeXBl":
186
+ - !binary |-
187
+ YXBwbGljYXRpb24veG1sOyBjaGFyc2V0PXV0Zi04
188
+ !binary "VHJhbnNmZXItRW5jb2Rpbmc=":
189
+ - !binary |-
190
+ Y2h1bmtlZA==
191
+ !binary "U3RhdHVz":
192
+ - !binary |-
193
+ MjAw
194
+ !binary "WC1Qb3dlcmVkLUJ5":
195
+ - !binary |-
196
+ UGh1c2lvbiBQYXNzZW5nZXIgKG1vZF9yYWlscy9tb2RfcmFjaykgMy4wLjE0
197
+ !binary "TG9jYXRpb24=":
198
+ - !binary |-
199
+ aHR0cHM6Ly93d3cucGl2b3RhbHRyYWNrZXIuY29tL3NlcnZpY2VzL3YzL3By
200
+ b2plY3RzLzcwMzg5Ny9zdG9yaWVzLzQ3Mzg3MDUxL25vdGVzLzQwMjQ1MzE1
201
+ !binary "RXRhZw==":
202
+ - !binary |-
203
+ ImY1NjA5ZWFmNWVmNDQyM2M4OTNlYzdiODBmMDc5Y2RjIg==
204
+ !binary "Q2FjaGUtQ29udHJvbA==":
205
+ - !binary |-
206
+ cHJpdmF0ZSwgbWF4LWFnZT0wLCBtdXN0LXJldmFsaWRhdGU=
207
+ !binary "WC1SdW50aW1l":
208
+ - !binary |-
209
+ MTE3
210
+ !binary "U2V0LUNvb2tpZQ==":
211
+ - !binary |-
212
+ dF9zZXNzaW9uPUJBaDdDRG9QWlhod2FYSmxjMTloZEVsMU9nbFVhVzFsRFZK
213
+ TkhJQndJZXpjQmpvZlFHMWhjbk5vWVd4ZmQybDBhRjkxZEdOZlkyOWxjbU5w
214
+ YjI1R09nOXpaWE56YVc5dVgybGtJaVV3T1dFeU16VmtPR0poTlRFM04yVTNN
215
+ amczWTJKbFpURTRPVEZqWkdSbFpqb1FYMk56Y21aZmRHOXJaVzRpTVZSRlVE
216
+ aE9lalZoVEZwVkszbFZaMUpMY0VOcU9YcFdLMUJ4VGpob1RsbzNhbWR1VVVK
217
+ aWRXMUJkSE05LS1jYTE3OWFjYjY2YmM3ZjExYWYxM2ZhYTc1MzQzN2YxN2Rj
218
+ ODIxODhkOyBwYXRoPS87IHNlY3VyZTsgSHR0cE9ubHk=
219
+ !binary "U2VydmVy":
220
+ - !binary |-
221
+ bmdpbngvMS4yLjIgKyBQaHVzaW9uIFBhc3NlbmdlciAzLjAuMTQgKG1vZF9y
222
+ YWlscy9tb2RfcmFjayk=
223
+ !binary "Q29udGVudC1FbmNvZGluZw==":
224
+ - !binary |-
225
+ Z3ppcA==
226
+ body:
227
+ encoding: ASCII-8BIT
228
+ string: !binary |-
229
+ H4sIAAAAAAAAAzWPwWrDMBBE7/6KRfdWki2RYGTl1lx6MNQ9lVJEtZEFtlWk
230
+ TUn+vrZJYQ7L8GaZMafbPMEv5hLT0jH5LBjg8p18XELH3oeXpyM72cosidBW
231
+ ACZ6oPsPdiwuhAEzs0rUSjdSGx79jhDeyH709JrCCnyCA8JCMGMpLiBcUgYa
232
+ EfqhVYfmeBBaQqGU74bvye2Fu9KYsu3ddYKzmyYXRsyGP+yN2Ar5L0ePNt4R
233
+ UpyR2VrIhgu1CkTdat1KBW/nwfD/xLpmv231Bw4ua0z9AAAA
234
+ http_version:
235
+ recorded_at: Wed, 03 Apr 2013 18:55:14 GMT
236
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe PtLogger do
4
+ let(:resource_class) { PtLogger }
5
+
6
+ before do
7
+ set_test_credentials
8
+ end
9
+
10
+ context "with embedded story id", :vcr do
11
+ let(:message) { "a test message for the PT:#{test_story_id} story" }
12
+ subject { resource_class.log(message) }
13
+ it "logs successfully" do
14
+ should be_a(PivotalTracker::Note)
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Test Credentials" do
4
+ real_credentials_available?
5
+ end
@@ -0,0 +1,35 @@
1
+ require 'pt_logger'
2
+
3
+ require 'vcr'
4
+ VCR.configure do |c|
5
+ c.cassette_library_dir = "spec/fixtures/cassettes"
6
+ c.hook_into :webmock
7
+ c.configure_rspec_metadata!
8
+ c.filter_sensitive_data('<API_KEY>') { (ENV['TEST_PTLOGGER_API_KEY'] || 'fakeapikey') }
9
+ end
10
+
11
+ # Requires supporting files with custom matchers and macros, etc,
12
+ # in ./support/ and its subdirectories.
13
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
14
+
15
+ RSpec.configure do |config|
16
+ config.treat_symbols_as_metadata_keys_with_true_values = true
17
+
18
+ # == Mock Framework
19
+ #
20
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
21
+ #
22
+ # config.mock_with :mocha
23
+ # config.mock_with :flexmock
24
+ # config.mock_with :rr
25
+ config.mock_with :rspec
26
+
27
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
28
+ # config.fixture_path = "#{::Rails.root}/spec/fixtures"
29
+
30
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
31
+ # examples within a transaction, remove the following line or assign false
32
+ # instead of true.
33
+ # config.use_transactional_fixtures = true
34
+
35
+ end
@@ -0,0 +1,54 @@
1
+ module CredentialsHelper
2
+
3
+ # Command: sets test PT credentials
4
+ def set_test_credentials
5
+ PtLogger.setup do |config|
6
+ config.api_key = test_api_key
7
+ config.project_id = test_project_id
8
+ end
9
+ end
10
+
11
+ # Returns true if real PT credentials have been configured
12
+ def real_credentials_available?
13
+ if real_api_key
14
+ STDERR.puts %{
15
+ NOTE: real PT credentials are configured so if the integration tests are missing request cassettes,
16
+ live queries will be performed to record the actual interaction.
17
+ }
18
+ true
19
+ else
20
+ STDERR.puts %{
21
+ NOTE: real PT credentials are not configured so if the integration tests are missing request cassettes,
22
+ they will fail. Set real PT credentials with environment variables:
23
+
24
+ export TEST_PTLOGGER_API_KEY=your_api_key
25
+
26
+ }
27
+ false
28
+ end
29
+ end
30
+
31
+ # Returns the API Key to use for tests
32
+ def test_api_key
33
+ real_api_key || 'fakeapikey'
34
+ end
35
+ def real_api_key
36
+ ENV['TEST_PTLOGGER_API_KEY']
37
+ end
38
+
39
+ # Returns the project ID to use for tests
40
+ def test_project_id
41
+ '703897'
42
+ end
43
+
44
+ # Returns the story ID to use for tests
45
+ def test_story_id
46
+ '47387051'
47
+ end
48
+
49
+ end
50
+
51
+ RSpec.configure do |conf|
52
+ conf.extend CredentialsHelper
53
+ conf.include CredentialsHelper
54
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe PtLogger do
4
+ let(:resource_class) { PtLogger }
5
+ let(:logger_class) { PtLogger::Logger }
6
+
7
+ describe "##log" do
8
+ subject { resource_class.log(message) }
9
+ context "when story_id is defined in the message" do
10
+ let(:message) { "test message for story #12345678" }
11
+ let(:expected_message) { "[PtLogger] test message for story #12345678" }
12
+ let(:expected_story_id) { 12345678 }
13
+ it "should not call send_story_note!" do
14
+ logger_class.any_instance.should_receive(:send_story_note!).with(expected_message,expected_story_id).and_return(nil)
15
+ subject
16
+ end
17
+ end
18
+ context "when story_id is not defined" do
19
+ let(:message) { "test message without ID" }
20
+ it "should not call send_story_note!" do
21
+ logger_class.any_instance.should_receive(:send_story_note!).never
22
+ subject
23
+ end
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe PtLogger do
4
+ let(:resource) { PtLogger }
5
+
6
+ ['api_key','project_id'].each do |string_config_option|
7
+ describe "##{string_config_option}" do
8
+ subject { resource.send(string_config_option) }
9
+
10
+ let(:expected) { 'somthing' }
11
+ before do
12
+ resource.send("#{string_config_option}=",expected)
13
+ end
14
+ it { should eql(expected) }
15
+
16
+ end
17
+ end
18
+
19
+ describe "##setup" do
20
+ let(:api_key) { 'somthing' }
21
+ before do
22
+ resource.setup do |config|
23
+ config.api_key = api_key
24
+ end
25
+ end
26
+ subject { resource }
27
+ its(:api_key) { should eql(api_key) }
28
+ end
29
+
30
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ describe PtLogger::Logger do
4
+
5
+ let(:resource_class) { PtLogger::Logger }
6
+ let(:instance) { resource_class.new }
7
+
8
+ context "when configured" do
9
+ let(:api_key) { 'somthing' }
10
+ let(:project_id) { 'somthingelse' }
11
+
12
+ before do
13
+ PtLogger.setup do |config|
14
+ config.api_key = api_key
15
+ config.project_id = project_id
16
+ end
17
+ end
18
+
19
+ describe "#api_key" do
20
+ subject { instance.api_key }
21
+ it { should_not be_nil }
22
+ end
23
+
24
+ describe "#project_id" do
25
+ subject { instance.project_id }
26
+ it { should_not be_nil }
27
+ end
28
+
29
+ describe "#project" do
30
+ let(:mock_project) { mock() }
31
+ before do
32
+ PivotalTracker::Project.stub(:find).and_return(mock_project)
33
+ end
34
+ subject { instance.project }
35
+ it { should eql(mock_project) }
36
+ end
37
+
38
+ end
39
+
40
+ describe "#extract_story_id_from" do
41
+ subject { instance.extract_story_id_from(message) }
42
+ [
43
+ { given: 'contains no story ref', expect: nil},
44
+ { given: 'contains #12 ref', expect: 12},
45
+ { given: 'contains at end of string #123', expect: 123},
46
+ { given: '#1234 contains at start of string', expect: 1234},
47
+ { given: 'contains pt PT:12345 ref', expect: 12345},
48
+ { given: 'contains pt lowercase pt:123456 ref', expect: 123456},
49
+ { given: 'contains #1234embeded ref', expect: nil}
50
+ ].each do |expectations|
51
+ context "when given '#{expectations[:given]}'" do
52
+ let(:message) { expectations[:given] }
53
+ it { should eql(expectations[:expect]) }
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "#append_story_note" do
59
+ subject { instance.append_story_note(message) }
60
+ context "when story_id is defined in the message" do
61
+ let(:message) { "test message for story #12345678" }
62
+ let(:expected_message) { "[PtLogger] test message for story #12345678" }
63
+ let(:expected_story_id) { 12345678 }
64
+ it "should not call send_story_note!" do
65
+ instance.should_receive(:send_story_note!).with(expected_message,expected_story_id).and_return(nil)
66
+ subject
67
+ end
68
+ end
69
+ context "when story_id is not defined" do
70
+ let(:message) { "test message without ID" }
71
+ it "should not call send_story_note!" do
72
+ instance.should_receive(:send_story_note!).never
73
+ subject
74
+ end
75
+ end
76
+ context "when story_id is defined explicitly" do
77
+ subject { instance.append_story_note(message,story_id) }
78
+ let(:message) { "test message for story #12345678" }
79
+ let(:story_id) { 87654321 }
80
+ let(:expected_message) { "[PtLogger] test message for story #12345678" }
81
+ let(:expected_story_id) { 87654321 }
82
+ it "should not call send_story_note!" do
83
+ instance.should_receive(:send_story_note!).with(expected_message,expected_story_id).and_return(nil)
84
+ subject
85
+ end
86
+ end
87
+ end
88
+
89
+
90
+ end
metadata ADDED
@@ -0,0 +1,237 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pt_logger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Paul Gallagher
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.0.3
30
+ - !ruby/object:Gem::Dependency
31
+ name: pivotal-tracker
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 0.5.10
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 0.5.10
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>'
52
+ - !ruby/object:Gem::Version
53
+ version: 1.1.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>'
60
+ - !ruby/object:Gem::Version
61
+ version: 1.1.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.9.2.2
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.9.2.2
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 2.8.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 2.8.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: rdoc
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '3.11'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '3.11'
110
+ - !ruby/object:Gem::Dependency
111
+ name: guard-rspec
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 1.2.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 1.2.0
126
+ - !ruby/object:Gem::Dependency
127
+ name: rb-fsevent
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 0.9.1
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 0.9.1
142
+ - !ruby/object:Gem::Dependency
143
+ name: vcr
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: '2.4'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: '2.4'
158
+ - !ruby/object:Gem::Dependency
159
+ name: webmock
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ~>
164
+ - !ruby/object:Gem::Version
165
+ version: 1.9.0
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ~>
172
+ - !ruby/object:Gem::Version
173
+ version: 1.9.0
174
+ description: Simple way to log messages to Pivotal tracker stories
175
+ email:
176
+ - gallagher.paul@gmail.com
177
+ executables: []
178
+ extensions: []
179
+ extra_rdoc_files: []
180
+ files:
181
+ - .gitignore
182
+ - .rspec
183
+ - .rvmrc
184
+ - .travis.yml
185
+ - Gemfile
186
+ - Guardfile
187
+ - LICENSE.txt
188
+ - README.md
189
+ - Rakefile
190
+ - lib/pt_logger.rb
191
+ - lib/pt_logger/base.rb
192
+ - lib/pt_logger/config.rb
193
+ - lib/pt_logger/logger.rb
194
+ - lib/pt_logger/version.rb
195
+ - pt_logger.gemspec
196
+ - spec/fixtures/cassettes/PtLogger/with_embedded_story_id/logs_successfully.yml
197
+ - spec/integration/base_spec.rb
198
+ - spec/integration/credentials_spec.rb
199
+ - spec/spec_helper.rb
200
+ - spec/support/credentials_helper.rb
201
+ - spec/unit/base_spec.rb
202
+ - spec/unit/config_spec.rb
203
+ - spec/unit/logger_spec.rb
204
+ homepage: ''
205
+ licenses: []
206
+ post_install_message:
207
+ rdoc_options: []
208
+ require_paths:
209
+ - lib
210
+ required_ruby_version: !ruby/object:Gem::Requirement
211
+ none: false
212
+ requirements:
213
+ - - ! '>='
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ required_rubygems_version: !ruby/object:Gem::Requirement
217
+ none: false
218
+ requirements:
219
+ - - ! '>='
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
222
+ requirements: []
223
+ rubyforge_project:
224
+ rubygems_version: 1.8.23
225
+ signing_key:
226
+ specification_version: 3
227
+ summary: Provides a simple interface for logging infomation on a Pivotal Tracker story.
228
+ Optionally integrates with Rails logger.
229
+ test_files:
230
+ - spec/fixtures/cassettes/PtLogger/with_embedded_story_id/logs_successfully.yml
231
+ - spec/integration/base_spec.rb
232
+ - spec/integration/credentials_spec.rb
233
+ - spec/spec_helper.rb
234
+ - spec/support/credentials_helper.rb
235
+ - spec/unit/base_spec.rb
236
+ - spec/unit/config_spec.rb
237
+ - spec/unit/logger_spec.rb