timr 0.3.0 → 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.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.ackrc +9 -0
  3. data/.editorconfig +1 -0
  4. data/.env.example +7 -0
  5. data/.github/CONTRIBUTING.md +32 -0
  6. data/.github/ISSUE_TEMPLATE.md +13 -0
  7. data/.gitignore +8 -2
  8. data/.rdoc_options +21 -0
  9. data/.travis.yml +10 -7
  10. data/Gemfile +8 -0
  11. data/README.md +216 -3
  12. data/bin/.gitignore +2 -0
  13. data/bin/README.md +17 -0
  14. data/bin/build.sh +14 -0
  15. data/bin/build_api.sh +14 -0
  16. data/bin/build_coverage.sh +23 -0
  17. data/bin/build_info.sh +27 -0
  18. data/bin/build_man.sh +41 -0
  19. data/bin/clean.sh +14 -0
  20. data/bin/dev_setup.sh +19 -0
  21. data/bin/install.sh +49 -0
  22. data/bin/publish +38 -0
  23. data/bin/release.sh +35 -0
  24. data/bin/test.sh +19 -0
  25. data/bin/timr +20 -40
  26. data/bin/timr_bash_completion.sh +337 -0
  27. data/bin/uninstall.sh +24 -0
  28. data/lib/timr.rb +36 -8
  29. data/lib/timr/command/basic_command.rb +170 -0
  30. data/lib/timr/command/continue_command.rb +86 -0
  31. data/lib/timr/command/help_command.rb +137 -0
  32. data/lib/timr/command/log_command.rb +297 -0
  33. data/lib/timr/command/pause_command.rb +89 -0
  34. data/lib/timr/command/pop_command.rb +176 -0
  35. data/lib/timr/command/push_command.rb +141 -0
  36. data/lib/timr/command/report_command.rb +689 -0
  37. data/lib/timr/command/start_command.rb +172 -0
  38. data/lib/timr/command/status_command.rb +198 -0
  39. data/lib/timr/command/stop_command.rb +127 -0
  40. data/lib/timr/command/task_command.rb +318 -0
  41. data/lib/timr/command/track_command.rb +381 -0
  42. data/lib/timr/command/version_command.rb +18 -0
  43. data/lib/timr/duration.rb +159 -0
  44. data/lib/timr/exception/timr_error.rb +113 -0
  45. data/lib/timr/ext/time.rb +12 -0
  46. data/lib/timr/helper/datetime_helper.rb +128 -0
  47. data/lib/timr/helper/terminal_helper.rb +58 -0
  48. data/lib/timr/helper/translation_helper.rb +45 -0
  49. data/lib/timr/model/basic_model.rb +287 -0
  50. data/lib/timr/model/config.rb +48 -0
  51. data/lib/timr/model/foreign_id_db.rb +84 -0
  52. data/lib/timr/model/stack.rb +161 -0
  53. data/lib/timr/model/task.rb +1039 -0
  54. data/lib/timr/model/track.rb +589 -0
  55. data/lib/timr/progressbar.rb +41 -0
  56. data/lib/timr/simple_opt_parser.rb +230 -0
  57. data/lib/timr/status.rb +70 -0
  58. data/lib/timr/table.rb +88 -0
  59. data/lib/timr/timr.rb +500 -558
  60. data/lib/timr/version.rb +4 -15
  61. data/man/.gitignore +2 -0
  62. data/man/_footer +3 -0
  63. data/man/timr-continue.1 +48 -0
  64. data/man/timr-continue.1.ronn +39 -0
  65. data/man/timr-ftime.7 +77 -0
  66. data/man/timr-ftime.7.ronn +57 -0
  67. data/man/timr-log.1 +109 -0
  68. data/man/timr-log.1.ronn +87 -0
  69. data/man/timr-pause.1 +56 -0
  70. data/man/timr-pause.1.ronn +45 -0
  71. data/man/timr-pop.1 +66 -0
  72. data/man/timr-pop.1.ronn +53 -0
  73. data/man/timr-push.1 +25 -0
  74. data/man/timr-push.1.ronn +20 -0
  75. data/man/timr-report.1 +228 -0
  76. data/man/timr-report.1.ronn +193 -0
  77. data/man/timr-start.1 +100 -0
  78. data/man/timr-start.1.ronn +82 -0
  79. data/man/timr-status.1 +53 -0
  80. data/man/timr-status.1.ronn +42 -0
  81. data/man/timr-stop.1 +75 -0
  82. data/man/timr-stop.1.ronn +60 -0
  83. data/man/timr-task.1 +147 -0
  84. data/man/timr-task.1.ronn +115 -0
  85. data/man/timr-track.1 +109 -0
  86. data/man/timr-track.1.ronn +89 -0
  87. data/man/timr.1 +119 -0
  88. data/man/timr.1.ronn +68 -0
  89. data/timr.gemspec +18 -3
  90. data/timr.sublime-project +20 -1
  91. metadata +142 -23
  92. data/Makefile +0 -12
  93. data/Makefile.common +0 -56
  94. data/lib/timr/stack.rb +0 -81
  95. data/lib/timr/task.rb +0 -258
  96. data/lib/timr/track.rb +0 -167
  97. data/lib/timr/window.rb +0 -259
  98. data/lib/timr/window_help.rb +0 -41
  99. data/lib/timr/window_tasks.rb +0 -30
  100. data/lib/timr/window_test.rb +0 -20
  101. data/lib/timr/window_timeline.rb +0 -33
  102. data/tests/tc_stack.rb +0 -121
  103. data/tests/tc_task.rb +0 -190
  104. data/tests/tc_track.rb +0 -144
  105. data/tests/tc_window.rb +0 -428
  106. data/tests/ts_all.rb +0 -6
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Build code coverage for https://timr.fox21.at/coverage/.
4
+
5
+ SCRIPT_BASEDIR=$(dirname "$0")
6
+ RUBYOPT=-w
7
+ TZ=Europe/Vienna
8
+ export COVERAGE=1
9
+
10
+
11
+ set -e
12
+ which bundler &> /dev/null || { echo 'ERROR: bundler not found in PATH'; exit 1; }
13
+
14
+ cd "${SCRIPT_BASEDIR}/.."
15
+
16
+ is_local=$1
17
+
18
+ if [[ "$is_local" = -l ]]; then
19
+ echo 'use local SimpleCov PHPUnit Formatter'
20
+ SIMPLECOV_PHPUNIT_LOAD_PATH=../simplecov-phpunit
21
+ fi
22
+
23
+ bundler exec ./test/suite_all.rb
data/bin/build_info.sh ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Build build.txt file for https://timr.fox21.at/build.txt.
4
+
5
+ DATE=$(date +"%F %T %z")
6
+ SCRIPT_BASEDIR=$(dirname "$0")
7
+
8
+
9
+ which ruby &> /dev/null || { echo 'ERROR: ruby not found in PATH'; exit 1; }
10
+
11
+ set -e
12
+ cd "${SCRIPT_BASEDIR}/.."
13
+
14
+ RUBY_VERSION=$(ruby -e "print RUBY_VERSION")
15
+ TIMR_VERSION=$(ruby -I lib/timr -rversion -e "print %{#{TheFox::Timr::VERSION} (#{TheFox::Timr::DATE})}")
16
+
17
+ printf "%s
18
+
19
+ ruby: %s
20
+ timr: %s
21
+
22
+ --- build ---
23
+ id: %s
24
+ ref: %s@%s
25
+ stage: %s
26
+ server: %s %s
27
+ " "${DATE}" "${RUBY_VERSION}" "${TIMR_VERSION}" "${CI_BUILD_ID}" "${CI_BUILD_REF}" "${CI_BUILD_REF_NAME}" "${CI_BUILD_STAGE}" "${CI_SERVER_NAME}" "${CI_SERVER_VERSION}"
data/bin/build_man.sh ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Build manual pages.
4
+
5
+ DATE=$(date +"%F")
6
+ SCRIPT_BASEDIR=$(dirname "$0")
7
+
8
+
9
+ set -e
10
+ which cp &> /dev/null || { echo 'ERROR: cp not found in PATH'; exit 1; }
11
+ which cat &> /dev/null || { echo 'ERROR: cat not found in PATH'; exit 1; }
12
+ which ronn &> /dev/null || { echo 'ERROR: ronn not found in PATH'; exit 1; }
13
+
14
+ cd "${SCRIPT_BASEDIR}/../man"
15
+
16
+ for file in \
17
+ timr-continue.1.ronn \
18
+ timr-log.1.ronn \
19
+ timr-pause.1.ronn \
20
+ timr-pop.1.ronn \
21
+ timr-push.1.ronn \
22
+ timr-report.1.ronn \
23
+ timr-start.1.ronn \
24
+ timr-status.1.ronn \
25
+ timr-stop.1.ronn \
26
+ timr-task.1.ronn \
27
+ timr-track.1.ronn \
28
+ timr-ftime.7.ronn ; do
29
+
30
+ echo "file: '$file'"
31
+ tmp_file="${file}.tmp"
32
+ cp "$file" "$tmp_file"
33
+ {
34
+ echo
35
+ cat _footer
36
+ } >> "$tmp_file"
37
+ done
38
+
39
+ ronn -w --date="$DATE" --manual='Timr Manual' --organization='FOX21.at' timr.1.ronn timr-*.ronn.tmp
40
+
41
+ echo 'done'
data/bin/clean.sh ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Clean up development files.
4
+
5
+ SCRIPT_BASEDIR=$(dirname "$0")
6
+
7
+
8
+ set -e
9
+ which rm &> /dev/null || { echo 'ERROR: rm not found in PATH'; exit 1; }
10
+
11
+ cd "${SCRIPT_BASEDIR}/.."
12
+
13
+ rm -frd .bundle
14
+ rm -f .setup Gemfile.lock
data/bin/dev_setup.sh ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Development setup.
4
+
5
+ SCRIPT_BASEDIR=$(dirname "$0")
6
+
7
+
8
+ set -e
9
+ which cp &> /dev/null || { echo 'ERROR: cp not found in PATH'; exit 1; }
10
+ which bundler &> /dev/null || { echo 'ERROR: bundler not found in PATH'; exit 1; }
11
+
12
+ cd "${SCRIPT_BASEDIR}/.."
13
+
14
+ # Create .env file.
15
+ if [[ ! -f .env ]]; then
16
+ cp .env.example .env
17
+ fi
18
+
19
+ bundler install
data/bin/install.sh ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Install Gem local.
4
+
5
+ SCRIPT_BASEDIR=$(dirname "$0")
6
+
7
+
8
+ option=$1
9
+ set -e
10
+ which mkdir &> /dev/null || { echo 'ERROR: mkdir not found in PATH'; exit 1; }
11
+ which mv &> /dev/null || { echo 'ERROR: mv not found in PATH'; exit 1; }
12
+ which chmod &> /dev/null || { echo 'ERROR: chmod not found in PATH'; exit 1; }
13
+ which gem &> /dev/null || { echo 'ERROR: gem not found in PATH'; exit 1; }
14
+ which bundler &> /dev/null || { echo 'ERROR: bundler not found in PATH'; exit 1; }
15
+
16
+ cd "${SCRIPT_BASEDIR}/.."
17
+
18
+ # Load Environment Variables
19
+ [[ -f .env ]] && source .env
20
+
21
+ if [[ -z "${GEMSPEC_FILE}" ]] ; then
22
+ echo 'ERROR: one of the environment variables is missing'
23
+
24
+ echo "GEMSPEC_FILE: '${GEMSPEC_FILE}'"
25
+
26
+ exit 1
27
+ fi
28
+
29
+ gem_file=$(gem build "${GEMSPEC_FILE}" 2> /dev/null | grep 'File:' | tail -1 | awk '{ print $2 }')
30
+
31
+ if [[ -z "$gem_file" ]] ; then
32
+ echo 'ERROR: gem_file variable not set'
33
+ exit 1
34
+ fi
35
+
36
+ echo "install gem file '$gem_file'"
37
+ gem install "$gem_file"
38
+
39
+ # Create tmp directory.
40
+ if [[ ! -d tmp ]]; then
41
+ mkdir -p tmp
42
+ chmod u=rwx,go-rwx tmp
43
+ fi
44
+
45
+ if [[ "$option" = "-f" ]]; then
46
+ mv -v "$gem_file" tmp
47
+ else
48
+ mv -v -i "$gem_file" tmp
49
+ fi
data/bin/publish ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Upload files to https://timr.fox21.at.
4
+
5
+ SCRIPT_BASEDIR=$(dirname "$0")
6
+
7
+
8
+ set -e
9
+ cd "${SCRIPT_BASEDIR}/.."
10
+
11
+ # Load Environment Variables
12
+ [[ -f .env ]] && source .env
13
+
14
+ if [[ -z "${CI_BUILD_REF_NAME}" ]] || [[ -z "${RSYNC_USER}" ]] || [[ -z "${RSYNC_HOST}" ]] || [[ -z "${RSYNC_REMOTE_PATH_MASTER}" ]] || [[ -z "${RSYNC_REMOTE_PATH_DEVELOP}" ]] || [[ -z "${RSYNC_OPTIONS}" ]] ; then
15
+ echo 'ERROR: one of the environment variables is missing'
16
+
17
+ echo "CI_BUILD_REF_NAME: '${CI_BUILD_REF_NAME}'"
18
+
19
+ echo "RSYNC_USER: '${RSYNC_USER}'"
20
+ echo "RSYNC_HOST: '${RSYNC_HOST}'"
21
+ echo "RSYNC_REMOTE_PATH_MASTER: '${RSYNC_REMOTE_PATH_MASTER}'"
22
+ echo "RSYNC_REMOTE_PATH_DEVELOP: '${RSYNC_REMOTE_PATH_DEVELOP}'"
23
+ echo "RSYNC_OPTIONS: '${RSYNC_OPTIONS}'"
24
+
25
+ exit 1
26
+ fi
27
+
28
+ which rsync &> /dev/null || { echo 'ERROR: rsync not found in PATH'; exit 1; }
29
+
30
+ remote_path=$RSYNC_REMOTE_PATH_DEVELOP
31
+ if [[ "$CI_BUILD_REF_NAME" = "master" ]]; then
32
+ remote_path=$RSYNC_REMOTE_PATH_MASTER
33
+ fi
34
+
35
+ echo "rsync to '${RSYNC_USER}@${RSYNC_HOST}:${remote_path}'"
36
+ rsync ${RSYNC_OPTIONS} build.txt coverage api "${RSYNC_USER}@${RSYNC_HOST}:${remote_path}"
37
+
38
+ rsync ${RSYNC_OPTIONS} --include man --include='man/*.html' --exclude='*' man "${RSYNC_USER}@${RSYNC_HOST}:${remote_path}"
data/bin/release.sh ADDED
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Release gem to https://rubygems.org.
4
+
5
+ SCRIPT_BASEDIR=$(dirname "$0")
6
+
7
+
8
+ set -e
9
+ which mv &> /dev/null || { echo 'ERROR: mv not found in PATH'; exit 1; }
10
+ which gem &> /dev/null || { echo 'ERROR: gem not found in PATH'; exit 1; }
11
+
12
+ cd "${SCRIPT_BASEDIR}/.."
13
+
14
+ # Load Environment Variables
15
+ [[ -f .env ]] && source .env
16
+
17
+ if [[ -z "${GEMSPEC_FILE}" ]] ; then
18
+ echo 'ERROR: one of the environment variables is missing'
19
+
20
+ echo "GEMSPEC_FILE: '${GEMSPEC_FILE}'"
21
+
22
+ exit 1
23
+ fi
24
+
25
+ gem_file=$(gem build "${GEMSPEC_FILE}" 2> /dev/null | grep 'File:' | tail -1 | awk '{ print $2 }')
26
+
27
+ echo "push gem file '$gem_file'"
28
+ gem push "$gem_file"
29
+
30
+ # Create tmp directory.
31
+ if [[ ! -d tmp ]]; then
32
+ mkdir -p tmp
33
+ chmod u=rwx,go-rwx tmp
34
+ fi
35
+ mv -v -i "$gem_file" tmp
data/bin/test.sh ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Run Unit Tests.
4
+
5
+ SCRIPT_BASEDIR=$(dirname "$0")
6
+ RUBYOPT=-w
7
+ TZ=Europe/Vienna
8
+
9
+
10
+ set -e
11
+ which grep &> /dev/null || { echo 'ERROR: grep not found in PATH'; exit 1; }
12
+ which bundler &> /dev/null || { echo 'ERROR: bundler not found in PATH'; exit 1; }
13
+
14
+ cd "${SCRIPT_BASEDIR}/.."
15
+
16
+ # What should 'taks' mean? Task?
17
+ grep -r -i taks lib man test && { echo 'ERROR: Wrong word found'; exit 1; } || true
18
+
19
+ bundler exec ./test/suite_all.rb
data/bin/timr CHANGED
@@ -1,50 +1,30 @@
1
1
  #!/usr/bin/env ruby
