gitwakatime 0.2.2 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +22 -0
- data/.gitignore +1 -0
- data/.travis.yml +2 -1
- data/README.md +7 -5
- data/Rakefile +9 -3
- data/bin/gitwakatime +1 -2
- data/gitwakatime.gemspec +2 -8
- data/lib/gitwakatime.rb +9 -3
- data/lib/gitwakatime/cli.rb +14 -2
- data/lib/gitwakatime/commit.rb +7 -3
- data/lib/gitwakatime/commited_file.rb +6 -5
- data/lib/gitwakatime/controller.rb +10 -7
- data/lib/gitwakatime/durations_calculator.rb +42 -0
- data/lib/gitwakatime/mapper.rb +8 -7
- data/lib/gitwakatime/query.rb +29 -57
- data/lib/gitwakatime/request.rb +24 -0
- data/lib/gitwakatime/request_builder.rb +36 -0
- data/lib/gitwakatime/timer.rb +8 -19
- data/lib/gitwakatime/version.rb +1 -1
- data/spec/cli_spec.rb +12 -4
- data/spec/commited_file_spec.rb +0 -1
- data/spec/durations_spec.rb +1 -15
- data/spec/fixtures/heartbeats.json +4222 -4516
- data/spec/fixtures/wakatime.yml +3 -0
- data/spec/mapper_spec.rb +2 -2
- data/spec/query_spec.rb +29 -13
- data/spec/request_builder_spec.rb +21 -0
- data/spec/spec_helper.rb +10 -24
- data/spec/timer_spec.rb +30 -14
- metadata +14 -24
- data/lib/gitwakatime/durations.rb +0 -96
data/spec/mapper_spec.rb
CHANGED
@@ -26,9 +26,9 @@ describe 'description' do
|
|
26
26
|
|
27
27
|
it 'maps files dependent commits' do
|
28
28
|
expect(
|
29
|
-
GitWakaTime::Commit.all.
|
29
|
+
GitWakaTime::Commit.all.find do |c|
|
30
30
|
c.sha == 'dcd748bd06b8a0f239d779bee4f1eaf1f4aa500d'
|
31
|
-
end.
|
31
|
+
end.commited_files.first.dependent_sha
|
32
32
|
).to eq '2254dd56976b5f32a2289438842e42a35a18ff86'
|
33
33
|
end
|
34
34
|
end
|
data/spec/query_spec.rb
CHANGED
@@ -1,35 +1,51 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe GitWakaTime::Query do
|
4
4
|
|
5
5
|
before(:each) do
|
6
6
|
GitWakaTime.config.git = Git.open(@wdir)
|
7
7
|
GitWakaTime::Mapper.new(start_at: Date.new(2015, 1, 24))
|
8
|
-
@commits = GitWakaTime::Commit
|
9
|
-
@files = GitWakaTime::CommitedFile
|
10
|
-
@query = GitWakaTime::Query.new(@commits, @files, File.basename(@wdir))
|
11
8
|
end
|
12
9
|
|
10
|
+
let(:start_at) { Date.new(2015, 1, 24) }
|
11
|
+
let(:end_at) { Date.new(2015, 2, 24) }
|
12
|
+
subject(:subject) { described_class.new(start_at, end_at, File.basename(@wdir)) }
|
13
|
+
|
13
14
|
before do
|
14
|
-
stub_request(:get,
|
15
|
-
.with(query: hash_including(:
|
15
|
+
stub_request(:get, /.*wakatime.com\/api\/v1\/users\/current\/heartbeats/)
|
16
|
+
.with(query: hash_including(:date))
|
16
17
|
.to_return(body: File.read('./spec/fixtures/heartbeats.json'), status: 200)
|
17
18
|
end
|
18
19
|
|
19
|
-
it '
|
20
|
-
heartbeats =
|
20
|
+
it 'will return an array of heartbeats' do
|
21
|
+
heartbeats = subject.call
|
21
22
|
|
22
23
|
expect(heartbeats).to be_a Array
|
23
24
|
expect(heartbeats.size).to eq 9 # 10ths is lonely
|
24
25
|
expect(heartbeats.last).to be_a GitWakaTime::Heartbeat
|
25
26
|
expect(heartbeats.last.branch).to eq 'master'
|
26
27
|
end
|
27
|
-
it 'produces valid search for api' do
|
28
28
|
|
29
|
-
|
29
|
+
describe 'caching' do
|
30
|
+
it 'when heartbeats after query date return true ' do
|
31
|
+
expect(GitWakaTime::Heartbeat).to receive(:max).with(:time)
|
32
|
+
.and_return(Time.now.to_s)
|
33
|
+
expect(subject.cached?(1.month.ago)).to eq(true)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'when heartbeats after query date are the same ' do
|
37
|
+
expect(GitWakaTime::Heartbeat).to receive(:max).with(:time)
|
38
|
+
.and_return(Time.now.to_s)
|
39
|
+
|
40
|
+
expect(subject.cached?(Date.today)).to eq(false)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'when no heartbeats present' do
|
44
|
+
expect(GitWakaTime::Heartbeat).to receive(:max).with(:time)
|
45
|
+
.and_return(nil)
|
46
|
+
|
47
|
+
expect(subject.cached?(Date.today)).to eq(false)
|
48
|
+
end
|
30
49
|
|
31
|
-
expect(heartbeats).to be_a Array
|
32
|
-
expect(heartbeats.first[:start].to_date).to eq Date.new(2015, 01, 29)
|
33
|
-
expect(heartbeats.first[:end].to_date).to eq Date.new(2015, 03, 05)
|
34
50
|
end
|
35
51
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GitWakaTime::RequestBuilder do
|
4
|
+
subject(:subject) { described_class.new(3.days.ago, Time.now).call }
|
5
|
+
|
6
|
+
it 'returns a array of hashes' do
|
7
|
+
expect(subject).to be_a(Array)
|
8
|
+
expect(subject.first).to be_a(Hash)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'has a hash per day' do
|
12
|
+
expect(subject.size).to eq(4)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'has a first hash will be for 3 days ago' do
|
16
|
+
expect(subject.first).to eq(
|
17
|
+
date: 3.days.ago.to_date,
|
18
|
+
show: 'file,branch,project,time,id'
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,7 +6,11 @@
|
|
6
6
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
7
|
ENV['thor_env'] = 'test'
|
8
8
|
ENV['waka_log'] = 'false'
|
9
|
+
require 'codeclimate-test-reporter'
|
10
|
+
CodeClimate::TestReporter.start
|
9
11
|
|
12
|
+
require 'webmock/rspec'
|
13
|
+
WebMock.disable_net_connect!(allow: 'codeclimate.com')
|
10
14
|
require 'gitwakatime'
|
11
15
|
|
12
16
|
RSpec.configure do |config|
|
@@ -21,38 +25,20 @@ RSpec.configure do |config|
|
|
21
25
|
GitWakaTime::Heartbeat.new.columns
|
22
26
|
end
|
23
27
|
|
24
|
-
config.
|
25
|
-
|
26
|
-
|
27
|
-
GitWakaTime::Heartbeat.truncate
|
28
|
+
config.around(:each) do |example|
|
29
|
+
DB.transaction(rollback: :always, auto_savepoint: true) { example.run }
|
30
|
+
end
|
28
31
|
|
29
|
-
|
32
|
+
config.before(:each) do
|
33
|
+
allow(
|
30
34
|
GitWakaTime.config
|
31
|
-
).to receive('user_name').and_return('Russell Osborne')
|
35
|
+
).to receive('user_name').and_return('Russell Osborne')
|
32
36
|
end
|
33
37
|
|
34
38
|
config.after(:all) do
|
35
39
|
FileUtils.rm_r(File.dirname(@wdir))
|
36
40
|
end
|
37
41
|
end
|
38
|
-
require 'codeclimate-test-reporter'
|
39
|
-
CodeClimate::TestReporter.start
|
40
|
-
require 'webmock/rspec'
|
41
|
-
|
42
|
-
WebMock.disable_net_connect!(allow: 'codeclimate.com')
|
43
|
-
|
44
|
-
def capture(stream)
|
45
|
-
begin
|
46
|
-
stream = stream.to_s
|
47
|
-
eval "$#{stream} = StringIO.new"
|
48
|
-
yield
|
49
|
-
result = eval("$#{stream}").string
|
50
|
-
ensure
|
51
|
-
eval("$#{stream} = #{stream.upcase}")
|
52
|
-
end
|
53
|
-
|
54
|
-
result
|
55
|
-
end
|
56
42
|
|
57
43
|
def set_file_paths
|
58
44
|
@test_dir = File.join(File.dirname(__FILE__))
|
data/spec/timer_spec.rb
CHANGED
@@ -2,29 +2,45 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe 'description' do
|
4
4
|
let(:git) { Git.open(@wdir) }
|
5
|
+
let(:heartbeat) { double(:heartbeat, sum: 1) }
|
6
|
+
let(:heartbeats) { double(:heartbeats, grep: [heartbeat, heartbeat]) }
|
5
7
|
|
6
8
|
before do
|
7
|
-
stub_request(:get,
|
8
|
-
|
9
|
-
|
9
|
+
stub_request(:get, /.*wakatime.com\/api\/v1\/heartbeats/)
|
10
|
+
.with(query: hash_including(:date))
|
11
|
+
.to_return(body: File.read('./spec/fixtures/heartbeats.json'), status: 200)
|
12
|
+
|
13
|
+
# Prevent any callbacks to git.
|
14
|
+
# TODO: Refactor callbacks.
|
15
|
+
GitWakaTime.config.git = nil
|
10
16
|
end
|
11
17
|
|
12
|
-
it 'can be run on dummy' do
|
13
|
-
GitWakaTime.config.git = git
|
14
|
-
GitWakaTime::Mapper.new(start_at: Date.new(2015, 1, 24))
|
15
|
-
heartbeats = GitWakaTime::Query.new(
|
16
|
-
GitWakaTime::Commit, GitWakaTime::CommitedFile, File.basename(@wdir)
|
17
|
-
).get
|
18
|
+
it 'can be run on dummy with no heartbeats' do
|
18
19
|
timer = GitWakaTime::Timer.new(
|
19
|
-
GitWakaTime::Commit.all,
|
20
|
+
GitWakaTime::Commit.all, GitWakaTime::Heartbeat
|
20
21
|
).process
|
21
22
|
|
22
23
|
# # UTC breaks heartbeats of 1 day
|
23
24
|
# expect(timer.size).to eq 1
|
24
25
|
# With 7 relevant commits
|
25
|
-
expect(timer
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
expect(timer).to eq Hash.new
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'can be run on dummy with no heartbeats' do
|
30
|
+
c1 = GitWakaTime::Commit.create(sha: 'e493d6f2ab2a702fa7f9c168b852a3b44c524f08', parent_sha: '4c1ea35f9a811a0ef79da15ec85f25fce4c446ba', project: 'dummy', time_in_seconds: 0, date: Time.parse('2015-01-30 03:26:12 UTC'), message: 'conflicting commit on master.', author: 'Russell Osborne')
|
31
|
+
c2 = GitWakaTime::Commit.create(sha: 'd642b3c04c3025655a9c33e32b9d530696dcf7cc', parent_sha: '4c1ea35f9a811a0ef79da15ec85f25fce4c446ba', project: 'dummy', time_in_seconds: 0, date: Time.parse('2015-01-30 03:26:05 UTC'), message: 'another commit on dev.', author: 'Russell Osborne')
|
32
|
+
GitWakaTime::CommitedFile.create(commit_id: c1.id, dependent_sha: '4c1ea35f9a811a0ef79da15ec85f25fce4c446ba', dependent_date: Time.parse('2015-01-30 01:00:00 UTC'), time_in_seconds: 0, sha: 'd642b3c04c3025655a9c33e32b9d530696dcf7cc', name: '/dummy/spec/commit_spec.rb', entity: nil, project: 'dummy')
|
33
|
+
GitWakaTime::CommitedFile.create(commit_id: c2.id, dependent_sha: '4c1ea35f9a811a0ef79da15ec85f25fce4c446ba', dependent_date: Time.parse('2015-01-30 02:00:00 UTC'), time_in_seconds: 0, sha: 'd642b3c04c3025655a9c33e32b9d530696dcf7cc', name: '/dummy/lib/dummy/timer.rb', entity: nil, project: 'dummy')
|
34
|
+
GitWakaTime::Heartbeat.create(time: Time.parse('2015-01-30 02:33:00 UTC'), duration: 500, entity: '/dummy/spec/commit_spec.rb', type: 'file', branch: 'master', project: 'dummy')
|
35
|
+
GitWakaTime::Heartbeat.create(time: Time.parse('2015-01-30 02:31:54 UTC'), duration: 333, entity: '/dummy/lib/dummy/timer.rb', type: 'file', branch: 'master', project: 'dummy')
|
36
|
+
|
37
|
+
timer = GitWakaTime::Timer.new(
|
38
|
+
GitWakaTime::Commit.all, GitWakaTime::Heartbeat
|
39
|
+
).process
|
40
|
+
|
41
|
+
# One hash key per day
|
42
|
+
expect(timer.size).to eq 1
|
43
|
+
expect(timer[Date.new(2015, 1, 30)]).to be_a(Array)
|
44
|
+
expect(timer[Date.new(2015, 1, 30)].map(&:time_in_seconds).compact.reduce(&:+)).to eq(500 + 333)
|
29
45
|
end
|
30
46
|
end
|
metadata
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitwakatime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
8
|
-
- Jonas Arvidsson
|
9
|
-
- Yuji Nakayama
|
7
|
+
- Russell Osborne
|
10
8
|
autorequire:
|
11
9
|
bindir: bin
|
12
10
|
cert_chain: []
|
13
|
-
date: 2015-
|
11
|
+
date: 2015-12-18 00:00:00.000000000 Z
|
14
12
|
dependencies:
|
15
13
|
- !ruby/object:Gem::Dependency
|
16
14
|
name: git
|
@@ -40,20 +38,6 @@ dependencies:
|
|
40
38
|
- - ">="
|
41
39
|
- !ruby/object:Gem::Version
|
42
40
|
version: 0.0.2
|
43
|
-
- !ruby/object:Gem::Dependency
|
44
|
-
name: logger
|
45
|
-
requirement: !ruby/object:Gem::Requirement
|
46
|
-
requirements:
|
47
|
-
- - ">="
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '0'
|
50
|
-
type: :runtime
|
51
|
-
prerelease: false
|
52
|
-
version_requirements: !ruby/object:Gem::Requirement
|
53
|
-
requirements:
|
54
|
-
- - ">="
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version: '0'
|
57
41
|
- !ruby/object:Gem::Dependency
|
58
42
|
name: thor
|
59
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -208,9 +192,8 @@ dependencies:
|
|
208
192
|
- - ">="
|
209
193
|
- !ruby/object:Gem::Version
|
210
194
|
version: '0'
|
211
|
-
description:
|
212
|
-
|
213
|
-
Aims to enforce the community-driven Ruby Style Guide.
|
195
|
+
description: "A Tool that will compile git data with wakatime\n data
|
196
|
+
to establish time per commit "
|
214
197
|
email:
|
215
198
|
- russosborn@gmail.com
|
216
199
|
executables:
|
@@ -218,6 +201,7 @@ executables:
|
|
218
201
|
extensions: []
|
219
202
|
extra_rdoc_files: []
|
220
203
|
files:
|
204
|
+
- ".codeclimate.yml"
|
221
205
|
- ".gitignore"
|
222
206
|
- ".rspec"
|
223
207
|
- ".travis.yml"
|
@@ -232,11 +216,13 @@ files:
|
|
232
216
|
- lib/gitwakatime/commit.rb
|
233
217
|
- lib/gitwakatime/commited_file.rb
|
234
218
|
- lib/gitwakatime/controller.rb
|
235
|
-
- lib/gitwakatime/
|
219
|
+
- lib/gitwakatime/durations_calculator.rb
|
236
220
|
- lib/gitwakatime/heartbeat.rb
|
237
221
|
- lib/gitwakatime/log.rb
|
238
222
|
- lib/gitwakatime/mapper.rb
|
239
223
|
- lib/gitwakatime/query.rb
|
224
|
+
- lib/gitwakatime/request.rb
|
225
|
+
- lib/gitwakatime/request_builder.rb
|
240
226
|
- lib/gitwakatime/timer.rb
|
241
227
|
- lib/gitwakatime/version.rb
|
242
228
|
- spec/cli_spec.rb
|
@@ -292,8 +278,10 @@ files:
|
|
292
278
|
- spec/dummy/readme
|
293
279
|
- spec/durations_spec.rb
|
294
280
|
- spec/fixtures/heartbeats.json
|
281
|
+
- spec/fixtures/wakatime.yml
|
295
282
|
- spec/mapper_spec.rb
|
296
283
|
- spec/query_spec.rb
|
284
|
+
- spec/request_builder_spec.rb
|
297
285
|
- spec/spec_helper.rb
|
298
286
|
- spec/timer_spec.rb
|
299
287
|
homepage: ''
|
@@ -316,7 +304,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
316
304
|
version: '0'
|
317
305
|
requirements: []
|
318
306
|
rubyforge_project:
|
319
|
-
rubygems_version: 2.
|
307
|
+
rubygems_version: 2.4.5.1
|
320
308
|
signing_key:
|
321
309
|
specification_version: 4
|
322
310
|
summary: A Tool that will compile git data with wakatime data to establish time per
|
@@ -375,7 +363,9 @@ test_files:
|
|
375
363
|
- spec/dummy/readme
|
376
364
|
- spec/durations_spec.rb
|
377
365
|
- spec/fixtures/heartbeats.json
|
366
|
+
- spec/fixtures/wakatime.yml
|
378
367
|
- spec/mapper_spec.rb
|
379
368
|
- spec/query_spec.rb
|
369
|
+
- spec/request_builder_spec.rb
|
380
370
|
- spec/spec_helper.rb
|
381
371
|
- spec/timer_spec.rb
|
@@ -1,96 +0,0 @@
|
|
1
|
-
module GitWakaTime
|
2
|
-
# Extract Duration Data from Heartbeats for the WAKATIME API
|
3
|
-
class Durations
|
4
|
-
attr_accessor :heartbeats
|
5
|
-
def initialize(args)
|
6
|
-
return @heartbeats = args[:heartbeats] if args[:heartbeats]
|
7
|
-
fail if args[:project].nil?
|
8
|
-
@project = args[:project]
|
9
|
-
@args = args
|
10
|
-
@session = Wakatime::Session.new(api_key: GitWakaTime.config.api_key)
|
11
|
-
@client = Wakatime::Client.new(@session)
|
12
|
-
@heartbeats = []
|
13
|
-
end
|
14
|
-
|
15
|
-
def load_heartbeats
|
16
|
-
unless cached?
|
17
|
-
|
18
|
-
Log.new "querying WakaTime heartbeats for #{@project}"
|
19
|
-
time = Benchmark.realtime do
|
20
|
-
@heartbeats = @client.heartbeats(@args)
|
21
|
-
|
22
|
-
# remove returned heartbeats that do not have the project we want
|
23
|
-
@heartbeats = @heartbeats.keep_if do |a|
|
24
|
-
a['project'] == @project
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
Log.new "API took #{time}s"
|
29
|
-
persist_heartbeats_localy(@heartbeats)
|
30
|
-
end
|
31
|
-
true
|
32
|
-
end
|
33
|
-
|
34
|
-
def persist_heartbeats_localy(heartbeats)
|
35
|
-
heartbeats.map do |heartbeat|
|
36
|
-
heartbeat['uuid'] = heartbeat['id']
|
37
|
-
heartbeat['time'] = Time.at(heartbeat['time'])
|
38
|
-
heartbeat.delete('id')
|
39
|
-
Heartbeat.find_or_create(uuid: heartbeat['uuid']) do |a|
|
40
|
-
a.update(heartbeat)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def cached?
|
46
|
-
# Check to see if this date range might be stale?
|
47
|
-
if cached_heartbeats.count > 0
|
48
|
-
max_local_timetamp = (
|
49
|
-
Time.parse(cached_heartbeats.max(:time)) + 15.day
|
50
|
-
).to_date
|
51
|
-
!(
|
52
|
-
@args[:start].to_date..@args[:end].to_date
|
53
|
-
).include?(max_local_timetamp)
|
54
|
-
else
|
55
|
-
false
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def cached_heartbeats
|
60
|
-
Heartbeat.where('time >= ?', @args[:end]).where(project: @project)
|
61
|
-
end
|
62
|
-
|
63
|
-
def heartbeats_to_durations(_project = nil, timeout = 15)
|
64
|
-
durations = []
|
65
|
-
current = nil
|
66
|
-
|
67
|
-
@heartbeats.each do | heartbeat |
|
68
|
-
# the first heartbeat just sets state and does nothing
|
69
|
-
unless current.nil?
|
70
|
-
|
71
|
-
# get duration since last heartbeat
|
72
|
-
duration = heartbeat.time.round - current.time.round
|
73
|
-
|
74
|
-
duration = 0.0 if duration < 0
|
75
|
-
|
76
|
-
# duration not logged if greater than the timeout
|
77
|
-
if duration < timeout * 60
|
78
|
-
|
79
|
-
# add duration to current heartbeat
|
80
|
-
current.duration = duration
|
81
|
-
|
82
|
-
# save to local db
|
83
|
-
current.save
|
84
|
-
|
85
|
-
# log current heartbeat as a duration
|
86
|
-
durations << current
|
87
|
-
end
|
88
|
-
end
|
89
|
-
# set state (re-start the clock)
|
90
|
-
current = heartbeat
|
91
|
-
|
92
|
-
end
|
93
|
-
durations
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|