durt 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a79549849f47d7161682e6dfc419395c07b1a85acb64e3fb1960564c444a1625
4
+ data.tar.gz: 349b33a912f66978bd7f9d92d0ac90d40f9747a0f5f24ef636d0897886f944c3
5
+ SHA512:
6
+ metadata.gz: 9e5facc089af1213b1b6ee26344e1e8a766d827c261294281de3004f01c84be1ac79f4adb599ecfeda7c53cd70698767ec89dc0a947f583ba8d6743a2c87ae9e
7
+ data.tar.gz: e9afa291bf22c73a703326f6312144719300001092bcbc8125885dfe1acaee92b491609306a4ad0350cd9e312abab039a1e62d6a9b3a03fa03b8a2a70594dd30
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Luis Felipe Sanchez (durt.github.io)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,99 @@
1
+ # Durt
2
+
3
+ Small Ruby program generated using https://github.com/snada/generator-ruby-cmd
4
+
5
+ ## Install
6
+
7
+ This is a Ruby program and uses Bundler to ensure dependencies consistency. On your machine navigate to the project root and run:
8
+
9
+ ```bash
10
+ # If not already installed:
11
+ gem install bundler
12
+
13
+ bundle install
14
+ ```
15
+
16
+ This code is packaged as a Ruby gem, and it should be built and installed running these commands:
17
+
18
+ ```bash
19
+ gem build durt.gemspec
20
+ gem install durt
21
+ ```
22
+
23
+ ## Setup
24
+
25
+ First, you will want to initialize your issues database.
26
+
27
+ ```
28
+ durt init
29
+ ```
30
+
31
+
32
+ Make sure Upwork client (or pick time tracker) is running and in the correct
33
+ project.
34
+
35
+ Then, create `.durt.yml` at your root folder. Example for Jira project:
36
+
37
+ ```
38
+ # ~/.durt.yml
39
+
40
+ ---
41
+ Jira:
42
+ :username: username@example.com
43
+ :password: yourpassword
44
+ :site: http://yourproject.atlassian.net:443/
45
+ :context_path: ''
46
+ :auth_type: :basic
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ If you followed the above instruction and the gem is installed on the system, you should have the binary file ready to run from your command line.
52
+
53
+ Start by choosing the issue statuses that you'll be able to choose from:
54
+
55
+ ```bash
56
+ durt statuses
57
+ ```
58
+
59
+ Next, pick an issue to work on:
60
+
61
+ ```bash
62
+ durt memo
63
+ ```
64
+
65
+ You will be asked to estimate the time it will take you to work on this issue.
66
+ Valid inputs include: `29 minutes`, `3 hours`, `123249 sec` `3 min`, etc.
67
+ As long as it includes a number and something that resembles a time measure it
68
+ will not complain.
69
+
70
+ If you wish to execute without installing, you can by launching this command from the project root directory:
71
+
72
+ ```bash
73
+ ruby -Ilib bin/durt memo
74
+ ```
75
+
76
+ Other commands include:
77
+
78
+ ```bash
79
+ durt start
80
+ durt stop
81
+ durt stats
82
+ durt stats-all
83
+ durt edit-estimate
84
+ ```
85
+
86
+ ## Testing
87
+
88
+ This code is covered with both unit tests and feature tests, using Rspec (testing library classes) and Cucumber/Aruba (testing the actual command line program).
89
+
90
+ You can launch the test suite by running:
91
+
92
+ ```bash
93
+ bundle exec rake spec
94
+ bundle exec rake features
95
+ #launch both:
96
+ bundle exec rake
97
+ ```
98
+
99
+ For unit tests, a simple code coverage tool is provided, and you can see the results by opening the generated `coverage` folder.
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/durt'
5
+
6
+ # Read lines from both file or STDIN
7
+ # lines = (ARGV[0] ? IO.readlines(ARGV[0]) : ARGF.readlines).map(&:chomp)
8
+
9
+ # puts Durt::VERSION
10
+
11
+ command = ARGV[0]
12
+ # options = ARGV[1..-1]
13
+
14
+ def current_project
15
+ Durt::Project.current_project
16
+ end
17
+
18
+ NULL_COMMAND = Durt::Command::NullCommand
19
+ VERSION_COMMAND = Durt::Command::Version
20
+ BROWSE_DB_COMMAND = Durt::Command::BrowseDb
21
+ CONSOLE_COMMAND = Durt::Command::Console
22
+ SYNC_COMMAND = Durt::Command::SyncIssues
23
+
24
+ COMMAND_TRANSLATIONS =
25
+ {
26
+ '-v' => VERSION_COMMAND,
27
+ 'db' => BROWSE_DB_COMMAND,
28
+ 'sync' => SYNC_COMMAND,
29
+ 'c' => CONSOLE_COMMAND,
30
+ nil => NULL_COMMAND
31
+ }.freeze
32
+
33
+ command_klass =
34
+ COMMAND_TRANSLATIONS[command] ||
35
+ "Durt::Command::#{command.underscore.camelize}"
36
+ .yield_self { |name| Object.const_defined?(name) && name.constantize } ||
37
+ NULL_COMMAND
38
+
39
+ begin
40
+ command_klass.call
41
+ rescue ActiveRecord::StatementInvalid => e
42
+ raise e unless Durt.env.production?
43
+
44
+ puts e.message
45
+ puts "Database structure is incorrect"
46
+ puts "You might need to run 'durt init'"
47
+ end
@@ -0,0 +1,22 @@
1
+ default: &default
2
+ adapter: sqlite3
3
+ encoding: unicode
4
+ pool: 5
5
+ timeout: 5000
6
+ host: localhost
7
+
8
+ development:
9
+ <<: *default
10
+ database: <%= ENV['HOME'] %>/.durt/db/development.sqlite3
11
+
12
+ test: &test
13
+ <<: *default
14
+ database: <%= ENV['HOME'] %>/.durt/db/test.sqlite3
15
+
16
+ production:
17
+ <<: *default
18
+ database: <%= ENV['HOME'] %>/.durt/db/production.sqlite3
19
+
20
+ sample:
21
+ <<: *default
22
+ database: db/sample.sqlite3
Binary file
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pry'
4
+ require 'active_support'
5
+ require 'active_support/inflector'
6
+ require 'erb'
7
+
8
+ ENV['RAILS_ENV'] = ENV.fetch('DURT_ENV', 'production')
9
+
10
+ require 'active_record'
11
+
12
+ module Durt
13
+ def self.env
14
+ ActiveSupport::StringInquirer.new(ENV['RAILS_ENV'])
15
+ end
16
+ end
17
+
18
+ config_file_path = File.expand_path('../db/config.yml', __dir__)
19
+
20
+ db_config =
21
+ YAML.load(ERB.new(IO.read(config_file_path)).result)
22
+
23
+ raise 'Sample db should be blank and remain unused' if Durt.env.sample?
24
+
25
+ ActiveRecord::Base.establish_connection(db_config[Durt.env])
26
+
27
+ require_relative 'durt/version'
28
+ require_relative 'durt/configurable'
29
+ require_relative 'durt/project'
30
+ require_relative 'durt/service'
31
+ require_relative 'durt/command'
32
+
33
+ require_relative 'durt/global_controller'
34
+ require_relative 'durt/project_controller'
35
+ require_relative 'durt/local_plugin'
36
+ require_relative 'durt/notify_plugin'
37
+ require_relative 'durt/upwork_plugin'
38
+ require_relative 'durt/github_plugin'
39
+ require_relative 'durt/jira_plugin'
40
+ require_relative 'durt/pivotal_plugin'
41
+ require_relative 'durt/ebs_plugin'
42
+
43
+ require_relative 'durt/issue'
44
+ require_relative 'durt/session'
45
+ require_relative 'durt/status'
46
+
47
+ require_relative 'durt/null_time_tracker'
48
+ require_relative 'durt/local_bug_tracker'
49
+ require_relative 'durt/notify_tracker'
50
+ require_relative 'durt/upwork_tracker'
51
+ require_relative 'durt/null_bug_tracker'
52
+ require_relative 'durt/github_bug_tracker'
53
+ require_relative 'durt/jira_bug_tracker'
54
+ require_relative 'durt/pivotal_bug_tracker'
55
+
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Durt
4
+ class ApplicationRecord < ::ActiveRecord::Base
5
+ self.abstract_class = true
6
+
7
+ scope :to_choice_h, -> { Hash[map { |r| [r.to_s, r] }] }
8
+
9
+ def active!
10
+ reload.update(active: true)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jira-ruby'
4
+
5
+ module Durt
6
+ class BugTracker
7
+ attr_reader :project
8
+
9
+ def initialize(project, config = nil)
10
+ @project = project
11
+ @config = config
12
+
13
+ after_initialize
14
+ end
15
+
16
+ def after_initialize; end
17
+
18
+ def active?
19
+ true
20
+ end
21
+
22
+ def fetch_issues
23
+ raise NotImplementedError
24
+ end
25
+
26
+ def fetch_statuses
27
+ raise NotImplementedError
28
+ end
29
+
30
+ def source_name
31
+ self.class.name.split('::').last.sub('BugTracker', '')
32
+ end
33
+
34
+ def issues
35
+ project.issues.where(source: source_name)
36
+ end
37
+
38
+ def statuses
39
+ Durt::Status.where(source: source_name)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Durt
4
+ module Command
5
+ class Init < ::Durt::Service
6
+ def initialize
7
+ durt_db_dir = File.expand_path('~/.durt/db')
8
+ db_sample = File.expand_path('../../db/sample.sqlite3', __dir__)
9
+ copy_dest = File.join(durt_db_dir, 'production.sqlite3')
10
+ dest_exist = File.exist?(copy_dest)
11
+
12
+ FileUtils.mkdir_p(durt_db_dir, verbose: true)
13
+ FileUtils.cp(db_sample, copy_dest, noop: dest_exist, verbose: true)
14
+ end
15
+ end
16
+
17
+ class BrowseDb < ::Durt::Service
18
+ def initialize
19
+ system("sqlitebrowser #{ActiveRecord::Base.connection_config[:database]}")
20
+ end
21
+ end
22
+
23
+ class Version < ::Durt::Service
24
+ def initialize
25
+ puts Durt::VERSION
26
+ end
27
+ end
28
+
29
+ class NullCommand < ::Durt::Service
30
+ def initialize
31
+ puts 'Unknown command'
32
+ exit
33
+ end
34
+ end
35
+
36
+ class Console < ::Durt::Service
37
+ def initialize
38
+ controller = Durt::GlobalController.new
39
+
40
+ steps << ->(_) { controller.console }
41
+ end
42
+ end
43
+
44
+ class NewProject < ::Durt::Service
45
+ def initialize
46
+ controller = Durt::GlobalController.new
47
+
48
+ steps << ->(_) { controller.create_project }
49
+ steps << ->(project) { controller.create_project_config(project) }
50
+ steps << ->(project) { controller.select_project(project) }
51
+ steps << ->(project) { controller.switch_to_project(project) }
52
+ end
53
+ end
54
+
55
+ class SelectProject < ::Durt::Service
56
+ def initialize
57
+ controller = Durt::GlobalController.new
58
+
59
+ steps << ->(_) { controller.select_project }
60
+ steps << ->(project) { controller.switch_to_project(project) }
61
+ end
62
+ end
63
+
64
+ class Filter < ::Durt::Service
65
+ def initialize
66
+ project = Durt::Project.current_project
67
+ controller = Durt::ProjectController.new(project)
68
+
69
+ steps << ->(_) { controller.filter }
70
+ end
71
+ end
72
+
73
+ class Memo < ::Durt::Service
74
+ def initialize
75
+ project = Durt::Project.current_project
76
+ controller = Durt::ProjectController.new(project)
77
+
78
+ steps << ->(_) { controller.sync_issues }
79
+ steps << ->(_) { controller.select_issue }
80
+ steps << ->(issue) { controller.enter_issue(issue) }
81
+ end
82
+ end
83
+
84
+ class SelectIssue < ::Durt::Service
85
+ def initialize
86
+ project = Durt::Project.current_project
87
+ controller = Durt::ProjectController.new(project)
88
+
89
+ steps << ->(_) { controller.select_issue }
90
+ end
91
+ end
92
+
93
+ class SyncIssues < ::Durt::Service
94
+ def initialize
95
+ project = Durt::Project.current_project
96
+ controller = Durt::ProjectController.new(project)
97
+
98
+ steps << ->(_) { controller.sync_issues }
99
+ end
100
+ end
101
+
102
+ class NewIssue < ::Durt::Service
103
+ def initialize
104
+ project = Durt::Project.current_project
105
+ controller = Durt::ProjectController.new(project)
106
+
107
+ steps << ->(_) { controller.new_issue }
108
+ steps << ->(issue) { controller.select_issue(issue) }
109
+ steps << ->(issue) { controller.push_issue(issue) }
110
+ end
111
+ end
112
+
113
+ class Start < ::Durt::Service
114
+ def initialize
115
+ project = Durt::Project.current_project
116
+ controller = Durt::ProjectController.new(project)
117
+
118
+ steps << ->(_) { controller.current_issue }
119
+ steps << ->(issue) { controller.start_issue(issue) }
120
+ end
121
+ end
122
+
123
+ class Stop < ::Durt::Service
124
+ def initialize
125
+ project = Durt::Project.current_project
126
+ controller = Durt::ProjectController.new(project)
127
+
128
+ steps << ->(_) { controller.current_issue }
129
+ steps << ->(issue) { controller.stop_issue(issue) }
130
+ end
131
+ end
132
+
133
+ class Stats < ::Durt::Service
134
+ def initialize
135
+ Durt::Project.current_project.active_issue.puts_stats
136
+ end
137
+ end
138
+
139
+ class ProjectStats < ::Durt::Service
140
+ def initialize
141
+ Durt::Project.current_project.puts_stats
142
+ end
143
+ end
144
+ end
145
+ end