2
2
  # coding: UTF-8
3
3
 
4
- require 'optparse'
5
4
  require 'timr'
6
5
 
6
+ include TheFox::Timr::Command
7
+ include TheFox::Timr::Error
7
8
 
8
- @options = {
9
- :dir => nil,
10
- :config_path => "#{Dir.home}/.timr/timr.conf",
11
- }
12
- opts = OptionParser.new do |o|
13
- o.banner = 'Usage: timr [options]'
14
- o.separator('')
15
-
16
- o.on('-d', '--dir <path>', 'Path to a timr directory.') do |path|
17
- @options[:dir] = path
18
- end
19
-
20
- o.on('-p', '--project <name>', 'Project Name: use ~/.timr/projects/NAME as path.') do |name|
21
- @options[:dir] = File.expand_path(name, "#{Dir.home}/.timr/projects")
22
- end
23
-
24
- o.on('-c', '--config <path>', 'Path to config file. Default: ~/.timr/timr.conf') do |path|
25
- @options[:config_path] = File.expand_path(path)
26
- end
27
-
28
- o.on_tail('-V', '--version', 'Show version.') do
29
- puts "#{TheFox::Timr::NAME} #{TheFox::Timr::VERSION} (#{TheFox::Timr::DATE})"
30
- puts "#{TheFox::Timr::HOMEPAGE}"
31
- exit
32
- end
33
-
34
- o.on_tail('-h', '--help', 'Show this message.') do
35
- puts o
36
- puts
37
- exit 3
38
- end
9
+ if $DEBUG # @TODO deactivate this
10
+ START_TIME = Time.now.to_ms
11
+ puts "#{START_TIME} #{self.class} #{__method__} START"
12
+ # puts "__FILE__: #{__FILE__}"
13
+ # puts "$0: #{$0}"
14
+ puts '-------------------------------------------------------------------------'
39
15
  end
