ptimelog 0.5.3 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4683decb77f362d2861b903e30db9dcb330151f7ee43d6ddb3c332d3af4243b2
4
- data.tar.gz: 23c0c132975613fb3f16c064930e6aa72b49e28fbd7cd9b3636aef6863cbb1e4
3
+ metadata.gz: 53f453d27b45af79d5bef690d87c5ad36984848f3df02a3114cc60fb3e4a4dbf
4
+ data.tar.gz: 77c4269e3d12bc42db29624bf4b06e2092f1c60459d13aed8a2d3bf28e03ba12
5
5
  SHA512:
6
- metadata.gz: e24c93aefa5a8ae475013593af737f872bade8f0f02997551bd2fe2cce049e64bd42869fe9648630f1b02191f2f7fc87883b942a9e266492c0fa09227c51b592
7
- data.tar.gz: 043b2383d127e1aeccb716f8e14e47a365cdc309862c0d1309916ceb1695b194e1cb9aad1e4bc5f63f3b9a95aa3aae55981606018370b03d077a1f5a3d42159a
6
+ metadata.gz: 6db9a06490897de96ca955ad900876f8848482a2dfe1796cdf1f0dfdbb35ed0d44f61616e2c00fa56acc1cc427b3e39645b37fc65cf7144f55f414fd762fc15b
7
+ data.tar.gz: d6e38738b5f4384b03edac240bdcd7622e2812d8d056529d26d10903b6d1e73e3c72e1f3b4bfede1e4a234c5738ec8171d0385d276f3ab7843a8675759361251
data/.rubocop.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
- Metrics/LineLength:
3
+ Layout/LineLength:
4
4
  Max: 120
5
5
 
6
6
  Metrics/BlockLength:
@@ -13,12 +13,12 @@ Style/TrailingCommaInArrayLiteral:
13
13
  Style/TrailingCommaInHashLiteral:
14
14
  EnforcedStyleForMultiline: consistent_comma
15
15
 
16
- Layout/AlignHash:
16
+ Layout/HashAlignment:
17
17
  EnforcedHashRocketStyle: table
18
18
  EnforcedColonStyle: table
19
19
  EnforcedLastArgumentHashStyle: always_inspect # default
20
20
 
21
- Naming/UncommunicativeMethodParamName:
21
+ Naming/MethodParameterName:
22
22
  AllowedNames:
23
23
  - fn
24
24
  # default allowed names
data/.rubocop_todo.yml CHANGED
@@ -1,12 +1,12 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2019-08-06 22:23:40 +0200 using RuboCop version 0.65.0.
3
+ # on 2020-01-22 14:10:50 +0100 using RuboCop version 0.79.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 3
9
+ # Offense count: 4
10
10
  Metrics/AbcSize:
11
11
  Max: 16
12
12
 
data/README.md CHANGED
@@ -37,6 +37,7 @@ small tooling to transfer timelog-entries from gtimelog's timelog.txt to the Puz
37
37
  - [ ] from *-notation
38
38
  - [ ] allow to have a list of "favourite" time-accounts
39
39
  - [ ] select best-matching time-account according to tags, possibly limited to the favourites
40
+ - [x] combine billable and account-lookup into one script
40
41
  - [ ] add cli-help
41
42
  - [ ] use commander for CLI?
42
43
 
@@ -84,16 +85,15 @@ Otherwise, a script to determine the time-account is loaded.
84
85
  ptimelog can prefill the account-number and billable-state of an entry.
85
86
 
86
87
  The tags are used to determine a script that helps infer the time-account.
87
- These scripts should be located in `~/.config/ptimelog/parsers/` and be named
88
+ These scripts should be located in `~/.config/ptimelog/inferers/` and be named
88
89
  like the first tag used. The script gets the ticket, the description and all
89
- remaining tags passed as arguments. The output of the script should only be the
90
- ID of the time-account.
90
+ remaining tags passed as arguments.
91
91
 
