jira-auto-tool 1.0.0 → 1.1.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: ef155479c2de20dfb3e3832c19a641451e04f80223f72d549f00b9deef55bfb1
4
- data.tar.gz: fd35c88ae871e535a8d5a2423a2a93725593f9124a290656b37221b229071905
3
+ metadata.gz: 17df99358f86abaa36bf5e36882881e34df34de901441daf121e98b86fbd4ea2
4
+ data.tar.gz: 9fb2d8b44488861db052fdabab616260ca0b276dfd1f595a39ccff8822a83b0b
5
5
  SHA512:
6
- metadata.gz: b5913dded0750570c80fe1be755edf588a1f136f0ba417ff1168ae6093d1fa58406252f18280a4158c46971532445d20a00c0b4bbf82cd800176192f776664ff
7
- data.tar.gz: '09aeea8783e1c9ff219b202e1b6ad031870e802b4f4b6bdfaeb33f3adeed47f8ca93056f79127a50edda131b115e4f232fc19be0e794e30ecafd28e954c6ca0c'
6
+ metadata.gz: 7d65dab75a5828d2d2ecc2c533aca864abb0a4f541f662ab4740fcda352805e80482bd6c8aefefc5bd13290a1b2365072732f5813b6365e9928d373ca7f300a7
7
+ data.tar.gz: a62f5ad58f3cb57756c5c1e9589665553eb802cfa1e8af60629cf27aea3451a0129e4b7a1b808ce28b2db98eb2d5d3da1d44ac8fadb81b49dcabbe176777299b
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/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
+ """
@@ -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_loader 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
@@ -70,7 +70,7 @@ module Jira
70
70
  environment_variable_name = caller_method_name.upcase
71
71
 
72
72
  value = ENV.fetch(environment_variable_name) do |name|
73
- raise KeyError, "Missing #{name} environment variable!"
73
+ raise KeyError, "Missing #{name} environment_loader variable!"
74
74
  end
75
75
 
76
76
  log.debug { "fetch_corresponding_environment_variable(#{environment_variable_name}) - #{value.inspect}" }
@@ -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.0"
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
@@ -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
@@ -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_loader" 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) }
@@ -117,7 +131,7 @@ module Jira
117
131
  end
118
132
 
119
133
  # TODO: move that to environment_based_value_spec
120
- RSpec.shared_examples "an overridable environment based value" do |method_name|
134
+ RSpec.shared_examples "an overridable environment_loader based value" do |method_name|
121
135
  let(:env_var_name) { method_name.to_s.upcase }
122
136
  let(:method_name?) { :"#{method_name}_defined?" }
123
137
  let(:config) { Config.new(object_with_overridable_value) }
@@ -127,7 +141,7 @@ module Jira
127
141
  allow(config).to receive_messages(value_store: {})
128
142
  end
129
143
 
130
- context "when the environment variable is set" do
144
+ context "when the environment_loader variable is set" do
131
145
  let(:expected_value) { "#{env_var_name} env_value" }
132
146
 
133
147
  before do
@@ -142,7 +156,7 @@ module Jira
142
156
  .to eq(expected_value)
143
157
  end
144
158
 
145
- it "fetches its value from the environment" do
159
+ it "fetches its value from the environment_loader" do
146
160
  expect(object_with_overridable_value.send(method_name)).to eq(expected_value)
147
161
  end
148
162
 
@@ -159,11 +173,11 @@ module Jira
159
173
  end
160
174
  end
161
175
 
162
- context "when the environment variable is not set" do
176
+ context "when the environment_loader variable is not set" do
163
177
  before do
164
178
  allow(ENV).to receive(:fetch)
165
179
  .with(env_var_name)
166
- .and_raise(KeyError.new("Missing #{env_var_name} environment variable!)"))
180
+ .and_raise(KeyError.new("Missing #{env_var_name} environment_loader variable!)"))
167
181
 
168
182
  allow(ENV).to receive(:key?).with(env_var_name).and_return(false)
169
183
  end
@@ -175,9 +189,9 @@ module Jira
175
189
  .to eq("DEFAULT_VALUE")
176
190
  end
177
191
 
178
- it "raises an error if the environment variable is not found" do
192
+ it "raises an error if the environment_loader variable is not found" do
179
193
  expect { object_with_overridable_value.send(method_name) }
180
- .to raise_error(KeyError, /Missing #{env_var_name} environment variable!/)
194
+ .to raise_error(KeyError, /Missing #{env_var_name} environment_loader variable!/)
181
195
  end
182
196
  end
183
197
 
@@ -218,10 +232,10 @@ module Jira
218
232
  jira_site_url jira_username
219
233
  jira_sprint_field_name
220
234
  ].each do |method_name|
221
- describe "environment based values" do
235
+ describe "environment_loader based values" do
222
236
  let(:object_with_overridable_value) { tool }
223
237
 
224
- it_behaves_like "an overridable environment based value", method_name
238
+ it_behaves_like "an overridable environment_loader based value", method_name
225
239
  end
226
240
  end
227
241
 
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.0
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
@@ -299,6 +306,7 @@ files:
299
306
  - spec/jira/auto/tool/board_spec.rb
300
307
  - spec/jira/auto/tool/common_options_spec.rb
301
308
  - spec/jira/auto/tool/config_spec.rb
309
+ - spec/jira/auto/tool/environment_loader_spec.rb
302
310
  - spec/jira/auto/tool/field_controller_spec.rb
303
311
  - spec/jira/auto/tool/field_option_spec.rb
304
312
  - spec/jira/auto/tool/field_spec.rb