punched 1.1.1 → 1.2.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/lib/punchcard.rb +25 -12
- data/spec/punchcard_spec.rb +25 -27
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1904b731e6d56b8dc58e49fd74f61d274da5a56342cb97b81a8a9c165f67dcc3
|
4
|
+
data.tar.gz: d923efb27d5f2f6dea68ae9591a1a2d8ad602ba773a1155eb18642b61bbca434
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a98ac0bc3bb08062c85a97098bd5b5f9db1f5adb6f6dac97f02a4838dcde3f99feb91a90da7f45c4b2cf447a36e4cc70c832b1db3c2f0db40ae2d7c8f73a6df6
|
7
|
+
data.tar.gz: 7f097ad0f236ff27c7eb3dccde336aca01724a04f5613ff4a7eb3dcd9ca3d18438d4ec41cd391a769348ea482fc128971c1ed696ddb2d1d9b3d026c9624a1f02
|
data/lib/punchcard.rb
CHANGED
@@ -11,9 +11,9 @@ class PunchCard
|
|
11
11
|
HOURLY_RATE_PATTERN = /^\s*(\d+)([^\d]+)*\s*/i.freeze
|
12
12
|
TIME_POINT_PATTERN = /^((\d+|.+?\s[\+\-]\d{4}?\s*)(\-)*(\d+|\s.+\d?)*)$/.freeze
|
13
13
|
META_KEY_PATTERN = /^([a-zA-Z0-9]+)\:\s*(.*)$/.freeze
|
14
|
-
VERSION = '1.
|
14
|
+
VERSION = '1.2.0'.freeze
|
15
15
|
|
16
|
-
attr_accessor :
|
16
|
+
attr_accessor :title
|
17
17
|
|
18
18
|
def initialize(project_name)
|
19
19
|
@wilcard_for_filename = ''
|
@@ -29,10 +29,10 @@ class PunchCard
|
|
29
29
|
def start
|
30
30
|
output = []
|
31
31
|
if start_time && !end_time
|
32
|
-
output << "'#{
|
32
|
+
output << "'#{title_or_project}' already started (#{humanized_total} total)"
|
33
33
|
output << duration(start_time, timestamp).to_s
|
34
34
|
else
|
35
|
-
output << "'#{
|
35
|
+
output << "'#{title_or_project}' started (#{humanized_total} total)"
|
36
36
|
self.start_time = timestamp
|
37
37
|
end
|
38
38
|
output.join("\n")
|
@@ -41,9 +41,9 @@ class PunchCard
|
|
41
41
|
def stop
|
42
42
|
output = []
|
43
43
|
if end_time
|
44
|
-
output << "'#{
|
44
|
+
output << "'#{title_or_project}' already stopped (#{humanized_total} total)"
|
45
45
|
elsif start_time
|
46
|
-
output << "'#{
|
46
|
+
output << "'#{title_or_project}' stopped (#{humanized_total} total)"
|
47
47
|
self.end_time = timestamp
|
48
48
|
else
|
49
49
|
output << 'Nothing to stop'
|
@@ -59,11 +59,23 @@ class PunchCard
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
+
def title_or_project
|
63
|
+
title || project
|
64
|
+
end
|
65
|
+
|
66
|
+
def title_and_project
|
67
|
+
if title != project
|
68
|
+
"#{title} [#{project}]"
|
69
|
+
else
|
70
|
+
project
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
62
74
|
def status
|
63
75
|
project_exists_or_stop!
|
64
76
|
find_or_make_file
|
65
77
|
output = []
|
66
|
-
output << (
|
78
|
+
output << (title_or_project + " (#{running_status})\n")
|
67
79
|
output << humanized_total
|
68
80
|
output.join("\n")
|
69
81
|
end
|
@@ -104,7 +116,7 @@ class PunchCard
|
|
104
116
|
durations.push duration(starttime, endtime)
|
105
117
|
end
|
106
118
|
'"' + [
|
107
|
-
|
119
|
+
title_and_project,
|
108
120
|
running_status,
|
109
121
|
last_activity ? self.class.format_time(Time.at(last_activity).to_datetime) : '',
|
110
122
|
humanized_total,
|
@@ -253,9 +265,9 @@ class PunchCard
|
|
253
265
|
return str if str.nil?
|
254
266
|
|
255
267
|
str.strip!
|
256
|
-
#
|
268
|
+
# here some legacy… previous versions stored timestamp,
|
257
269
|
# but now punched stores date-time strings for better readability.
|
258
|
-
# So we have to convert timestamp and date-time format into timestamp
|
270
|
+
# So we have to convert timestamp and date-time format into timestamp
|
259
271
|
str =~ /^\d+$/ ? str.to_i : (str =~ /^\d{4}\-\d/ ? Time.parse(str).to_i : nil)
|
260
272
|
end
|
261
273
|
|
@@ -286,7 +298,8 @@ class PunchCard
|
|
286
298
|
end
|
287
299
|
i += 1
|
288
300
|
end
|
289
|
-
@project =
|
301
|
+
@project = File.basename(project_file)
|
302
|
+
self.title = title
|
290
303
|
timestamps
|
291
304
|
end
|
292
305
|
|
@@ -328,7 +341,7 @@ class PunchCard
|
|
328
341
|
|
329
342
|
def find_or_make_file
|
330
343
|
write_string_to_project_file!(@project + "\n") unless project_exist?
|
331
|
-
|
344
|
+
self.title ||= project_data.first
|
332
345
|
end
|
333
346
|
|
334
347
|
def find_or_make_settings_dir
|
data/spec/punchcard_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
1
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'punchcard'
|
4
4
|
require 'securerandom'
|
5
5
|
|
6
6
|
def example_settings_dir
|
@@ -8,13 +8,12 @@ def example_settings_dir
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def setup_example_settings_dir
|
11
|
-
Dir.glob(example_settings_dir+'/*').each { |file| File.delete(file) }
|
11
|
+
Dir.glob(example_settings_dir + '/*').each { |file| File.delete(file) }
|
12
12
|
PunchCard.send(:remove_const, :SETTINGS_DIR)
|
13
13
|
PunchCard.const_set(:SETTINGS_DIR, example_settings_dir)
|
14
14
|
end
|
15
15
|
|
16
16
|
describe PunchCard do
|
17
|
-
|
18
17
|
before do
|
19
18
|
setup_example_settings_dir
|
20
19
|
end
|
@@ -25,8 +24,8 @@ describe PunchCard do
|
|
25
24
|
PunchCard.new("My random Project #{SecureRandom.hex}")
|
26
25
|
end
|
27
26
|
|
28
|
-
def my_project_file
|
29
|
-
File.open("#{example_settings_dir}/#{filename}",
|
27
|
+
def my_project_file(filename = 'my_project')
|
28
|
+
File.open("#{example_settings_dir}/#{filename}", 'r').read
|
30
29
|
end
|
31
30
|
|
32
31
|
def start_and_stop
|
@@ -63,7 +62,7 @@ describe PunchCard do
|
|
63
62
|
it 'should calculate tracked total time' do
|
64
63
|
project = two_seconds_tracking
|
65
64
|
tracked_time = project.details.lines.last.match(/^\d{2}\:\d{2}\:(\d{2}).*total/)[1].to_i
|
66
|
-
expect(tracked_time).to
|
65
|
+
expect(tracked_time).to be_between 1, 3
|
67
66
|
project = two_seconds_tracking
|
68
67
|
tracked_time = project.details.lines.last.match(/^\d{2}\:\d{2}\:(\d{2}).*total/)[1].to_i
|
69
68
|
expect(tracked_time).to be_between 3, 5
|
@@ -80,29 +79,29 @@ describe PunchCard do
|
|
80
79
|
expect(my_project_file.lines[-2]).to match(/^\d+/)
|
81
80
|
end
|
82
81
|
|
83
|
-
it 'should
|
84
|
-
PunchCard.new
|
85
|
-
expect(my_project_file('playing_mot_rhead').strip).to eq(
|
86
|
-
project = PunchCard.new
|
87
|
-
expect(project.project).to eq(
|
82
|
+
it 'should convert names to underscore with special characters' do
|
83
|
+
PunchCard.new 'Playing Motörhead'
|
84
|
+
expect(my_project_file('playing_mot_rhead').strip).to eq('Playing Motörhead')
|
85
|
+
project = PunchCard.new 'Playing*'
|
86
|
+
expect(project.project).to eq('playing_mot_rhead')
|
88
87
|
end
|
89
88
|
|
90
89
|
it 'should set hourlyRate' do
|
91
90
|
project = start_and_stop
|
92
|
-
project.set 'hourlyRate',
|
93
|
-
expect(my_project_file.lines[1].strip).to eq(
|
91
|
+
project.set 'hourlyRate', '1000 €'
|
92
|
+
expect(my_project_file.lines[1].strip).to eq('hourlyRate: 1000 €')
|
94
93
|
end
|
95
94
|
|
96
95
|
it 'should calculate earnings' do
|
97
96
|
project = start_and_stop
|
98
|
-
project.set 'hourlyRate',
|
97
|
+
project.set 'hourlyRate', '1000EURO'
|
99
98
|
project.toggle
|
100
99
|
sleep 2
|
101
100
|
project.toggle
|
102
101
|
project.toggle
|
103
102
|
sleep 2
|
104
103
|
project.toggle
|
105
|
-
expect(project.csv).to match /^"My Project","stopped","[0-9\-\s\:]+?","[0-9\:]+?","1000.0 EURO","1\.\d+ EURO"$/
|
104
|
+
expect(project.csv).to match /^"My Project \[my_project\]","stopped","[0-9\-\s\:]+?","[0-9\:]+?","1000.0 EURO","1\.\d+ EURO"$/
|
106
105
|
end
|
107
106
|
|
108
107
|
it 'should track different projects simultanously' do
|
@@ -115,16 +114,16 @@ describe PunchCard do
|
|
115
114
|
project_a.stop
|
116
115
|
sleep 2
|
117
116
|
project_b.stop
|
118
|
-
expect(project_b.total.to_i - project_a.total.to_i).to be_between(2,4)
|
117
|
+
expect(project_b.total.to_i - project_a.total.to_i).to be_between(2, 4)
|
119
118
|
end
|
120
119
|
|
121
120
|
it 'should load latest project by wildcard' do
|
122
121
|
project_a = random_project
|
123
|
-
project = PunchCard.new
|
122
|
+
project = PunchCard.new 'My random*'
|
124
123
|
expect(project.project).to eq(project_a.project)
|
125
124
|
sleep 1
|
126
125
|
project_b = random_project
|
127
|
-
project = PunchCard.new
|
126
|
+
project = PunchCard.new 'My random*'
|
128
127
|
expect(project.project).to eq(project_b.project)
|
129
128
|
expect(project.project).not_to eq(project_a.project)
|
130
129
|
end
|
@@ -133,23 +132,22 @@ describe PunchCard do
|
|
133
132
|
project = example_project
|
134
133
|
content = my_project_file
|
135
134
|
project.rename 'Renamed Project'
|
136
|
-
expect(File.open("#{example_settings_dir}/renamed_project",
|
137
|
-
expect(File.
|
135
|
+
expect(File.open("#{example_settings_dir}/renamed_project", 'r').read.strip).to eq(content.strip.sub(/My Project/, 'Renamed Project'))
|
136
|
+
expect(File.exist?("#{example_settings_dir}/my_project")).to be_falsey
|
138
137
|
expect(project.project).to eq('Renamed Project')
|
139
138
|
project.start
|
140
139
|
sleep 0.1
|
141
140
|
project.stop
|
142
|
-
content = File.open("#{example_settings_dir}/renamed_project",
|
141
|
+
content = File.open("#{example_settings_dir}/renamed_project", 'r').read.strip
|
143
142
|
project.rename 'Other Project'
|
144
|
-
expect(File.open("#{example_settings_dir}/other_project",
|
145
|
-
expect(File.
|
143
|
+
expect(File.open("#{example_settings_dir}/other_project", 'r').read.strip).to eq(content.strip.sub(/Renamed Project/, 'Other Project'))
|
144
|
+
expect(File.exist?("#{example_settings_dir}/renamed_project")).to be_falsey
|
146
145
|
end
|
147
146
|
|
148
147
|
it 'should remove' do
|
149
148
|
project = example_project
|
150
|
-
expect(File.
|
149
|
+
expect(File.exist?("#{example_settings_dir}/my_project")).to be_truthy
|
151
150
|
project.remove
|
152
|
-
expect(File.
|
151
|
+
expect(File.exist?("#{example_settings_dir}/my_project")).to be_falsey
|
153
152
|
end
|
154
|
-
|
155
153
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: punched
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Philipp Staender
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: markdown-tables
|
@@ -60,8 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
requirements: []
|
63
|
-
|
64
|
-
rubygems_version: 2.7.8
|
63
|
+
rubygems_version: 3.0.3
|
65
64
|
signing_key:
|
66
65
|
specification_version: 4
|
67
66
|
summary: Punchcard Timetracker
|