92
- In order to infer the billable-state of an entry, a script
93
- `~/.config/ptimelog/billable` is called. It only gets the previously infered
94
- account-id as argument and is expected to output "true" or "false".
92
+ The output of the script should be the ID of the time-account and the
93
+ billable-state as "true" or "false". Both items need to be separated by
94
+ whitespace, so you can output those two on the same line or on different lines.
95
95
 
96
- Since these script are called a lot, it is better to write them in a compiled
96
+ Since these scripts are called a lot, it is better to write them in a compiled
97
97
  language. If you only like ruby, take a look at crystal. For such simple
98
98
  scripts, the code is almost identical and "just" needs to be compiled.
99
99
 
@@ -13,7 +13,7 @@ module Ptimelog
13
13
  end
14
14
 
15
15
  def run
16
- launch_editor(@file)
16
+ launch_editor(find_file(@file))
17
17
  end
18
18
 
19
19
  private
@@ -21,10 +21,50 @@ module Ptimelog
21
21
  def launch_editor(file)
22
22
  editor = `which $EDITOR`.chomp
23
23
 
24
- file = file.nil? ? Timelog.timelog_txt : @scripts.parser(@file)
25
-
26
24
  exec "#{editor} #{file}"
27
25
  end
26
+
27
+ def find_file(requested_file)
28
+ %i[
29
+ timelog
30
+ existing_inferer
31
+ existing_parser
32
+ billable
33
+ empty_inferer
34
+ ].each do |file_lookup|
35
+ valid, filename = send(file_lookup, requested_file)
36
+
37
+ return filename if valid
38
+ end
39
+ end
40
+
41
+ def timelog(file)
42
+ [file.nil?, Timelog.timelog_txt]
43
+ end
44
+
45
+ def existing_inferer(file)
46
+ fn = @scripts.inferer(file)
47
+
48
+ [fn.exist?, fn]
49
+ end
50
+
51
+ def existing_parser(file)
52
+ fn = @scripts.parser(file)
53
+
54
+ [fn.exist?, fn]
55
+ end
56
+
57
+ def billable(file)
58
+ [file == 'billable', @scripts.billable]
59
+ end
60
+
61
+ def empty_inferer(file)
62
+ [true, @scripts.inferer(file)]
63
+ end
64
+
65
+ def empty_parser(file)
66
+ [true, @scripts.parser(file)]
67
+ end
28
68
  end
29
69
  end
30
70
  end
@@ -30,6 +30,7 @@ module Ptimelog
30
30
  entry.description,
31
31
  entry.tags,
32
32
  entry.account,
33
+ (entry.billable? ? '$' : nil),
33
34
  ].compact.join(' ∴ '),
34
35
  ].compact.join(' ')
35
36
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ptimelog
4
+ # Allow to add some (hopefully) helpful deprecation warning
5
+ module DeprecationWarning
6
+ def self.included(base)
7
+ base.send :extend, ClassMethods
8
+ end
9
+
10
+ # Keep track of wether the deprecation have been shown already or not
11
+ module ClassMethods
12
+ def deprecation_warning_rendered?
13
+ @deprecation_warning_rendered == true
14
+ end
15
+
16
+ def reset_deprecation_warning!
17
+ @deprecation_warning_rendered = false
18
+ end
19
+
20
+ def deprecation_warning_rendered!
21
+ @deprecation_warning_rendered = true
22
+ end
23
+ end
24
+
25
+ def deprecate(*args)
26
+ warn deprecate_header(*args)
27
+
28
+ return if self.class.deprecation_warning_rendered?
29
+
30
+ warn deprecate_message(*args)
31
+ self.class.deprecation_warning_rendered!
32
+ end
33
+
34
+ def deprecate_header(_)
35
+ raise <<~MESSAGE
36
+ deprecate_header(args) not implemented
37
+
38
+ Please define a header/short-info for the deprecation, rendered every
39
+ time the deprecation is hit.
40
+ MESSAGE
41
+ end
42
+
43
+ def deprecate_message(_)
44
+ raise <<~MESSAGE
45
+ deprecate_message(args) not implemented
46
+
47
+ Please define a message () for the deprecation, rendered only the first
48
+ time the deprecation is hit.
49
+ MESSAGE
50
+ end
51
+ end
52
+ end
@@ -10,6 +10,9 @@ module Ptimelog
10
10
  # define only trivial writers, omit special and derived values
