punched 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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