40
- ARGV << '-h' if ARGV.count == 0
41
- opts.parse(ARGV)
42
16
 
43
- timr = TheFox::Timr::Timr.new(@options[:dir], @options[:config_path])
44
17
  begin
45
- timr.run
46
- rescue Exception => e
47
- raise e
48
- ensure
49
- timr.close
18
+ command = BasicCommand.create_command_from_argv(ARGV.clone)
19
+ command.run
20
+ command.shutdown
21
+ rescue TimrError => e
22
+ puts "timr error: #{e}"
23
+ end
24
+
25
+ if $DEBUG # @TODO deactivate this
26
+ END_TIME = Time.now.to_ms
27
+ puts '-------------------------------------------------------------------------'
28
+ puts "#{END_TIME} #{self.class} #{__method__} END"
29
+ puts "TIMR RUNTIME: #{END_TIME - START_TIME} ms"
50
30
  end
@@ -0,0 +1,337 @@
1
+
2
+ # Source from this file running
3
+ # source bin/timr_bash_completion.sh
4
+
5
+ function _timr_command {
6
+ local curr_word=$1
7
+ local timr_commands=(
8
+ continue
9
+ help
10
+ log
11
+ pause
12
+ pop
13
+ push
14
+ report
15
+ start
16
+ status
17
+ stop
18
+ task
19
+ track
20
+ )
21
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
22
+ }
23
+
24
+ function _timr_continue_main {
25
+ local curr_word=$1
26
+ local timr_commands=(
27
+ --help
28
+ --date
29
+ --time
30
+ )
31
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
32
+ }
33
+
34
+ function _timr_log_main {
35
+ local curr_word=$1
36
+ local timr_commands=(
37
+ --help
38
+
39
+ --from
40
+ --to
41
+
42
+ --day
43
+ --month
44
+ --year
45
+
46
+ --all
47
+
48
+ --start-date --start-time
49
+ --end-date --end-time
50
+ )
51
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
52
+ }
53
+
54
+ function _timr_pause_main {
55
+ local curr_word=$1
56
+ local timr_commands=(
57
+ --help
58
+ --end-date --date
59
+ --end-time --time
60
+ )
61
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
62
+ }
63
+
64
+ function _timr_pop_main {
65
+ local curr_word=$1
66
+ local timr_commands=(
67
+ --help
68
+
69
+ --start-date --start-time
70
+ --end-date --end-time
71
+
72
+ --date
73
+ --time
74
+ )
75
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
76
+ }
77
+
78
+ function _timr_push_main {
79
+ local curr_word=$1
80
+ local timr_commands=(
81
+ --help
82
+
83
+ --name
84
+ --description
85
+ --hourly-rate
86
+ --flat-rate
87
+
88
+ --message
89
+ --edit
90
+ --date
91
+ --time
92
+ )
93
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
94
+ }
95
+
96
+ function _timr_report_main {
97
+ local curr_word=$1
98
+ local timr_commands=(
99
+ --help
100
+ --day
101
+ --month
102
+ --year
103
+ --all
104
+ --tasks
105
+ --tracks
106
+ --csv
107
+ --force
108
+ )
109
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
110
+ }
111
+
112
+ function _timr_start_main {
113
+ local curr_word=$1
114
+ local timr_commands=(
115
+ --help
116
+
117
+ --id
118
+ --name
119
+ --description
120
+ --estimation
121
+ --hourly-rate
122
+ --flat-rate
123
+
124
+ --message
125
+ --edit
126
+ --date
127
+ --time
128
+ )
129
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
130
+ }
131
+
132
+ function _timr_status_main {
133
+ local curr_word=$1
134
+ local timr_commands=(
135
+ --help
136
+ --verbose
137
+ --full
138
+ --reverse
139
+ )
140
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
141
+ }
142
+
143
+ function _timr_stop_main {
144
+ local curr_word=$1
145
+ local timr_commands=(
146
+ --help
147
+
148
+ --start-date
149
+ --start-time
150
+ --end-date --date
151
+ --end-time --time
152
+
153
+ --message
154
+ --edit
155
+ )
156
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
157
+ }
158
+
159
+ function _timr_task_main {
160
+ local curr_word=$1
161
+ local timr_commands=(
162
+ --help
163
+
164
+ add
165
+ remove
166
+ set
167
+ show
168
+ )
169
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
170
+ }
171
+
172
+ function _timr_task_add {
173
+ local curr_word=$1
174
+ local timr_commands=(
175
+ --id
176
+ --name
177
+ --description
178
+ --estimation
179
+ --billed --unbilled
180
+ --hourly-rate --no-hourly-rate
181
+ --flat-rate --no-flat-rate
182
+ )
183
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
184
+ }
185
+
186
+ function _timr_task_remove {
187
+ local curr_word=$1
188
+ COMPREPLY=( $(compgen -A variable 'TIMR_' -- "${curr_word}") )
189
+ }
190
+
191
+ function _timr_task_set {
192
+ local curr_word=$1
193
+ local timr_commands=(
194
+ --id
195
+ --name
196
+ --description
197
+ --estimation
198
+ --billed --unbilled
199
+ --hourly-rate --no-hourly-rate
200
+ --flat-rate --no-flat-rate
201
+ )
202
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
203
+ }
204
+
205
+ function _timr_task_show {
206
+ local curr_word=$1
207
+ local timr_commands=(
208
+ --tracks
209
+ )
210
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
211
+ }
212
+
213
+ function _timr_track_main {
214
+ local curr_word=$1
215
+ local timr_commands=(
216
+ --help
217
+
218
+ add
219
+ remove
220
+ set
221
+ show
222
+ )
223
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
224
+ }
225
+
226
+ function _timr_track_add {
227
+ local curr_word=$1
228
+ local timr_commands=(
229
+ --message
230
+ --start-date --start-time
231
+ --end-date --end-time
232
+ --billed --unbilled
233
+ )
234
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
235
+ }
236
+
237
+ function _timr_track_remove {
238
+ local curr_word=$1
239
+ COMPREPLY=( $(compgen -A variable 'TIMR_' -- "${curr_word}") )
240
+ }
241
+
242
+ function _timr_track_set {
243
+ local curr_word=$1
244
+ local timr_commands=(
245
+ --message
246
+ --start-date --start-time
247
+ --end-date --end-time
248
+ --billed --unbilled
249
+ --task
250
+ )
251
+ COMPREPLY=( $(compgen -W '${timr_commands[@]}' -- "${curr_word}") )
252
+ }
253
+
254
+ function _timr_track_show {
255
+ local curr_word=$1
256
+ COMPREPLY=( $(compgen -W '--task' -- "${curr_word}") )
257
+ }
258
+
259
+ function _timr_main {
260
+ local curr_word
261
+ # local prev_word
262
+
263
+ curr_word="${COMP_WORDS[COMP_CWORD]}"
264
+ # prev_word="${COMP_WORDS[COMP_CWORD-1]}"
265
+
266
+ unset -v 'COMP_WORDS[0]'
267
+
268
+ COMPREPLY=()
269
+
270
+ local timr_command timr_subcommand
271
+
272
+ for word in "${COMP_WORDS[@]}"; do
273
+ case ${word} in
274
+ -*)
275
+ # Skip, next.
276
+ ;;
277
+ *)
278
+ if [[ ! -z "$word" ]]; then
279
+ if [[ -z "$timr_command" ]]; then
280
+ timr_command=$word
281
+ else
282
+ timr_subcommand=$word
283
+ break
284
+ fi
285
+ fi
286
+ ;;
287
+ esac
288
+ done
289
+
290
+ if [[ -z "$timr_command" ]]; then
291
+ case ${curr_word} in
292
+ -*)
293
+ COMPREPLY=( $(compgen -W "-V --version -h --help -C" -- "${curr_word}") )
294
+ ;;
295
+ *)
296
+ _timr_command "$curr_word"
297
+ ;;
298
+ esac
299
+ else
300
+ if [[ "$curr_word" = "$timr_command" ]]; then
301
+ # To fit *) in the case below.
302
+ unset timr_command
303
+ fi
304
+ if [[ "$curr_word" = "$timr_subcommand" ]]; then
305
+ # To fit *) in the second level case below.
306
+ unset timr_subcommand
307
+ fi
308
+
309
+ case "${timr_command}" in
310
+ continue|log|pause|pop|push|report|start|status|stop)
311
+ "_timr_${timr_command}_main" "$curr_word"
312
+ ;;
313
+ task|track)
314
+ case "${timr_subcommand}" in
315
+ add|remove|set|show)
316
+ "_timr_${timr_command}_${timr_subcommand}" "$curr_word"
317
+ ;;
318
+ *)
319
+ "_timr_${timr_command}_main" "$curr_word"
320
+ ;;
321
+ esac
322
+ ;;
323
+ help|*)
324
+ _timr_command "$curr_word"
325
+ ;;
326
+ esac
327
+ fi
328
+ # echo
329
+ }
330
+
331
+ # Dev
332
+ # complete -F _timr_main -o bashdefault timr_dev
333
+
334
+ complete -F _timr_main -o bashdefault timr
335
+
336
+ # To remove timr.
337
+ # complete -r timr