11
11
  attr_writer :date, :ticket, :description
12
12
 
13
+ BILLABLE = 1
14
+ NON_BILLABLE = 0
15
+
13
16
  def initialize(config = Configuration.instance)
14
17
  @config = config
15
18
  @script = Script.new(@config[:dir])
@@ -53,23 +56,29 @@ module Ptimelog
53
56
  end
54
57
 
55
58
  def hidden?
56
- @description =~ /\*\*$/ # hide lunch and breaks
59
+ @description.to_s.end_with?('**') # hide lunch and breaks
60
+ end
61
+
62
+ def billable?
63
+ @billable == BILLABLE
57
64
  end
58
65
 
66
+ # this method will be reduced in 0.7, when support for parsers is removed
59
67
  def infer_ptime_settings
60
- @account = infer_account
61
- @billable = infer_billable
68
+ return if hidden?
69
+
70
+ if @script.inferer(script_name).exist?
71
+ @account, @billable = infer_account_and_billable
72
+ else
73
+ @account = infer_account
74
+ @billable = infer_billable
75
+ end
62
76
  end
63
77
 
64
78
  def to_s
65
79
  [
66
80
  @start_time, '-', @finish_time,
67
- [
68
- @ticket,
69
- @description,
70
- @tags,
71
- @account,
72
- ].compact.join(' : '),
81
+ [@ticket, @description, @tags, @account].compact.join(' : '),
73
82
  ].compact.join(' ')
74
83
  end
75
84
 
@@ -92,24 +101,43 @@ module Ptimelog
92
101
  end.map { |part| part.to_s.rjust(2, '0') }.join(':')
93
102
  end
94
103
 
95
- def infer_account
96
- return unless @tags
104
+ def script_name
105
+ @script_name ||= @tags.to_a.first.to_s
106
+ end
97
107
 
98
- parser_name = @tags.first
99
- parser = @script.parser(parser_name)
108
+ def script_args
109
+ @script_args ||= @tags.to_a[1..-1].to_a.map(&:inspect).join(' ')
110
+ end
100
111
 
112
+ # this method will be removed in 0.7, when support for parsers is removed
113
+ def infer_account
114
+ parser = @script.parser(script_name)
101
115
  return unless parser.exist?
102
116
 
