jira-auto-tool 1.0.0 → 1.1.2

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: ef155479c2de20dfb3e3832c19a641451e04f80223f72d549f00b9deef55bfb1
4
- data.tar.gz: fd35c88ae871e535a8d5a2423a2a93725593f9124a290656b37221b229071905
3
+ metadata.gz: add7c4637bf997f40928d5c82ccb61253feee7f9bc671068b41e38e706843402
4
+ data.tar.gz: 5a7f0d706305157e7efae7656834c56ec9f70e32042547fcf660255c8b26c539
5
5
  SHA512:
6
- metadata.gz: b5913dded0750570c80fe1be755edf588a1f136f0ba417ff1168ae6093d1fa58406252f18280a4158c46971532445d20a00c0b4bbf82cd800176192f776664ff
7
- data.tar.gz: '09aeea8783e1c9ff219b202e1b6ad031870e802b4f4b6bdfaeb33f3adeed47f8ca93056f79127a50edda131b115e4f232fc19be0e794e30ecafd28e954c6ca0c'
6
+ metadata.gz: 1210eedc7eda1ca3a93a81ce66539c3728b2c470c45da54dec690ad0b0d38eb07c36f0ddf41d067bf6bbaa3eb5272af62ea131eafe34147f0645f8c17635c280
7
+ data.tar.gz: 5dfdbbe196e763f005504fd4f3311533fb2cc543a987674bf8d7c282c8534178391f461986a08f6b7df85ebaa4b8c85a6f879815d5789fbdcd90923cfb443bf8
data/README.md CHANGED
@@ -35,10 +35,19 @@ in such a cloud sandbox. Though, if the sandbox belongs to the target context
35
35
 
36
36
  ## Setup
37
37
 
38
+ 1. Create an example configuration file
39
+ ```bash
40
+ jira-auto-tool --env-setup
41
+ ```
42
+ 2. Adjust the file to your context.
43
+
44
+ **WARNING** - It is highly recommended that the JIRA_API_TOKEN value is set as an environment variable
45
+ and **NOT** in the generated file.
46
+
38
47
  While we strive to use convention over configuration as a principle, the following environment variables have to be set
39
48
  in order to use this tool:
40
49
 
41
- Required environment variables:
50
+ Some explanations:
42
51
 
43
52
  - `JIRA_USERNAME` - Your Jira account username (e.g., "user@company.com").
44
53
  - `JIRA_API_TOKEN` - Your Jira API authentication token.
@@ -63,19 +72,20 @@ See [sprint filtering](./features/sprint_filtering.feature).
63
72
 
64
73
  ## Usage
65
74
 
66
- * Leverage the [specification by examples](./features)
67
75
  * Use the tool integrated help:
68
76
  ```bash
69
77
  jira-auto-tool --help
70
78
  ```
71
- * Usually the long option names have a short version equivalent to reduce typing.
79
+ * Leverage the [specification by examples](./features) for a detailled understand of the features.
80
+ * Note that usually the long option names have a short version equivalent to reduce typing.
72
81
 
73
82
  Below are a few examples.
74
83
 
75
84
  ### Add Sprints
76
85
 
77
- The following is going to create sprints `sprint_prefix_25.4.3` until `sprint_prefix_25.4.6`
78
- for the teams respective sprint prefixes.
86
+ The following is going to [add sprints](./features/create_sprints_using_existing_ones_as_reference.feature)
87
+ `sprint_prefix_25.4.3` until `sprint_prefix_25.4.6`
88
+ to the teams respective sprint prefixes.
79
89
  ```bash
80
90
  jira-auto-tool --sprint-add=25.4.3,4
81
91
  ```
data/Rakefile CHANGED
@@ -4,6 +4,10 @@ require "bundler/gem_tasks"
4
4
  require "rspec/core/rake_task"
5
5
  require "cucumber"
6
6
  require "cucumber/rake/task"
7
+ require "rake"
8
+
9
+ # Load custom tasks
10
+ Dir.glob("lib/tasks/**/*.rake").each { |r| load r }
7
11
 
8
12
  RSpec::Core::RakeTask.new(:spec)
9
13
 
data/bin/jira-auto-tool CHANGED
@@ -20,6 +20,7 @@ require "jira/auto/tool"
20
20
  require "jira/auto/tool/board_controller/options"
21
21
  require "jira/auto/tool/common_options"
22
22
  require "jira/auto/tool/config/options"
23
+ require "jira/auto/tool/environment_loader/options"
23
24
  require "jira/auto/tool/jira_http_options"
24
25
  require "jira/auto/tool/performer/options"
25
26
  require "jira/auto/tool/project/options"
@@ -36,6 +37,7 @@ option_parser = OptionParser.new do |parser|
36
37
  Jira::Auto::Tool::JiraHttpOptions.add(tool, parser)
37
38
  Jira::Auto::Tool::BoardController::Options.add(tool, parser)
38
39
  Jira::Auto::Tool::Config::Options.add(tool, parser)
40
+ Jira::Auto::Tool::EnvironmentLoader::Options.add(tool, parser)
39
41
  Jira::Auto::Tool::Project::Options.add(tool, parser)
40
42
  Jira::Auto::Tool::Performer::Options.add(tool, parser)
41
43
  Jira::Auto::Tool::SprintController::Options.add(tool, parser)
