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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/punchcard.rb +25 -12
  3. data/spec/punchcard_spec.rb +25 -27
  4. metadata +3 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9fdd61f9eabb988d556bbd57326f7e3183ab0e06bc89ad0793b7b6b10297d674
4
- data.tar.gz: 0b01c0843ef8b1fdb35db945499abe6471eb02ddd9cd235d3a2573b1c62397ec
3
+ metadata.gz: 1904b731e6d56b8dc58e49fd74f61d274da5a56342cb97b81a8a9c165f67dcc3
4
+ data.tar.gz: d923efb27d5f2f6dea68ae9591a1a2d8ad602ba773a1155eb18642b61bbca434
5
5
  SHA512:
6
- metadata.gz: ab670118039f178ccd2d2c86d73dbbffbeefd5143db78f8f8b4ac96fa978e07c41860260fd8501af17140786cd9816ce595b60c3348b20eb16d7e8584adef6c5
7
- data.tar.gz: 882f24d878d733bc45bb38e94553968fad541e36a2eb08a29c5278d05f57de473e9ae3afcb312771b8594eeabf711d82e762ac991307c442e953e937a2471af2
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.1.1'.freeze
14
+ VERSION = '1.2.0'.freeze
15
15
 
16
- attr_accessor :project
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 << "'#{project}' already started (#{humanized_total} total)"
32
+ output << "'#{title_or_project}' already started (#{humanized_total} total)"
33
33
  output << duration(start_time, timestamp).to_s
34
34
  else
35
- output << "'#{project}' started (#{humanized_total} total)"
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 << "'#{@project}' already stopped (#{humanized_total} total)"
44
+ output << "'#{title_or_project}' already stopped (#{humanized_total} total)"
45
45
  elsif start_time
46
- output << "'#{@project}' stopped (#{humanized_total} total)"
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 << (project + " (#{running_status})\n")
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
- @project,
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
- # This is some legacy... previous versions stored timestamp,
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 here
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 = title if title
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
- @project = project_data.first
344
+ self.title ||= project_data.first
332
345
  end
333
346
 
334
347
  def find_or_make_settings_dir
@@ -1,6 +1,6 @@
1
- $:.push File.expand_path("../lib", __FILE__)
1
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
2
2
 
3
- require "punchcard"
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 filename = 'my_project'
29
- File.open("#{example_settings_dir}/#{filename}", "r").read
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 be_between 1, 3
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 read and write utf8 names' do
84
- PunchCard.new "Playing Motörhead"
85
- expect(my_project_file('playing_mot_rhead').strip).to eq("Playing Motörhead")
86
- project = PunchCard.new "Playing*"
87
- expect(project.project).to eq("Playing Motörhead")
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', "1000 €"
93
- expect(my_project_file.lines[1].strip).to eq("hourlyRate: 1000 €")
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', "1000EURO"
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 "My random*"
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 "My random*"
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", "r").read.strip).to eq(content.strip.sub(/My Project/, 'Renamed Project'))
137
- expect(File.exists?("#{example_settings_dir}/my_project")).to be_falsey
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", "r").read.strip
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", "r").read.strip).to eq(content.strip.sub(/Renamed Project/, 'Other Project'))
145
- expect(File.exists?("#{example_settings_dir}/renamed_project")).to be_falsey
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.exists?("#{example_settings_dir}/my_project")).to be_truthy
149
+ expect(File.exist?("#{example_settings_dir}/my_project")).to be_truthy
151
150
  project.remove
152
- expect(File.exists?("#{example_settings_dir}/my_project")).to be_falsey
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.1.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-02-27 00:00:00.000000000 Z
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
- rubyforge_project: punched
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