103
- cmd = %(#{parser} "#{@ticket}" "#{@description}" #{@tags[1..-1].map(&:inspect).join(' ')})
117
+ @script.deprecate(parser)
118
+
119
+ cmd = %(#{parser} "#{@ticket}" "#{@description}" #{script_args})
104
120
  `#{cmd}`.chomp # maybe only execute if parser is in correct dir?
105
121
  end
106
122
 
123
+ # this method will be removed in 0.7, when support for billable is removed
107
124
  def infer_billable
108
125
  script = @script.billable
126
+ return BILLABLE unless script.exist?
127
+
128
+ @script.deprecate(script)
129
+
130
+ `#{script} #{@account}`.chomp == 'true' ? BILLABLE : NON_BILLABLE
131
+ end
132
+
133
+ def infer_account_and_billable
134
+ script = @script.inferer(script_name)
135
+
136
+ cmd = %(#{script} "#{@ticket}" "#{@description}" #{script_args})
109
137
 
110
- return 1 unless script.exist?
138
+ account, billable = `#{cmd}`.chomp.split
111
139
 
112
- `#{script} #{@account}`.chomp == 'true' ? 1 : 0
140
+ [account, (billable == 'true' ? BILLABLE : NON_BILLABLE)]
113
141
  end
114
142
  end
115
143
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'naught'
4
+ require 'pathname'
5
+
6
+ NullPathname = Naught.build do |config|
7
+ config.impersonate Pathname
8
+ config.predicates_return false
9
+ end
@@ -16,5 +16,27 @@ module Ptimelog
16
16
  def billable
17
17
  @config_dir.join('billable').expand_path
18
18
  end
19
+
20
+ def inferer(name)
21
+ return NullPathname.new if name.to_s.empty?
22
+ raise if name =~ %r{[\\/]} # prevent relavtive paths, stupidly, FIXME: really check FS
23
+
24
+ @config_dir.join('inferers').join(name).expand_path
25
+ end
26
+
27
+ include DeprecationWarning
28
+
29
+ def deprecate_message(_)
30
+ <<~MESSAGE
31
+ Please move the parser- and billable-scripts to an inferer-script.
32
+ Support for the previous scripts in parsers/* and billable will
33
+ be dropped in 0.7.
34
+
35
+ MESSAGE
36
+ end
37
+
38
+ def deprecate_header(script_fn)
39
+ "DEPRECATION NOTICE: #{script_fn} is deprecated"
40
+ end
19
41
  end
20
42
  end
@@ -1,6 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Version
3
+ # the version, following semver
4
+ #
5
+ # Someone wanted to have documentation, so here goes...
6
+ #
7
+ # Please note that the version-string is not frozen. Although it of course is,
8
+ # because all strings in this file are frozen. That's what the magic comment
9
+ # at the top of the file does. :gasp:
10
+ #
11
+ # What else? Yeah, the VERSION-constant is part of the module Ptimelog because
12
+ # that is what is described here.
13
+ #
14
+ # So, I truly hope you are happy now, that I documented this file properly. For
15
+ # any remaining questions, please open an issue or even better a pull-request
16
+ # with an improvement. Keep in mind that this is also covered by rspec so I
17
+ # expect (pun intended) 100% test-coverage for any additional code.
4
18
  module Ptimelog
5
- VERSION = '0.5.3'
19
+ VERSION = '0.6.0'
6
20
  end
data/lib/ptimelog.rb CHANGED
@@ -6,8 +6,10 @@ $LOAD_PATH.unshift File.dirname(__FILE__)
6
6
  module Ptimelog
7
7
  autoload :App, 'ptimelog/app'
8
8
  autoload :Configuration, 'ptimelog/configuration'
9
+ autoload :DeprecationWarning, 'ptimelog/deprecation_warning'
9
10
  autoload :Entry, 'ptimelog/entry'
10
11
  autoload :NamedDate, 'ptimelog/named_date'
12
+ autoload :NullPathname, 'ptimelog/null_pathname'
11
13
  autoload :Script, 'ptimelog/script'
12
14
  autoload :Timelog, 'ptimelog/timelog'
13
15
  autoload :VERSION, 'ptimelog/version'
data/ptimelog.gemspec CHANGED
@@ -22,6 +22,8 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
24
 
25
+ spec.add_dependency 'naught'
26
+
25
27
  spec.add_development_dependency 'bundler'
26
28
  spec.add_development_dependency 'overcommit', '~> 0.45'
27
29
  spec.add_development_dependency 'pry', '~> 0.12'
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ptimelog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthias Viehweger
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-15 00:00:00.000000000 Z
11
+ date: 2020-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: naught
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -138,8 +152,10 @@ files:
138
152
  - lib/ptimelog/command/show.rb
139
153
  - lib/ptimelog/command/upload.rb
140
154
  - lib/ptimelog/configuration.rb
155
+ - lib/ptimelog/deprecation_warning.rb
141
156
  - lib/ptimelog/entry.rb
142
157
  - lib/ptimelog/named_date.rb
158
+ - lib/ptimelog/null_pathname.rb
143
159
  - lib/ptimelog/script.rb
144
160
  - lib/ptimelog/timelog.rb
145
161
  - lib/ptimelog/version.rb