@@ -0,0 +1,28 @@
1
+ ---
2
+ <%
3
+ project_key = "PROJ"
4
+ sprint_field_name = "Sprint"
5
+ jira_username = "cbroult@yahoo.com"
6
+ %>
7
+ ##JIRA_API_TOKEN: WARNING - it is recommended to set the value directly as an environment variable
8
+ ART_SPRINT_REGEX:
9
+ DISABLE_COVERAGE: true
10
+ EXPECTED_START_DATE_FIELD_NAME: Expected Start
11
+ IMPLEMENTATION_TEAM_FIELD_NAME: "Implementation Team"
12
+ JAT_RATE_INTERVAL_IN_SECONDS:
13
+ JAT_RATE_LIMIT_IN_SECONDS:
14
+ JAT_TICKETS_FOR_TEAM_SPRINT_TICKET_DISPATCHER_JQL: "project = <%= project_key %> AND <%= sprint_field_name %> IS EMPTY"
15
+ JIRA_BOARD_NAME: "<%= project_key %> - Your board name"
16
+ JIRA_BOARD_NAME_REGEX: "<%= project_key %>|ART 16|unconventional board name"
17
+ JIRA_CONTEXT_PATH: /jira
18
+ JIRA_HTTP_DEBUG:
19
+ JIRA_PROJECT_KEY: <%= project_key %>
20
+ JIRA_SITE_URL: http://cbroult.atlassian.net:443/
21
+ JIRA_SPRINT_FIELD_NAME: "<%= sprint_field_name %>"
22
+ JIRA_USERNAME: <%= jira_username %>
23
+
24
+ <%
25
+ message = "TODO: set the values specific to your context and remove this part of the file"
26
+ log.error { message }
27
+ raise message
28
+ %>
@@ -0,0 +1,44 @@
1
+ classDiagram
2
+ class Tool {
3
+ }
4
+
5
+ class BoardController {
6
+ }
7
+
8
+ class SprintController {
9
+ }
10
+
11
+ class BoardOptions {
12
+ +add(tool, parser)$
13
+ }
14
+
15
+ class SprintOptions {
16
+ +add(tool, parser)$
17
+ +add_sprint_adding_options(parser, tool)$
18
+ +add_sprint_listing_options(parser, tool)$
19
+ +add_sprint_prefix_listing_options(parser, tool)$
20
+ }
21
+
22
+ class UntilDate {
23
+ }
24
+
25
+ class Cache {
26
+ }
27
+
28
+ Tool --> BoardController : has
29
+ Tool --> SprintController : has
30
+ BoardController --> BoardOptions : uses
31
+ SprintController --> SprintOptions : uses
32
+ BoardController --> Cache : uses
33
+ SprintOptions --> UntilDate : uses
34
+
35
+ %% Namespace structure
36
+ namespace Jira {
37
+ namespace Auto {
38
+ Tool
39
+ namespace Tool {
40
+ BoardController
41
+ SprintController
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,48 @@
1
+ # Overall Class Diagram Structure
2
+
3
+ ```mermaid
4
+ classDiagram
5
+ class Tool {
6
+ }
7
+
8
+ class BoardController {
9
+ }
10
+
11
+ class SprintController {
12
+ }
13
+
14
+ class BoardOptions {
15
+ +add(tool, parser)$
16
+ }
17
+
18
+ class SprintOptions {
19
+ +add(tool, parser)$
20
+ +add_sprint_adding_options(parser, tool)$
21
+ +add_sprint_listing_options(parser, tool)$
22
+ +add_sprint_prefix_listing_options(parser, tool)$
23
+ }
24
+
25
+ class UntilDate {
26
+ }
27
+
28
+ class Cache {
29
+ }
30
+
31
+ Tool --> BoardController : has
32
+ Tool --> SprintController : has
33
+ BoardController --> BoardOptions : uses
34
+ SprintController --> SprintOptions : uses
35
+ BoardController --> Cache : uses
36
+ SprintOptions --> UntilDate : uses
37
+
38
+ %% Namespace structure
39
+ namespace Jira {
40
+ namespace Auto {
41
+ Tool
42
+ namespace Tool {
43
+ BoardController
44
+ SprintController
45
+ }
46
+ }
47
+ }
48
+ ```
@@ -0,0 +1,6 @@
1
+ # Principles
2
+
3
+ ## Configuration Over Configuration
4
+
5
+ ##
6
+
@@ -0,0 +1,166 @@
1
+ @wip
2
+ Feature: Environment Configuration Management
3
+ In order to avoid setting environment variables manually
4
+ As a user of jira-auto-tool
5
+ I want to be able to configure the tool using a configuration file
6
+
7
+ Scenario: Creating the environment configuration file
8
+ Given a file named "~/.config/jira-auto-tool/jira-auto-tool.env.yaml.erb" does not exist
9
+ When I successfully run `jira-auto-tool --env-create-file`
10
+ Then the output should match:
11
+ """
12
+ \s+INFO\s+Jira::Auto::Tool::EnvironmentLoader\s+:\s+Created\s+file\s.+/.config/jira-auto-tool/jira-auto-tool.env.yaml.erb
13
+ _______________________________________________
14
+ TODO: Adjust the configuration to your context!
15
+ """
16
+ And a file named "~/.config/jira-auto-tool/jira-auto-tool.env.yaml.erb" should contain exactly:
17
+ """
18
+ ---
19
+ <%
20
+ project_key = "PROJ"
21
+ sprint_field_name = "Sprint"
22
+ jira_username = "cbroult@yahoo.com"
23
+ %>
24
+ ##JIRA_API_TOKEN: WARNING - it is recommended to set the value directly as an environment variable
25
+ ART_SPRINT_REGEX:
26
+ DISABLE_COVERAGE: true
27
+ EXPECTED_START_DATE_FIELD_NAME: Expected Start
28
+ IMPLEMENTATION_TEAM_FIELD_NAME: "Implementation Team"
29
+ JAT_RATE_INTERVAL_IN_SECONDS:
30
+ JAT_RATE_LIMIT_IN_SECONDS:
31
+ JAT_TICKETS_FOR_TEAM_SPRINT_TICKET_DISPATCHER_JQL: "project = <%= project_key %> AND <%= sprint_field_name %> IS EMPTY"
32
+ JIRA_BOARD_NAME: "<%= project_key %> - Your board name"
33
+ JIRA_BOARD_NAME_REGEX: "<%= project_key %>|ART 16|unconventional board name"
34
+ JIRA_CONTEXT_PATH: /jira
35
+ JIRA_HTTP_DEBUG:
36
+ JIRA_PROJECT_KEY: <%= project_key %>
37
+ JIRA_SITE_URL: http://cbroult.atlassian.net:443/
38
+ JIRA_SPRINT_FIELD_NAME: "<%= sprint_field_name %>"
39
+ JIRA_USERNAME: <%= jira_username %>
40
+
41
+ <%
42
+ message = "TODO: set the values specific to your context and remove this part of the file"
43
+ log.error { message }
44
+ raise message
45
+ %>
46
+ """
47
+
48
+
49
+ Scenario: Not overriding an existing environment configuration file
50
+ Given a file named "~/.config/jira-auto-tool/jira-auto-tool.env.yaml.erb" with:
51
+ """
52
+ ---
53
+ JIRA_TOKEN: 'a dummy token'
54
+ """
55
+ When I run `jira-auto-tool --env-create-file`
56
+ Then it should fail matching:
57
+ """
58
+ ERROR\s+Jira::Auto::Tool::EnvironmentLoader\s+:\s+Not\s+overriding\s+existing\s+.+/.config/jira-auto-tool/jira-auto-tool.env.yaml.erb
59
+ ______________________________________________
60
+ Please remove first before running this again!
61
+ """
62
+
63
+ Scenario: Tool successfully loads the config
64
+ Given a file named "jira-auto-tool.env.yaml.erb" with:
65
+ """
66
+ ---
67
+ <%
68
+ jira_username = "user@jira.instance.com"
69
+ project_key = 'PROJ'
70
+ sprint_field_name = 'Sprint'
71
+ %>
72
+
73
+ ART_SPRINT_REGEX:
74
+ EXPECTED_START_DATE_FIELD_NAME: Expected Start
75
+ IMPLEMENTATION_TEAM_FIELD_NAME: "Implementation Team"
76
+ JAT_RATE_INTERVAL_IN_SECONDS:
77
+ JAT_RATE_LIMIT_IN_SECONDS:
78
+ JAT_TICKETS_FOR_TEAM_SPRINT_TICKET_DISPATCHER_JQL: "project = <%= project_key %> AND <%= sprint_field_name %> IS EMPTY"
79
+ JIRA_API_TOKEN: "current API TOKEN"
80
+ JIRA_BOARD_NAME: "Team Board"
81
+ JIRA_BOARD_NAME_REGEX: "ART 16|unconventional board name"
82
+ JIRA_CONTEXT_PATH: /jira
83
+ JIRA_HTTP_DEBUG:
84
+ JIRA_PROJECT_KEY: <%= project_key %>
85
+ JIRA_SITE_URL: "<%= 'https://example.atlassian.net' %>"
86
+ JIRA_SPRINT_FIELD_NAME: "<%= sprint_field_name %>"
87
+ JIRA_USERNAME: "<%= jira_username %>"
88
+ """
89
+ When I successfully run `jira-auto-tool --env-list`
90
+ Then the output should contain exactly:
91
+ """
92
+ Using configuration from ./jira-auto-tool.env.yaml.erb
93
+ +---------------------------------------------------+------------------------------------+
94
+ | Name | Value |
95
+ +---------------------------------------------------+------------------------------------+
96
+ | ART_SPRINT_REGEX | |
97
+ | EXPECTED_START_DATE_FIELD_NAME | Expected Start |
98
+ | IMPLEMENTATION_TEAM_FIELD_NAME | Implementation Team |
99
+ | JAT_RATE_INTERVAL_IN_SECONDS | |
100
+ | JAT_RATE_LIMIT_IN_SECONDS | |
101
+ | JAT_TICKETS_FOR_TEAM_SPRINT_TICKET_DISPATCHER_JQL | project = PROJ AND Sprint IS EMPTY |
102
+ | JIRA_API_TOKEN | current API TOKEN |
103
+ | JIRA_BOARD_NAME | Team Board |
104
+ | JIRA_BOARD_NAME_REGEX | ART 16|unconventional board name |
105
+ | JIRA_CONTEXT_PATH | /jira |
106
+ | JIRA_HTTP_DEBUG | |
107
+ | JIRA_PROJECT_KEY | PROJ |
108
+ | JIRA_SITE_URL | https://example.atlassian.net |
109
+ | JIRA_SPRINT_FIELD_NAME | Sprint |
110
+ | JIRA_USERNAME | user@jira.instance.com |
111
+ +---------------------------------------------------+------------------------------------+
112
+ """
113
+
114
+ Scenario: Tool looks first for configuration in the current directory
115
+ Given a file named "./jira-auto-tool.env.yaml.erb" with:
116
+ """
117
+ ---
118
+ JIRA_USERNAME: "current@company.com"
119
+ JIRA_API_TOKEN: "current-token"
120
+ JIRA_SITE_URL: "https://current.atlassian.net"
121
+ """
122
+ And a file named "~/.config/jira-auto-tool/jira-auto-tool.env.yaml.erb" with:
123
+ """
124
+ ---
125
+ JIRA_USERNAME: "home@company.com"
126
+ JIRA_API_TOKEN: "home-token"
127
+ JIRA_SITE_URL: "https://home.atlassian.net"
128
+ """
129
+ When I successfully run `jira-auto-tool --env-list`
130
+ Then the output should contain:
131
+ """
132
+ Using configuration from ./jira-auto-tool.env.yaml.erb
133
+ """
134
+
135
+ Scenario: Tool looks for home directory config folder when no config file in the current directory
136
+ Given a file named "./jira-auto-tool.env.yaml.erb" does not exist
137
+ And a file named "~/.config/jira-auto-tool/jira-auto-tool.env.yaml.erb" with:
138
+ """
139
+ JIRA_USERNAME: "home@company.com"
140
+ JIRA_API_TOKEN: "home-token"
141
+ JIRA_SITE_URL: "https://home.atlassian.net"
142
+ """
143
+ When I successfully run `jira-auto-tool --env-list`
144
+ Then the output should match:
145
+ """
146
+ Using configuration from .+/.config/jira-auto-tool/jira-auto-tool.env.yaml.erb
147
+ """
148
+
149
+ Scenario: Tool uses the existing environment values if no config file found
150
+ Given the following files should not exist:
151
+ | ./jira-auto-tool.env.yaml.erb |
152
+ | ~/.config/jira-auto-tool/jira-auto-tool.env.yaml.erb |
153
+ And the following environment variables are set:
154
+ | name | value |
155
+ | JIRA_API_TOKEN | token-value |
156
+ When I successfully run `jira-auto-tool --env-list`
157
+ Then the output should match:
158
+ """
159
+ Only using the environment variables since neither of the following files exist:
160
+ ./jira-auto-tool.env.yaml.erb
161
+ .+/.config/jira-auto-tool/jira-auto-tool.env.yaml.erb
162
+ """
163
+ And the output should match:
164
+ """
165
+ JIRA_API_TOKEN\s+|token-value\s+
166
+ """
@@ -21,9 +21,9 @@ Feature: Sprint Filtering
21
21
  """
22
22
  \+-------+--\+
23
23
  \| \s+ Matching Sprints \s+ \|
24
- \+-------\+-------------------------\+----------------\+-------------------------\+-------------------------\+-----------------------\+---------------------------------+--\+-------------------\+
25
- \| Id \| Name \| Length In Days \| Start Date \| End Date \| Board Name \| Board UI URL \s+ \| Board Project Key \|
26
- \+-------\+-------------------------\+----------------\+-------------------------\+-------------------------\+-----------------------\+---------------------------------+--\+-------------------\+
24
+ \+----+-\+-------------------------\+----------------\+-------------------------\+-------------------------\+-----------------------\+---------------------------------+--\+-------------------\+
25
+ \| Id \s+\| Name \| Length In Days \| Start Date \| End Date \| Board Name \| Board UI URL \s+ \| Board Project Key \|
26
+ \+----+-\+-------------------------\+----------------\+-------------------------\+-------------------------\+-----------------------\+---------------------------------+--\+-------------------\+
27
27
  """
28
28
  And the output should match:
29
29
  """
@@ -40,13 +40,13 @@ Feature: Sprint Filtering
40
40
 
41
41
  Scenario: No filtering (except closed sprints) and excluding the corresponding board information
42
42
  When I successfully run `jira-auto-tool --sprint-list-without-board-info`
43
- Then the stdout should contain:
43
+ Then the output should match:
44
44
  """
45
- +------------------------------------------------------------------------------------------------------+
46
- | Matching Sprints |
47
- +-------+-------------------------+----------------+-------------------------+-------------------------+
48
- | Id | Name | Length In Days | Start Date | End Date |
49
- +-------+-------------------------+----------------+-------------------------+-------------------------+
45
+ \+------+----------------------------------------------------------------------------------------------\+
46
+ \| \s+ Matching Sprints \s+ \|
47
+ \+-----+-\+-------------------------\+----------------\+-------------------------\+-------------------------\+
48
+ \| Id \s+\| Name \| Length In Days \| Start Date \| End Date \|
49
+ \+-----+-\+-------------------------\+----------------\+-------------------------\+-------------------------\+
50
50
  """
51
51
  And the output should match:
52
52
  """
@@ -68,11 +68,11 @@ Feature: Sprint Filtering
68
68
  When I successfully run `jira-auto-tool --sprint-list`
69
69
  Then the output should match:
70
70
  """
71
- \+---------+------------\+
71
+ \+--------+------------\+
72
72
  \| \s+ Matching Sprints \s+ \|
73
- \+-------\+---------+--------\+----------------\+-------------------------\+-------------------------\+-----------------------\+---------------------------------+--\+-------------------\+
74
- \| Id \| Name \s+ \| Length In Days \| Start Date \| End Date \| Board Name \| Board UI URL \s+ \| Board Project Key \|
75
- \+-------\+---------+--------\+----------------\+-------------------------\+-------------------------\+-----------------------\+---------------------------------+--\+-------------------\+
73
+ \+-----+-\+---------+--------\+----------------\+-------------------------\+-------------------------\+-----------------------\+---------------------------------+--\+-------------------\+
74
+ \| Id \s+\| Name \s+ \| Length In Days \| Start Date \| End Date \| Board Name \| Board UI URL \s+ \| Board Project Key \|
75
+ \+-----+-\+---------+--------\+----------------\+-------------------------\+-------------------------\+-----------------------\+---------------------------------+--\+-------------------\+
76
76
  """
77
77
  And the output should match:
78
78
  """
@@ -93,11 +93,11 @@ Feature: Sprint Filtering
93
93
  When I successfully run `jira-auto-tool --sprint-list`
94
94
  Then the output should match:
95
95
  """
96
- \+-----------+------\+
96
+ \+-------+------\+
97
97
  \| \s+ Matching Sprints \s+ \|
98
- \+-------\+---------+-------\+----------------\+-------------------------\+-------------------------\+-----------------------\+---------------------------------+--\+-------------------\+
99
- \| Id \| Name \s+ \| Length In Days \| Start Date \| End Date \| Board Name \| Board UI URL \s+ \| Board Project Key \|
100
- \+-------\+---------+-------\+----------------\+-------------------------\+-------------------------\+-----------------------\+---------------------------------+--\+-------------------\+
98
+ \+-----+-\+---------+-------\+----------------\+-------------------------\+-------------------------\+-----------------------\+---------------------------------+--\+-------------------\+
99
+ \| Id \s+\| Name \s+ \| Length In Days \| Start Date \| End Date \| Board Name \| Board UI URL \s+ \| Board Project Key \|
100
+ \+-----+-\+---------+-------\+----------------\+-------------------------\+-------------------------\+-----------------------\+---------------------------------+--\+-------------------\+
101
101
  """
102
102
  And the output should match:
103
103
  """
@@ -11,19 +11,15 @@ module Jira
11
11
  def self.add(tool, parser)
12
12
  ::ARGV << DISPLAY_HELP_OPTION if ARGV.empty?
13
13
 
14
- add_help_banner_and_options(parser)
15
-
16
- parser.on("-v", "--version", "Print the version") do
17
- Kernel.puts tool.class::VERSION
14
+ parser.section_header "Common"
18
15
 
19
- Kernel.exit 1
20
- end
16
+ add_help_banner_and_options(parser)
17
+ add_version_options(parser, tool)
21
18
  end
22
19
 
23
20
  def self.add_help_banner_and_options(parser)
24
21
  parser.banner = <<~EOBANNER
25
22
  Usage: #{File.basename($PROGRAM_NAME)} [options]*
26
-
27
23
  EOBANNER
28
24
 
29
25
  parser.on("-h", DISPLAY_HELP_OPTION, "Print this help") do
@@ -31,6 +27,14 @@ module Jira
31
27
  Kernel.exit 1
32
28
  end
33
29
  end
30
+
31
+ def self.add_version_options(parser, tool)
32
+ parser.on("-v", "--version", "Print the version") do
33
+ Kernel.puts tool.class::VERSION
34
+
35
+ Kernel.exit 1
36
+ end
37
+ end
34
38
  end
35
39
  end
36
40
  end
@@ -5,11 +5,12 @@ module Jira
5
5
  class Tool
6
6
  class Config
7
7
  class Options
8
- def self.add(_tool, parser)
8
+ def self.add(_tool, _parser)
9
9
  # parser.section_header "Config"
10
- #
10
+
11
11
  # parser.on("--config-list") do
12
- # # TODO: tool.config.list
12
+ # Config.list
13
+ # TODO: tool.config.list
13
14
  # end
14
15
  end
15
16
  end
@@ -32,15 +32,19 @@ module Jira
32
32
  end
33
33
 
34
34
  def path
35
- File.join(dir, "jira-auto-tool.config.yml")
35
+ File.join(dir, "#{tool_name}.config.yml")
36
36
  end
37
37
 
38
38
  def dir
39
- config_dir = File.join(Dir.home, ".config/jira-auto-tool")
39
+ config_dir = File.join(Dir.home, ".config/#{tool_name}")
40
40
  FileUtils.makedirs(config_dir)
41
41
  config_dir
42
42
  end
43
43
 
44
+ def tool_name
45
+ "jira-auto-tool"
46
+ end
47
+
44
48
  private
45
49
 
46
50
  def sanitize_key(key)
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jira
4
+ module Auto
5
+ class Tool
6
+ class EnvironmentLoader
7
+ module Options
8
+ def self.add(tool, parser)
9
+ parser.section_header "Environment"
10
+
11
+ parser.on("--env-list", "List the environment variables used by the tool") do
12
+ tool.environment.list
13
+ end
14
+
15
+ parser.on("--env-create-file", "Create the environment configuration file") { tool.environment.create_file }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jira
4
+ module Auto
5
+ class Tool
6
+ class EnvironmentLoader
7
+ attr_reader :tool
8
+
9
+ def initialize(tool, auto_setup: true)
10
+ @tool = tool
11
+
12
+ setup if auto_setup
13
+ end
14
+
15
+ def create_file
16
+ if File.exist?(file_path)
17
+ log.error do
18
+ <<~EOERRORMESSAGE
19
+ Not overriding existing #{file_path}
20
+ ______________________________________________
21
+ Please remove first before running this again!
22
+ EOERRORMESSAGE
23
+ end
24
+
25
+ Kernel.exit 1
26
+ else
27
+ FileUtils.cp(example_file_path, file_path)
28
+
29
+ log.info do
30
+ <<~EOMESSAGE
31
+ Created file #{file_path}
32
+ _______________________________________________
33
+ TODO: Adjust the configuration to your context!
34
+ EOMESSAGE
35
+ end
36
+ end
37
+ end
38
+
39
+ def list
40
+ $stdout.puts <<~EOLIST
41
+ #{configuration_source_string}
42
+ #{table}
43
+ EOLIST
44
+ end
45
+
46
+ def tool_environment
47
+ Environment.constants.sort.to_h do |constant|
48
+ constant_as_string = constant.to_s
49
+
50
+ [constant_as_string, ENV.fetch(constant_as_string, nil)]
51
+ end
52
+ end
53
+
54
+ def file_path
55
+ File.exist?(current_dir_file_path) ? current_dir_file_path : config_dir_file_path
56
+ end
57
+
58
+ def example_file_path
59
+ File.join(tool.home_dir, "config/examples", file_basename)
60
+ end
61
+
62
+ CURRENT_DIR = "."
63
+
64
+ private
65
+
66
+ def setup
67
+ config_values.each { |key, value| ENV[key] = value }
68
+ end
69
+
70
+ def configuration_source_string
71
+ if File.exist?(file_path)
72
+ "Using configuration from #{file_path}"
73
+ else
74
+ <<~EOENV_ONLY
75
+ Only using the environment variables since neither of the following files exist:
76
+ #{current_dir_file_path}
77
+ #{config_dir_file_path}
78
+ EOENV_ONLY
79
+ end
80
+ end
81
+
82
+ def config_values
83
+ @config_values ||= YAML.safe_load(config_file_content) || {}
84
+ end
85
+
86
+ def config_file_content
87
+ @config_file_content ||= File.exist?(file_path) ? ERB.new(File.read(file_path)).result(binding) : ""
88
+ end
89
+
90
+ def table
91
+ Terminal::Table.new do |t|
92
+ t.headings = %w[Name Value]
93
+ t.rows = tool_environment.to_a
94
+ end
95
+ end
96
+
97
+ def config
98
+ tool.config
99
+ end
100
+
101
+ def config_dir_file_path
102
+ File.join(config.dir, file_basename)
103
+ end
104
+
105
+ def current_dir_file_path
106
+ File.join(CURRENT_DIR, file_basename)
107
+ end
108
+
109
+ def file_basename
110
+ "#{config.tool_name}.env.yaml.erb"
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -55,10 +55,10 @@ module Jira
55
55
  constant_name = method_name.to_s.upcase
56
56
  class_eval <<-EOCONSTANT, __FILE__, __LINE__ + 1
57
57
  # This module and constant will be interpolated as follows:
58
- # module Environment
58
+ # class Environment
59
59
  # CONSTANT_NAME = "CONSTANT_NAME"
60
60
  # end
61
- module Environment
61
+ class Environment
62
62
  #{constant_name} = #{constant_name.inspect}
63
63
  end
64
64
  EOCONSTANT
@@ -10,7 +10,7 @@ class OptionParser
10
10
  on <<~EOSH
11
11
 
12
12
  #{header_name}
13
- #{header_name.gsub(/./, "-")}
13
+ #{header_name.gsub(/./, "*")}
14
14
  EOSH
15
15
  end
16
16
  end
@@ -3,7 +3,7 @@
3
3
  module Jira
4
4
  module Auto
5
5
  class Tool
6
- VERSION = "1.0.0"
6
+ VERSION = "1.1.2"
7
7
  end
8
8
  end
9
9
  end
@@ -8,6 +8,7 @@ require "jira-ruby"
8
8
 
9
9
  require_relative "tool/config"
10
10
  require_relative "tool/board_controller"
11
+ require_relative "tool/environment_loader"
11
12
  require_relative "tool/helpers/environment_based_value"
12
13
  require_relative "tool/project"
13
14
  require_relative "tool/rate_limited_jira_client"
@@ -23,15 +24,26 @@ require_relative "tool/version"
23
24
 
24
25
  module Jira
25
26
  module Auto
27
+ # rubocop:disable Metrics/ClassLength
26
28
  class Tool
27
29
  extend Helpers::EnvironmentBasedValue
28
30
 
29
31
  class Error < StandardError; end
30
32
 
33
+ attr_reader :environment
34
+
35
+ def initialize
36
+ @environment = EnvironmentLoader.new(self)
37
+ end
38
+
31
39
  def config
32
40
  @config ||= Config.new(self)
33
41
  end
34
42
 
43
+ def home_dir
44
+ File.expand_path(File.join("..", "..", ".."), __dir__)
45
+ end
46
+
35
47
  def board_name
36
48
  jira_board_name
37
49
  end
@@ -212,5 +224,7 @@ module Jira
212
224
  .create_sprint(self, board.id, attributes)
213
225
  end
214
226
  end
227
+
228
+ # rubocop:enable Metrics/ClassLength
215
229
  end
216
230
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ def validate_version_type(type)
4
+ valid_types = %w[patch minor major]
5
+ return if valid_types.include?(type)
6
+
7
+ puts "Error: Version type must be one of: #{valid_types.join(", ")}"
8
+ exit 1
9
+ end
10
+
11
+ def execute_version_bump(type)
12
+ puts "Bumping #{type} version..."
13
+ bump_result = system("bundle exec gem bump --version #{type}")
14
+ return if bump_result
15
+
16
+ puts "Error: Failed to bump version"
17
+ exit 1
18
+ end
19
+
20
+ def update_gemfile_lock
21
+ puts "Updating Gemfile.lock..."
22
+ bundle_result = system("bundle install")
23
+ return if bundle_result
24
+
25
+ puts "Error: Failed to update Gemfile.lock"
26
+ exit 1
27
+ end
28
+
29
+ def amend_commit_to_include_gemfile_lock_changes
30
+ puts "Amending commit to include Gemfile.lock update..."
31
+ system("git add .")
32
+ system(%(git commit --amend --no-edit))
33
+ end
34
+
35
+ namespace :version do
36
+ desc "Bump version (patch, minor, major) and update Gemfile.lock in a single step. Default: patch"
37
+ task :bump, [:type] do |_t, args|
38
+ args.with_defaults(type: "patch")
39
+
40
+ validate_version_type(args.type)
41
+
42
+ execute_version_bump(args.type)
43
+ update_gemfile_lock
44
+ amend_commit_to_include_gemfile_lock_changes
45
+
46
+ puts <<~EOEM
47
+ Version successfully bumped and committed!
48
+
49
+ Run 'git push' to push the changes to your remote repository.
50
+ EOEM
51
+ end
52
+ end
53
+
54
+ desc "Alias for version:bump"
55
+ task :bump, [:type] => ["version:bump"]
@@ -12,7 +12,10 @@ module Jira
12
12
  let(:tool) { Tool.new }
13
13
  let(:parser) { OptionParser.new }
14
14
 
15
- before { described_class.add(tool, parser) }
15
+ before do
16
+ allow(EnvironmentLoader).to receive_messages(new: instance_double(EnvironmentLoader))
17
+ described_class.add(tool, parser)
18
+ end
16
19
 
17
20
  context "when using --help" do
18
21
  it do
@@ -0,0 +1,180 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rspec"
4
+
5
+ module Jira
6
+ module Auto
7
+ class Tool
8
+ class EnvironmentLoader
9
+ RSpec.describe EnvironmentLoader do
10
+ let(:environment_loader) { described_class.new(tool, auto_setup: auto_setup) }
11
+ let(:auto_setup) { false }
12
+ let(:tool) { instance_double(Tool, config: config) }
13
+ let(:config) { instance_double(Config, dir: "config_dir", tool_name: "jira-auto-tool") }
14
+
15
+ # rubocop:disable RSpec/AnyInstance
16
+ describe "#initialize" do
17
+ context "when auto_setup is true" do
18
+ let(:auto_setup) { true }
19
+
20
+ it do
21
+ expect_any_instance_of(described_class).to receive(:setup)
22
+
23
+ environment_loader
24
+ end
25
+ end
26
+
27
+ context "when auto_setup is false" do
28
+ let(:auto_setup) { false }
29
+
30
+ it do
31
+ expect_any_instance_of(described_class).not_to receive(:setup)
32
+
33
+ environment_loader
34
+ end
35
+ end
36
+ end
37
+ # rubocop:enable RSpec/AnyInstance
38
+
39
+ describe "#file_path" do
40
+ before do
41
+ allow(File).to receive(:exist?).with("./jira-auto-tool.env.yaml.erb")
42
+ .and_return(current_directory_file_exists)
43
+ end
44
+
45
+ context "when file exists in current directory" do
46
+ let(:current_directory_file_exists) { true }
47
+
48
+ it { expect(environment_loader.file_path).to eq("./jira-auto-tool.env.yaml.erb") }
49
+ end
50
+
51
+ context "when file does not exist in current directory" do
52
+ let(:current_directory_file_exists) { false }
53
+
54
+ it { expect(environment_loader.file_path).to eq("config_dir/jira-auto-tool.env.yaml.erb") }
55
+ end
56
+ end
57
+
58
+ describe "#tool_environment" do
59
+ let(:environment_keys) { %i[JIRA_HOST JIRA_USER JIRA_PASSWORD] }
60
+
61
+ before do
62
+ allow(Environment).to receive(:constants).and_return(environment_keys)
63
+
64
+ environment_keys.each do |environment_key|
65
+ allow(ENV).to receive(:fetch).with(environment_key.to_s, nil).and_return("#{environment_key} value")
66
+ end
67
+ end
68
+
69
+ it do
70
+ expect(environment_loader.tool_environment).to eq(
71
+ "JIRA_HOST" => "JIRA_HOST value",
72
+ "JIRA_USER" => "JIRA_USER value",
73
+ "JIRA_PASSWORD" => "JIRA_PASSWORD value"
74
+ )
75
+ end
76
+ end
77
+
78
+ describe "#create_file" do
79
+ let(:logger) { instance_double(Logger) }
80
+
81
+ before do
82
+ allow(environment_loader)
83
+ .to receive_messages(file_path: "file_path", example_file_path: "example_file_path", log: logger)
84
+
85
+ allow(File).to receive(:exist?).with("file_path").and_return(file_path_exists)
86
+ end
87
+
88
+ context "when file does not exist" do
89
+ let(:file_path_exists) { false }
90
+
91
+ it "copies the example config file" do
92
+ expect(FileUtils).to receive(:cp).with("example_file_path", "file_path")
93
+
94
+ expect(logger).to receive(:info) do |&block|
95
+ expect(block.call).to eq(<<~EOCREATIONMESSAGE)
96
+ Created file file_path
97
+ _______________________________________________
98
+ TODO: Adjust the configuration to your context!
99
+ EOCREATIONMESSAGE
100
+ end
101
+
102
+ environment_loader.create_file
103
+ end
104
+ end
105
+
106
+ context "when file already exists" do
107
+ let(:file_path_exists) { true }
108
+
109
+ it "does not copy the example config file if it already exists" do
110
+ expect(logger).to receive(:error) do |&block|
111
+ expect(block.call).to eq(<<~EOEXPECTED_ERROR_MESSAGE)
112
+ Not overriding existing file_path
113
+ ______________________________________________
114
+ Please remove first before running this again!
115
+ EOEXPECTED_ERROR_MESSAGE
116
+ end
117
+
118
+ expect(Kernel).to receive(:exit).with(1)
119
+
120
+ environment_loader.create_file
121
+ end
122
+ end
123
+ end
124
+
125
+ describe "#example_file_path" do
126
+ before { allow(tool).to receive_messages(home_dir: "<JIRA_AUTO_TOOL_HOME_DIR>") }
127
+
128
+ it "returns the path to the example config file" do
129
+ expect(environment_loader.example_file_path)
130
+ .to eq("<JIRA_AUTO_TOOL_HOME_DIR>/config/examples/jira-auto-tool.env.yaml.erb")
131
+ end
132
+ end
133
+
134
+ describe "#setup" do
135
+ it "sets up the value according to the configuration file content" do
136
+ allow(environment_loader).to receive_messages(file_path: "file_path")
137
+ allow(environment_loader).to receive_messages(config_file_content: "file_content")
138
+
139
+ allow(YAML)
140
+ .to receive(:safe_load).with("file_content")
141
+ .and_return({ "a_key" => "a_value", "another_key" => "another_value" })
142
+
143
+ expect(ENV).to receive(:[]=).with("a_key", "a_value")
144
+ expect(ENV).to receive(:[]=).with("another_key", "another_value")
145
+
146
+ environment_loader.send(:setup)
147
+ end
148
+ end
149
+
150
+ describe "#config_file_content" do
151
+ let(:file_path) { "file_path" }
152
+ let(:file_content) do
153
+ <<-YAML_ERB
154
+ ---
155
+ a_key: <%= 4*4 %>
156
+ another_key: another_value
157
+ YAML_ERB
158
+ end
159
+
160
+ let(:erb_result) do
161
+ <<-YAML
162
+ ---
163
+ a_key: 16
164
+ another_key: another_value
165
+ YAML
166
+ end
167
+
168
+ before do
169
+ allow(environment_loader).to receive_messages(file_path: file_path)
170
+ allow(File).to receive(:exist?).with(file_path).and_return(true)
171
+ allow(File).to receive(:read).with(file_path).and_return(file_content)
172
+ end
173
+
174
+ it { expect(environment_loader.send(:config_file_content)).to eq(erb_result) }
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
@@ -12,7 +12,7 @@ RSpec.describe OptionParser do
12
12
  expect(option_parser).to receive(:on).with(<<~EOSB)
13
13
 
14
14
  a section name:
15
- ---------------
15
+ ***************
16
16
  EOSB
17
17
 
18
18
  option_parser.section_header("a section name")
@@ -9,6 +9,8 @@ module Jira
9
9
  RSpec.describe Tool do
10
10
  let(:tool) { described_class.new }
11
11
 
12
+ before { allow(EnvironmentLoader).to receive_messages(new: instance_double(EnvironmentLoader)) }
13
+
12
14
  it "has a version number" do
13
15
  expect(Jira::Auto::Tool::VERSION).not_to be_nil
14
16
  end
@@ -40,6 +42,14 @@ module Jira
40
42
  end
41
43
  end
42
44
 
45
+ describe "#environment" do
46
+ let(:environment_loader) { instance_double(EnvironmentLoader) }
47
+
48
+ before { allow(EnvironmentLoader).to receive_messages(new: environment_loader) }
49
+
50
+ it { expect(tool.environment).to eq(environment_loader) }
51
+ end
52
+
43
53
  # rubocop:disable RSpec/StubbedMock
44
54
  describe "#create_sprint" do
45
55
  it "creates a future sprint and transitions it to the desired state" do
@@ -103,6 +113,10 @@ module Jira
103
113
  it { expect(tool.sprint_controller).to be_a(SprintController) }
104
114
  end
105
115
 
116
+ describe "#home_dir" do
117
+ it { expect(tool.home_dir).to eq(File.expand_path("../../../", __dir__)) }
118
+ end
119
+
106
120
  describe "#project" do
107
121
  let(:jira_client) { instance_double(RateLimitedJiraClient, Project: project_query) }
108
122
  let(:jira_project) { instance_double(JIRA::Resource::Project) }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jira-auto-tool
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christophe Broult
@@ -213,10 +213,15 @@ files:
213
213
  - bin/jira-auto-tool.bat
214
214
  - bin/setup
215
215
  - bin/setup-dev-win.bat
216
+ - config/examples/jira-auto-tool.env.yaml.erb
216
217
  - cucumber.yml
218
+ - documentation/JiraToolClassDiagram.uml
219
+ - documentation/class_diagram.md
220
+ - documentation/principle.md
217
221
  - features/align_sprint_time_in_dates.feature
218
222
  - features/assign_tickets_to_team_sprints.feature
219
223
  - features/cache_boards.feature
224
+ - features/configure_environment.feature
220
225
  - features/control_http_request_rate_limit.feature
221
226
  - features/create_sprints_using_existing_ones_as_reference.feature
222
227
  - features/list_boards.feature
@@ -246,6 +251,8 @@ files:
246
251
  - lib/jira/auto/tool/common_options.rb
247
252
  - lib/jira/auto/tool/config.rb
248
253
  - lib/jira/auto/tool/config/options.rb
254
+ - lib/jira/auto/tool/environment_loader.rb
255
+ - lib/jira/auto/tool/environment_loader/options.rb
249
256
  - lib/jira/auto/tool/fetch_custom_field_options.rb
250
257
  - lib/jira/auto/tool/field.rb
251
258
  - lib/jira/auto/tool/field_controller.rb
@@ -291,6 +298,7 @@ files:
291
298
  - lib/jira/auto/tool/ticket.rb
292
299
  - lib/jira/auto/tool/until_date.rb
293
300
  - lib/jira/auto/tool/version.rb
301
+ - lib/tasks/version.rake
294
302
  - sig/jira/sprint/tool.rbs
295
303
  - spec/jira/auto/tool/board/cache_spec.rb
296
304
  - spec/jira/auto/tool/board/unavailable_board_spec.rb
@@ -299,6 +307,7 @@ files:
299
307
  - spec/jira/auto/tool/board_spec.rb
300
308
  - spec/jira/auto/tool/common_options_spec.rb
301
309
  - spec/jira/auto/tool/config_spec.rb
310
+ - spec/jira/auto/tool/environment_loader_spec.rb
302
311
  - spec/jira/auto/tool/field_controller_spec.rb
303
312
  - spec/jira/auto/tool/field_option_spec.rb
304
313
  - spec/jira/auto/tool/field_spec.rb