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 +4 -4
- data/README.md +15 -5
- data/Rakefile +4 -0
- data/bin/jira-auto-tool +2 -0
- data/config/examples/jira-auto-tool.env.yaml.erb +28 -0
- data/documentation/JiraToolClassDiagram.uml +44 -0
- data/documentation/class_diagram.md +48 -0
- data/documentation/principle.md +6 -0
- data/features/configure_environment.feature +166 -0
- data/features/sprint_filtering.feature +17 -17
- data/lib/jira/auto/tool/common_options.rb +11 -7
- data/lib/jira/auto/tool/config/options.rb +4 -3
- data/lib/jira/auto/tool/config.rb +6 -2
- data/lib/jira/auto/tool/environment_loader/options.rb +21 -0
- data/lib/jira/auto/tool/environment_loader.rb +115 -0
- data/lib/jira/auto/tool/helpers/environment_based_value.rb +2 -2
- data/lib/jira/auto/tool/helpers/option_parser.rb +1 -1
- data/lib/jira/auto/tool/version.rb +1 -1
- data/lib/jira/auto/tool.rb +14 -0
- data/lib/tasks/version.rake +55 -0
- data/spec/jira/auto/tool/common_options_spec.rb +4 -1
- data/spec/jira/auto/tool/environment_loader_spec.rb +180 -0
- data/spec/jira/auto/tool/helpers/option_parser_spec.rb +1 -1
- data/spec/jira/auto/tool_spec.rb +14 -0
- metadata +10 -1
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: add7c4637bf997f40928d5c82ccb61253feee7f9bc671068b41e38e706843402
         | 
| 4 | 
            +
              data.tar.gz: 5a7f0d706305157e7efae7656834c56ec9f70e32042547fcf660255c8b26c539
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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 | 
            -
             | 
| 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 | 
            -
            *  | 
| 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  | 
| 78 | 
            -
             | 
| 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
    
    
    
        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,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 | 
| 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  | 
| 43 | 
            +
                Then the output should match:
         | 
| 44 44 | 
             
                  """
         | 
| 45 | 
            -
                   | 
| 46 | 
            -
                   | 
| 47 | 
            -
                   | 
| 48 | 
            -
                   | 
| 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 | 
| 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 | 
| 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 | 
            -
                       | 
| 15 | 
            -
             | 
| 16 | 
            -
                      parser.on("-v", "--version", "Print the version") do
         | 
| 17 | 
            -
                        Kernel.puts tool.class::VERSION
         | 
| 14 | 
            +
                      parser.section_header "Common"
         | 
| 18 15 |  | 
| 19 | 
            -
             | 
| 20 | 
            -
                       | 
| 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,  | 
| 8 | 
            +
                      def self.add(_tool, _parser)
         | 
| 9 9 | 
             
                        # parser.section_header "Config"
         | 
| 10 | 
            -
             | 
| 10 | 
            +
             | 
| 11 11 | 
             
                        # parser.on("--config-list") do
         | 
| 12 | 
            -
                        # | 
| 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, " | 
| 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 | 
| 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 | 
            -
                          #  | 
| 58 | 
            +
                          # class Environment
         | 
| 59 59 | 
             
                          #   CONSTANT_NAME = "CONSTANT_NAME"
         | 
| 60 60 | 
             
                          # end
         | 
| 61 | 
            -
                           | 
| 61 | 
            +
                          class Environment
         | 
| 62 62 | 
             
                             #{constant_name} = #{constant_name.inspect}
         | 
| 63 63 | 
             
                          end
         | 
| 64 64 | 
             
                        EOCONSTANT
         | 
    
        data/lib/jira/auto/tool.rb
    CHANGED
    
    | @@ -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  | 
| 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
         | 
    
        data/spec/jira/auto/tool_spec.rb
    CHANGED
    
    | @@ -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. | 
| 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
         |