story_branch 0.6.1 → 0.7.0.alpha
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/Gemfile.lock +16 -14
- data/docs/index.md +168 -0
- data/lib/story_branch/cli.rb +0 -12
- data/lib/story_branch/commands/add.rb +29 -37
- data/lib/story_branch/config_manager.rb +157 -8
- data/lib/story_branch/github/tracker.rb +5 -10
- data/lib/story_branch/jira/project.rb +14 -6
- data/lib/story_branch/jira/tracker.rb +9 -12
- data/lib/story_branch/main.rb +22 -83
- data/lib/story_branch/pivotal/tracker.rb +4 -9
- data/lib/story_branch/tracker_base.rb +39 -0
- data/lib/story_branch/version.rb +1 -1
- data/story_branch.gemspec +2 -1
- metadata +23 -8
- data/lib/story_branch/commands/migrate.rb +0 -103
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a12f882753865d3d70a70e890fd74ad6f2c62437af6156dbc95d351cf6af9ac
|
4
|
+
data.tar.gz: 663c2ab9b76745eea8c95e1c30f88c39ca40b1892c1a64eb311a6f91266fefd8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2442c7a38bc27d78a1be6d8219b99d70ccf531fcab8cd25b216b36845cd88c1f4e27748ea8733d8af232ef8c7235bc375f4dd45f3912daa0b7a9838fc3ca1e2
|
7
|
+
data.tar.gz: 8814adeb71cc1b479d2e521505fa1d0b58bd7a3f2f5e49781f8c7fce863d2e1490dfd202b6f79c58c58e59dfcdfd8c61cd44d2653a55db80ef5da0aa9ae447ae
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
story_branch (0.
|
4
|
+
story_branch (0.7.0.alpha)
|
5
5
|
blanket_wrapper (~> 3.0)
|
6
6
|
damerau-levenshtein (~> 1.3)
|
7
7
|
jira-ruby (~> 1.7)
|
@@ -10,6 +10,7 @@ PATH
|
|
10
10
|
tty-config (~> 0.2.0)
|
11
11
|
tty-pager (~> 0.12)
|
12
12
|
tty-prompt (~> 0.18)
|
13
|
+
xdg (~> 3.0)
|
13
14
|
|
14
15
|
GEM
|
15
16
|
remote: https://rubygems.org/
|
@@ -35,7 +36,7 @@ GEM
|
|
35
36
|
httparty (0.17.3)
|
36
37
|
mime-types (~> 3.0)
|
37
38
|
multi_xml (>= 0.5.2)
|
38
|
-
i18n (1.
|
39
|
+
i18n (1.8.2)
|
39
40
|
concurrent-ruby (~> 1.0)
|
40
41
|
jira-ruby (1.7.1)
|
41
42
|
activesupport
|
@@ -44,10 +45,10 @@ GEM
|
|
44
45
|
oauth (~> 0.5, >= 0.5.0)
|
45
46
|
jwt (2.1.0)
|
46
47
|
method_source (0.9.2)
|
47
|
-
mime-types (3.3)
|
48
|
+
mime-types (3.3.1)
|
48
49
|
mime-types-data (~> 3.2015)
|
49
50
|
mime-types-data (3.2019.1009)
|
50
|
-
minitest (5.
|
51
|
+
minitest (5.14.0)
|
51
52
|
multi_xml (0.6.0)
|
52
53
|
multipart-post (2.1.1)
|
53
54
|
necromancer (0.5.1)
|
@@ -65,15 +66,15 @@ GEM
|
|
65
66
|
rspec-core (~> 3.9.0)
|
66
67
|
rspec-expectations (~> 3.9.0)
|
67
68
|
rspec-mocks (~> 3.9.0)
|
68
|
-
rspec-core (3.9.
|
69
|
-
rspec-support (~> 3.9.
|
69
|
+
rspec-core (3.9.1)
|
70
|
+
rspec-support (~> 3.9.1)
|
70
71
|
rspec-expectations (3.9.0)
|
71
72
|
diff-lcs (>= 1.2.0, < 2.0)
|
72
73
|
rspec-support (~> 3.9.0)
|
73
|
-
rspec-mocks (3.9.
|
74
|
+
rspec-mocks (3.9.1)
|
74
75
|
diff-lcs (>= 1.2.0, < 2.0)
|
75
76
|
rspec-support (~> 3.9.0)
|
76
|
-
rspec-support (3.9.
|
77
|
+
rspec-support (3.9.2)
|
77
78
|
rspec_junit_formatter (0.4.1)
|
78
79
|
rspec-core (>= 2, < 4, != 2.12.0)
|
79
80
|
strings (0.1.8)
|
@@ -83,7 +84,7 @@ GEM
|
|
83
84
|
strings-ansi (0.2.0)
|
84
85
|
thor (0.20.3)
|
85
86
|
thread_safe (0.3.6)
|
86
|
-
tty-color (0.5.
|
87
|
+
tty-color (0.5.1)
|
87
88
|
tty-command (0.8.2)
|
88
89
|
pastel (~> 0.7.0)
|
89
90
|
tty-config (0.2.0)
|
@@ -101,19 +102,20 @@ GEM
|
|
101
102
|
tty-screen (~> 0.7)
|
102
103
|
wisper (~> 2.0.0)
|
103
104
|
tty-screen (0.7.0)
|
104
|
-
tty-which (0.4.
|
105
|
-
tzinfo (1.2.
|
105
|
+
tty-which (0.4.2)
|
106
|
+
tzinfo (1.2.6)
|
106
107
|
thread_safe (~> 0.1)
|
107
|
-
unicode-display_width (1.6.
|
108
|
+
unicode-display_width (1.6.1)
|
108
109
|
unicode_utils (1.4.0)
|
109
110
|
wisper (2.0.1)
|
111
|
+
xdg (3.1.1)
|
110
112
|
zeitwerk (2.2.2)
|
111
113
|
|
112
114
|
PLATFORMS
|
113
115
|
ruby
|
114
116
|
|
115
117
|
DEPENDENCIES
|
116
|
-
bundler (~>
|
118
|
+
bundler (~> 2.0)
|
117
119
|
fakefs (~> 0.14)
|
118
120
|
git (~> 1.5)
|
119
121
|
ostruct (~> 0.1)
|
@@ -124,4 +126,4 @@ DEPENDENCIES
|
|
124
126
|
story_branch!
|
125
127
|
|
126
128
|
BUNDLED WITH
|
127
|
-
2.1.
|
129
|
+
2.1.3
|
data/docs/index.md
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
# Story Branch
|
2
|
+
|
3
|
+
Story branch is a CLI application that interacts with Pivotal Tracker, Github
|
4
|
+
and JIRA.
|
5
|
+
|
6
|
+
Depending on the tracker features, it provides different approaches.
|
7
|
+
|
8
|
+
- For PivotalTracker, it allows you to start and un-start stories, as well as
|
9
|
+
creating branches based on the story name and id and have a final commit message
|
10
|
+
marking the story as Finished.
|
11
|
+
|
12
|
+
- For Github and JIRA because there is not a fixed flow, it allows you to create
|
13
|
+
the branches based on the tickets name and numbers. Similarly, it supports one
|
14
|
+
final commit with a standard message.
|
15
|
+
|
16
|
+
[View Changelog](Changelog.md)
|
17
|
+
|
18
|
+
## Installing
|
19
|
+
|
20
|
+
Install the gem:
|
21
|
+
|
22
|
+
gem install story_branch
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
You should run story_branch from the git/project root folder.
|
27
|
+
|
28
|
+
## Commands available
|
29
|
+
|
30
|
+
You can see all the commands available by running
|
31
|
+
|
32
|
+
```
|
33
|
+
$ story_branch -h
|
34
|
+
|
35
|
+
Commands:
|
36
|
+
story_branch add # Add a new story branch configuration
|
37
|
+
story_branch create # Create branch from estimated stories in pivotal tracker
|
38
|
+
story_branch finish # Creates a git commit message for the staged changes with a [Finishes] tag
|
39
|
+
story_branch help [COMMAND] # Describe available commands or one specific command
|
40
|
+
story_branch migrate # Migrate old story branch configuration to the new format
|
41
|
+
story_branch start # Mark an estimated story as started in Pivotal Tracker
|
42
|
+
story_branch unstart # Mark a started story as un-started in Pivotal Tracker
|
43
|
+
story_branch version # story_branch gem version
|
44
|
+
```
|
45
|
+
|
46
|
+
## Settings
|
47
|
+
|
48
|
+
Story branch has a command available that will help you creating the configurations
|
49
|
+
for the projects, but essentially you'll be asked for the pivotal tracker project id and your api key.
|
50
|
+
|
51
|
+
### Configuring the project id
|
52
|
+
|
53
|
+
The project id you can get it easily from the url when viewing the project.
|
54
|
+
This value will be stored in the local configuration file that will be committed
|
55
|
+
to the working repository
|
56
|
+
|
57
|
+
### Configuring the api key
|
58
|
+
|
59
|
+
The api key you can get it from your account settings.
|
60
|
+
This value will be stored in your global configuration file that typically is
|
61
|
+
not shared with your co-workers in the repository. This way, each user will
|
62
|
+
be properly identified in the tracker
|
63
|
+
|
64
|
+
### Configuring the finish tag
|
65
|
+
|
66
|
+
On your local config you can add a line with `finish_tag: <Some random word>`.
|
67
|
+
This tag will be used in the commit message when running `story_branch finish`.
|
68
|
+
|
69
|
+
E.g.
|
70
|
+
`finish_tag: Resolves`
|
71
|
+
|
72
|
+
`story_branch finish` will make a commit with the message
|
73
|
+
`[Resolves #12313] story title`
|
74
|
+
|
75
|
+
|
76
|
+
### .story_branch files
|
77
|
+
|
78
|
+
When configuring story branch, it will create two .story_branch.yml files: one in
|
79
|
+
your home folder (`~/`) and one in your project's root (`./`).
|
80
|
+
The one in your home folder will be used to store the different project's configurations
|
81
|
+
such as which api key to use. This is done so you don't need to commit your
|
82
|
+
api key to the repository but still be able to use different keys in case you
|
83
|
+
have different accounts.
|
84
|
+
|
85
|
+
The one in your project root will keep a reference to the project configuration.
|
86
|
+
For now, this reference is the project id. This file can be safely committed to
|
87
|
+
the repository and shared amongst your co-workers.
|
88
|
+
|
89
|
+
## Commentary
|
90
|
+
|
91
|
+
`story_branch create`: Creates a git branch with automatic reference to a
|
92
|
+
Pivotal Tracker Story. It will get started stories from your active
|
93
|
+
project. You can enter text and press TAB to search for a story
|
94
|
+
name, or TAB to show the full list. It will then suggest an editable
|
95
|
+
branch name. When the branch is created the `story_id` will
|
96
|
+
be appended to it.
|
97
|
+
|
98
|
+
e.g. `my-story-name-1234567`
|
99
|
+
|
100
|
+
`story_branch finish`: Creates a git commit message for the staged changes.
|
101
|
+
|
102
|
+
e.g: `[Finishes #1234567] My story name`
|
103
|
+
|
104
|
+
You must stage all changes (or stash them) first. Note the commit will not
|
105
|
+
be pushed. Note: You'll be able to bail out of the commit.
|
106
|
+
|
107
|
+
`story_branch start`: Start a story in Pivotal Tracker from the terminal.
|
108
|
+
It'll get all un-started stories in your current project. You can
|
109
|
+
enter text and press TAB to search for a story name, or TAB to show
|
110
|
+
the full list.
|
111
|
+
|
112
|
+
`story_branch unstart`: Un-start a story in Pivotal Tracker from the terminal.
|
113
|
+
It'll get all started stories in your current project. You can
|
114
|
+
enter text and press TAB to search for a story name, or TAB to show
|
115
|
+
the full list.
|
116
|
+
|
117
|
+
## Configuring PivotalTracker
|
118
|
+
|
119
|
+
When running the command `story_branch add` you'll be asked 3 things:
|
120
|
+
1. tracker - You should select Pivotal Tracker
|
121
|
+
2. project id - This can be fetched from the PivotalTracker url. E.g in the url `https://www.pivotaltracker.com/n/projects/651417`, the project id would be `651417`
|
122
|
+
3. api key - this is your personal api key. You can get that from [your profile page](https://www.pivotaltracker.com/profile)
|
123
|
+
|
124
|
+
## Configuring Github
|
125
|
+
|
126
|
+
When running the command `story_branch add` you'll be asked 3 things:
|
127
|
+
1. project id - This is the github repository name in the format `<owner>/<repo_name>`. E.g. `story-branch/story_branch`.
|
128
|
+
2. tracker - You should select Github
|
129
|
+
3. api key - this is your personal api token. You can create one under your
|
130
|
+
[developer profile tokens page](https://github.com/settings/tokens)
|
131
|
+
|
132
|
+
## Configuring JIRA
|
133
|
+
|
134
|
+
The configuration for JIRA is slightly more complex as the endpoint changes according
|
135
|
+
to your project setup. You will need an API token, which you can create a new one in your [JIRA id management page](https://id.atlassian.com/manage/api-tokens)
|
136
|
+
1. tracker - You should select JIRA
|
137
|
+
2. JIRA's subdomain - you should type the JIRA's subdomain that you use to access in your browser. E.g I'd type perxtechnologies to access to https://perxtechnologies.atlassian.net
|
138
|
+
3. JIRA's project key - this should match which project you want to fetch the issues from. E.g. PW is the key for my Project Whistler, so I'd type PW
|
139
|
+
4. API key that you should have gotten in the first description step
|
140
|
+
5. username used for login in the JIRA usually. If you use google email authentication, the username should be your email
|
141
|
+
|
142
|
+
## Migrating
|
143
|
+
|
144
|
+
### Old configuration
|
145
|
+
|
146
|
+
If your were using story branch before there are some small changes on the way the
|
147
|
+
tool works. But worry not, we've written a command that allows you to migrate your
|
148
|
+
configuration. Running
|
149
|
+
|
150
|
+
`$ story_branch migrate`
|
151
|
+
|
152
|
+
will grab your existing configuration and convert it into the new format. The only
|
153
|
+
thing you'll need to provide is the project name reference.
|
154
|
+
|
155
|
+
### Old commands
|
156
|
+
|
157
|
+
Story branch was built providing a set of bin commands such as `git-story`, `git-finish`, `git-start` and `git-unstart`. These will be available still as
|
158
|
+
we try as much as possible to keep the updates retro-compatible, but are nothing
|
159
|
+
more than an alias for the CLI commands as follow:
|
160
|
+
|
161
|
+
- `git-story` runs `story_branch create`
|
162
|
+
- `git-finish` runs `story_branch finish`
|
163
|
+
- `git-start` runs `story_branch start`
|
164
|
+
- `git-unstart` runs `story_branch unstart`
|
165
|
+
|
166
|
+
## Contributing
|
167
|
+
|
168
|
+
All pull requests are welcome and will be reviewed.
|
data/lib/story_branch/cli.rb
CHANGED
@@ -78,17 +78,5 @@ module StoryBranch
|
|
78
78
|
StoryBranch::Commands::Add.new(options).execute
|
79
79
|
end
|
80
80
|
end
|
81
|
-
|
82
|
-
desc 'migrate', 'Migrate old story branch configuration to the new format'
|
83
|
-
method_option :help, aliases: '-h', type: :boolean,
|
84
|
-
desc: 'Display usage information'
|
85
|
-
def migrate(*)
|
86
|
-
if options[:help]
|
87
|
-
invoke :help, ['migrate']
|
88
|
-
else
|
89
|
-
require_relative 'commands/migrate'
|
90
|
-
StoryBranch::Commands::Migrate.new(options).execute
|
91
|
-
end
|
92
|
-
end
|
93
81
|
end
|
94
82
|
end
|
@@ -13,60 +13,61 @@ module StoryBranch
|
|
13
13
|
# It will try to load the existing global story branch config
|
14
14
|
# and then add the project id specified by the user.
|
15
15
|
class Add < StoryBranch::Command
|
16
|
-
def initialize(
|
17
|
-
@
|
18
|
-
@config = ConfigManager.init_config(Dir.home)
|
19
|
-
@local_config = ConfigManager.init_config('.')
|
16
|
+
def initialize(_options)
|
17
|
+
@new_config = ConfigManager.new
|
20
18
|
end
|
21
19
|
|
22
20
|
def execute(_input: $stdin, output: $stdout)
|
23
|
-
|
21
|
+
set_tracker_type
|
22
|
+
set_project_key
|
24
23
|
create_global_config
|
24
|
+
@new_config.save
|
25
25
|
output.puts 'Configuration added successfully'
|
26
26
|
end
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
def
|
31
|
-
return if
|
30
|
+
def set_tracker_type
|
31
|
+
return if @new_config.contains?(project_key)
|
32
32
|
|
33
33
|
puts "Setting #{tracker}"
|
34
|
-
@
|
35
|
-
|
36
|
-
puts "Appending #{project_id}"
|
37
|
-
@local_config.append(project_id, to: :project_id)
|
34
|
+
@new_config.tracker_type = tracker
|
35
|
+
end
|
38
36
|
|
39
|
-
|
37
|
+
def set_project_key
|
38
|
+
puts "Setting #{project_key}"
|
39
|
+
@new_config.project_key = project_key
|
40
40
|
end
|
41
41
|
|
42
42
|
def create_global_config
|
43
43
|
api_key = prompt.ask('Please provide the api key:', required: true)
|
44
|
-
@
|
45
|
-
@config.write(force: true)
|
44
|
+
@new_config.api_key = api_key
|
46
45
|
|
47
46
|
return unless tracker == 'jira'
|
48
47
|
|
49
|
-
# rubocop:disable
|
48
|
+
# rubocop:disable Metrics/LineLength
|
50
49
|
username = prompt.ask('Please provide username (email most of the times) for this key:',
|
51
50
|
required: true)
|
52
|
-
# rubocop:enable
|
53
|
-
@
|
54
|
-
@config.write(force: true)
|
51
|
+
# rubocop:enable Metrics/LineLength
|
52
|
+
@new_config.username = username
|
55
53
|
end
|
56
54
|
|
57
|
-
def
|
58
|
-
return @
|
55
|
+
def project_key
|
56
|
+
return @project_key if @project_key
|
59
57
|
|
58
|
+
@project_key = ask_for_project_key
|
59
|
+
end
|
60
|
+
|
61
|
+
def ask_for_project_key
|
60
62
|
if tracker == 'jira'
|
61
|
-
|
62
|
-
|
63
|
-
project_key = prompt.ask("What is your JIRA's project key?",
|
64
|
-
|
65
|
-
|
63
|
+
project_domain = prompt.ask("What is your JIRA's subdomain?",
|
64
|
+
required: true)
|
65
|
+
project_key = prompt.ask("What is your JIRA's project key?",
|
66
|
+
required: true)
|
67
|
+
|
68
|
+
"#{project_domain}|#{project_key}"
|
66
69
|
else
|
67
|
-
|
68
|
-
@project_id = prompt.ask("Please provide this project's id:", required: true)
|
69
|
-
# rubocop:enable Layout/LineLength
|
70
|
+
prompt.ask("Please provide this project's id:", required: true)
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
@@ -80,15 +81,6 @@ module StoryBranch
|
|
80
81
|
}
|
81
82
|
@tracker = prompt.select('Which tracker are you using?', trackers)
|
82
83
|
end
|
83
|
-
|
84
|
-
def local_config_has_value?
|
85
|
-
config_value = @local_config.fetch(:project_id)
|
86
|
-
if config_value.is_a? Array
|
87
|
-
config_value.include?(project_id)
|
88
|
-
else
|
89
|
-
config_value == project_id
|
90
|
-
end
|
91
|
-
end
|
92
84
|
end
|
93
85
|
end
|
94
86
|
end
|
@@ -1,20 +1,169 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'tty-config'
|
4
|
+
require 'tty-prompt'
|
5
|
+
require 'xdg'
|
4
6
|
|
5
7
|
module StoryBranch
|
6
|
-
# Config manager
|
7
|
-
# TTY::Config with the configuration file name set
|
8
|
-
#
|
8
|
+
# Config manager is used to manage all possible configuration settings
|
9
|
+
# it uses mainly TTY::Config with the configuration file name set
|
10
|
+
# rubocop:disable Metrics/ClassLength
|
9
11
|
class ConfigManager
|
10
|
-
|
11
|
-
|
12
|
-
|
12
|
+
CONFIG_FILENAME = '.story_branch'
|
13
|
+
|
14
|
+
attr_reader :errors
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@prompt = TTY::Prompt.new(interrupt: :exit)
|
18
|
+
load_configs
|
19
|
+
@config = ::TTY::Config.new
|
20
|
+
@config.merge(@local)
|
21
|
+
@config.merge(@global)
|
22
|
+
@errors = []
|
23
|
+
end
|
24
|
+
|
25
|
+
def tracker_type
|
26
|
+
@tracker_type ||= @config.fetch(:tracker, default: 'pivotal-tracker')
|
27
|
+
end
|
28
|
+
|
29
|
+
def tracker_type=(tracker)
|
30
|
+
@local.set(:tracker, value: tracker)
|
31
|
+
end
|
32
|
+
|
33
|
+
def issue_placement
|
34
|
+
@issue_placement ||= @config.fetch(:issue_placement, default: 'End')
|
35
|
+
end
|
36
|
+
|
37
|
+
def finish_tag
|
38
|
+
@finish_tag ||= @config.fetch(project_key,
|
39
|
+
:finish_tag, default: 'Finishes')
|
40
|
+
end
|
41
|
+
|
42
|
+
def project_key=(key)
|
43
|
+
@project_key = key
|
44
|
+
@local.append(key, to: :project_id) unless contains?(key)
|
45
|
+
end
|
46
|
+
|
47
|
+
def api_key=(key)
|
48
|
+
@api_key = key
|
49
|
+
@global.set(@project_key, :api_key, value: key)
|
50
|
+
end
|
51
|
+
|
52
|
+
def username=(username)
|
53
|
+
@username = username
|
54
|
+
@global.set(@project_key, :username, value: username)
|
55
|
+
end
|
56
|
+
|
57
|
+
def tracker_params
|
58
|
+
{
|
59
|
+
tracker_domain: tracker_domain,
|
60
|
+
username: username,
|
61
|
+
project_id: project_id,
|
62
|
+
api_key: api_key,
|
63
|
+
extra_query: extra_query
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
def valid?
|
68
|
+
validate
|
69
|
+
@errors.length.zero?
|
70
|
+
end
|
71
|
+
|
72
|
+
def contains?(project_key)
|
73
|
+
project_keys = @config.fetch(:project_id)
|
74
|
+
if project_keys.is_a? Array
|
75
|
+
project_keys.include?(project_key)
|
76
|
+
else
|
77
|
+
project_keys == project_key
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def save
|
82
|
+
@local.write(force: true)
|
83
|
+
@global.write(force: true)
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def api_key
|
89
|
+
@api_key ||= @config.fetch(project_key, :api_key)
|
90
|
+
end
|
91
|
+
|
92
|
+
def username
|
93
|
+
@username ||= @config.fetch(project_key, :username)
|
94
|
+
end
|
95
|
+
|
96
|
+
def project_key
|
97
|
+
return @project_key if @project_key
|
98
|
+
|
99
|
+
project_keys = @config.fetch(:project_id)
|
100
|
+
|
101
|
+
@project_key = choose_project_id(project_keys)
|
102
|
+
end
|
103
|
+
|
104
|
+
def extra_query
|
105
|
+
@extra_query ||= @config.fetch(project_key, :extra_query, default: '')
|
106
|
+
end
|
107
|
+
|
108
|
+
def project_id
|
109
|
+
return @project_id if @project_id
|
110
|
+
|
111
|
+
@project_id = if tracker_type == 'jira'
|
112
|
+
project_key.split('|')[1]
|
113
|
+
else
|
114
|
+
project_key
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def tracker_domain
|
119
|
+
return @tracker_domain if @tracker_domain
|
120
|
+
|
121
|
+
@tracker_domain = if tracker_type != 'jira'
|
122
|
+
''
|
123
|
+
else
|
124
|
+
project_key.split('|')[0]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def choose_project_id(project_ids)
|
129
|
+
return project_ids unless project_ids.is_a? Array
|
130
|
+
return project_ids[0] unless project_ids.length > 1
|
131
|
+
|
132
|
+
@prompt.select('Which project you want to fetch from?', project_ids)
|
133
|
+
end
|
134
|
+
|
135
|
+
def validate
|
136
|
+
@errors << 'Project ID is not set' if project_id.nil?
|
137
|
+
end
|
138
|
+
|
139
|
+
def load_configs
|
140
|
+
@local = read_config('.')
|
141
|
+
xdg_conf = XDG::Config.new
|
142
|
+
home_path = if conf_exist?(Dir.home)
|
143
|
+
Dir.home
|
144
|
+
else
|
145
|
+
xdg_conf.home
|
146
|
+
end
|
147
|
+
@global = read_config(home_path)
|
148
|
+
end
|
149
|
+
|
150
|
+
def read_config(path)
|
151
|
+
config = init_config(path)
|
152
|
+
config.read if config.persisted?
|
153
|
+
config
|
154
|
+
end
|
155
|
+
|
156
|
+
def conf_exist?(path)
|
157
|
+
config = init_config(path)
|
158
|
+
config.persisted?
|
159
|
+
end
|
160
|
+
|
161
|
+
def init_config(path)
|
13
162
|
config = ::TTY::Config.new
|
14
|
-
config.filename =
|
163
|
+
config.filename = CONFIG_FILENAME
|
15
164
|
config.append_path path
|
16
|
-
config.read if config.persisted? && should_read
|
17
165
|
config
|
18
166
|
end
|
19
167
|
end
|
168
|
+
# rubocop:enable Metrics/ClassLength
|
20
169
|
end
|
@@ -1,22 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'blanket'
|
4
|
+
require 'story_branch/tracker_base'
|
4
5
|
require_relative './project'
|
5
6
|
|
6
7
|
module StoryBranch
|
7
8
|
module Github
|
8
9
|
# Github API wrapper for story branch tracker
|
9
|
-
class Tracker
|
10
|
+
class Tracker < StoryBranch::TrackerBase
|
10
11
|
API_URL = 'https://api.github.com/'
|
11
|
-
TYPE = 'github'
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
def initialize(repo_name, api_key)
|
13
|
+
def initialize(project_id:, api_key:, **)
|
16
14
|
# NOTE: RepoName should follow owner/repo_name format
|
17
|
-
@repo_name =
|
15
|
+
@repo_name = project_id
|
18
16
|
@api_key = api_key
|
19
|
-
@type = TYPE
|
20
17
|
end
|
21
18
|
|
22
19
|
def valid?
|
@@ -37,9 +34,7 @@ module StoryBranch
|
|
37
34
|
|
38
35
|
private
|
39
36
|
|
40
|
-
def
|
41
|
-
raise 'API key must be specified' unless @api_key
|
42
|
-
|
37
|
+
def configure_api
|
43
38
|
Blanket.wrap API_URL, headers: {
|
44
39
|
'User-Agent' => 'Story Branch',
|
45
40
|
Authorization: "token #{@api_key}"
|
@@ -6,8 +6,9 @@ module StoryBranch
|
|
6
6
|
module Jira
|
7
7
|
# Jira Project representation
|
8
8
|
class Project
|
9
|
-
def initialize(jira_project)
|
9
|
+
def initialize(jira_project, query_addon = '')
|
10
10
|
@project = jira_project
|
11
|
+
@query_addon = query_addon
|
11
12
|
end
|
12
13
|
|
13
14
|
# Returns an array of Jira issues (Issue Class)
|
@@ -17,15 +18,22 @@ module StoryBranch
|
|
17
18
|
stories = if options[:id]
|
18
19
|
[@project.issues.find(options[:id])]
|
19
20
|
else
|
20
|
-
|
21
|
-
@project.client.Issue.jql(
|
22
|
-
"project=#{@project.key} AND status='To Do' AND assignee=currentUser()"
|
23
|
-
)
|
24
|
-
# rubocop:enable Layout/LineLength
|
21
|
+
@project.client.Issue.jql(jql_query)
|
25
22
|
end
|
26
23
|
|
27
24
|
stories.map { |s| Issue.new(s, @project) }
|
28
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def jql_query
|
30
|
+
base_query = "project=#{@project.key} AND assignee=currentUser()"
|
31
|
+
if @query_addon.length.positive?
|
32
|
+
[base_query, @query_addon].join(' AND ')
|
33
|
+
else
|
34
|
+
base_query
|
35
|
+
end
|
36
|
+
end
|
29
37
|
end
|
30
38
|
end
|
31
39
|
end
|
@@ -5,23 +5,22 @@
|
|
5
5
|
# my tracker and issues will still provide a similar api. This jira-ruby
|
6
6
|
# is used to get the data.
|
7
7
|
require 'jira-ruby'
|
8
|
+
require 'story_branch/tracker_base'
|
8
9
|
require_relative './project'
|
9
10
|
|
10
11
|
module StoryBranch
|
11
12
|
module Jira
|
12
13
|
# JIRA API wrapper for story branch tracker
|
13
|
-
class Tracker
|
14
|
-
|
15
|
-
|
16
|
-
attr_reader :type
|
17
|
-
|
18
|
-
def initialize(tracker_domain:, project_id:, api_key:, username:)
|
14
|
+
class Tracker < StoryBranch::TrackerBase
|
15
|
+
# rubocop:disable Metrics/LineLength
|
16
|
+
def initialize(tracker_domain:, project_id:, api_key:, username:, extra_query:)
|
19
17
|
@tracker_url = "https://#{tracker_domain}.atlassian.net"
|
20
18
|
@project_id = project_id
|
21
19
|
@api_key = api_key
|
22
20
|
@username = username
|
23
|
-
@
|
21
|
+
@extra_query = extra_query
|
24
22
|
end
|
23
|
+
# rubocop:enable Metrics/LineLength
|
25
24
|
|
26
25
|
def valid?
|
27
26
|
[@api_key, @project_id, @username, @tracker_url].none?(&:nil?)
|
@@ -52,10 +51,8 @@ module StoryBranch
|
|
52
51
|
}
|
53
52
|
end
|
54
53
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
@api ||= JIRA::Client.new(options)
|
54
|
+
def configure_api
|
55
|
+
JIRA::Client.new(options)
|
59
56
|
end
|
60
57
|
|
61
58
|
def project
|
@@ -63,7 +60,7 @@ module StoryBranch
|
|
63
60
|
raise 'project key must be set' unless @project_id
|
64
61
|
|
65
62
|
jira_project = api.Project.find(@project_id)
|
66
|
-
@project = Project.new(jira_project)
|
63
|
+
@project = Project.new(jira_project, @extra_query)
|
67
64
|
end
|
68
65
|
end
|
69
66
|
end
|
data/lib/story_branch/main.rb
CHANGED
@@ -17,14 +17,9 @@ module StoryBranch
|
|
17
17
|
attr_accessor :tracker
|
18
18
|
|
19
19
|
def initialize
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
# Read local config and decide what Utility to use
|
24
|
-
# (e.g. PivotalUtils, GithubUtils, ...)
|
25
|
-
@local_config = ConfigManager.init_config('.')
|
26
|
-
@global_config = ConfigManager.init_config(Dir.home)
|
27
|
-
initialize_tracker
|
20
|
+
@config = ConfigManager.new
|
21
|
+
abort(@config.errors.join("\n")) unless @config.valid?
|
22
|
+
@tracker = initialize_tracker
|
28
23
|
abort('Invalid tracker configuration setting.') unless @tracker.valid?
|
29
24
|
end
|
30
25
|
|
@@ -75,11 +70,10 @@ module StoryBranch
|
|
75
70
|
private
|
76
71
|
|
77
72
|
def require_pivotal
|
78
|
-
if @tracker.
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
true
|
73
|
+
return true if @tracker.class.name.match?('Pivotal')
|
74
|
+
|
75
|
+
prompt.say 'The configured tracker does not support this feature'
|
76
|
+
false
|
83
77
|
end
|
84
78
|
|
85
79
|
def current_story
|
@@ -159,29 +153,8 @@ module StoryBranch
|
|
159
153
|
@prompt ||= TTY::Prompt.new(interrupt: :exit)
|
160
154
|
end
|
161
155
|
|
162
|
-
def finish_tag
|
163
|
-
return @finish_tag if @finish_tag
|
164
|
-
|
165
|
-
fallback = @global_config.fetch(project_id,
|
166
|
-
:finish_tag,
|
167
|
-
default: 'Finishes')
|
168
|
-
@finish_tag = @local_config.fetch(:finish_tag, default: fallback)
|
169
|
-
@finish_tag
|
170
|
-
end
|
171
|
-
|
172
|
-
def issue_placement
|
173
|
-
return @issue_placement if @issue_placement
|
174
|
-
|
175
|
-
fallback = @global_config.fetch(project_id,
|
176
|
-
:issue_placement,
|
177
|
-
default: 'End')
|
178
|
-
@issue_placement = @local_config.fetch(:issue_placement,
|
179
|
-
default: fallback)
|
180
|
-
@issue_placement
|
181
|
-
end
|
182
|
-
|
183
156
|
def build_finish_message
|
184
|
-
message_tag = [finish_tag, "##{current_story.id}"].join(' ').strip
|
157
|
+
message_tag = [@config.finish_tag, "##{current_story.id}"].join(' ').strip
|
185
158
|
"[#{message_tag}] #{current_story.title}"
|
186
159
|
end
|
187
160
|
|
@@ -196,10 +169,11 @@ module StoryBranch
|
|
196
169
|
branch_name = valid_branch_name(story)
|
197
170
|
return unless branch_name
|
198
171
|
|
199
|
-
# rubocop:disable
|
172
|
+
# rubocop:disable Metrics/LineLength
|
200
173
|
feature_branch_name_with_story_id = build_branch_name(branch_name, story.id)
|
174
|
+
|
201
175
|
prompt.say("Creating: #{feature_branch_name_with_story_id} with #{current_branch} as parent")
|
202
|
-
# rubocop:enable
|
176
|
+
# rubocop:enable Metrics/LineLength
|
203
177
|
GitWrapper.create_branch feature_branch_name_with_story_id
|
204
178
|
end
|
205
179
|
|
@@ -233,65 +207,30 @@ module StoryBranch
|
|
233
207
|
# rubocop:enable Metrics/MethodLength
|
234
208
|
|
235
209
|
def build_branch_name(branch_name, story_id)
|
236
|
-
if issue_placement.casecmp('beginning').zero?
|
210
|
+
if @config.issue_placement.casecmp('beginning').zero?
|
237
211
|
"#{story_id}-#{branch_name}"
|
238
212
|
else
|
239
213
|
"#{branch_name}-#{story_id}"
|
240
214
|
end
|
241
215
|
end
|
242
216
|
|
243
|
-
def project_id
|
244
|
-
return @project_id if @project_id
|
245
|
-
|
246
|
-
project_ids = @local_config.fetch(:project_id)
|
247
|
-
@project_id = choose_project_id(project_ids)
|
248
|
-
end
|
249
|
-
|
250
|
-
def choose_project_id(project_ids)
|
251
|
-
return project_ids unless project_ids.is_a? Array
|
252
|
-
return project_ids[0] unless project_ids.length > 1
|
253
|
-
|
254
|
-
prompt.select('Which project you want to fetch from?', project_ids)
|
255
|
-
end
|
256
|
-
|
257
|
-
def api_key
|
258
|
-
@api_key ||= @global_config.fetch(project_id, :api_key)
|
259
|
-
end
|
260
|
-
|
261
|
-
def username
|
262
|
-
@username ||= @global_config.fetch(project_id, :username)
|
263
|
-
end
|
264
|
-
|
265
217
|
def current_branch
|
266
218
|
@current_branch ||= GitWrapper.current_branch
|
267
219
|
end
|
268
220
|
|
269
|
-
# rubocop:disable Metrics/AbcSize
|
270
|
-
# rubocop:disable Metrics/MethodLength
|
271
221
|
def initialize_tracker
|
272
|
-
|
273
|
-
|
274
|
-
|
222
|
+
# TODO: Ideally this would be mapped out somewhere so we don't need to
|
223
|
+
# evaluate anything from the config here
|
224
|
+
tracker_type = @config.tracker_type
|
225
|
+
case tracker_type
|
226
|
+
when 'github'
|
227
|
+
StoryBranch::Github::Tracker.new(@config.tracker_params)
|
228
|
+
when 'pivotal-tracker'
|
229
|
+
StoryBranch::Pivotal::Tracker.new(@config.tracker_params)
|
230
|
+
when 'jira'
|
231
|
+
StoryBranch::Jira::Tracker.new(@config.tracker_params)
|
275
232
|
end
|
276
|
-
tracker_type = @local_config.fetch(:tracker, default: 'pivotal-tracker')
|
277
|
-
@tracker = case tracker_type
|
278
|
-
when 'github'
|
279
|
-
StoryBranch::Github::Tracker.new(project_id, api_key)
|
280
|
-
when 'pivotal-tracker'
|
281
|
-
StoryBranch::Pivotal::Tracker.new(project_id, api_key)
|
282
|
-
when 'jira'
|
283
|
-
tracker_domain, project_key = project_id.split('|')
|
284
|
-
options = {
|
285
|
-
tracker_domain: tracker_domain,
|
286
|
-
project_id: project_key,
|
287
|
-
api_key: api_key,
|
288
|
-
username: username
|
289
|
-
}
|
290
|
-
StoryBranch::Jira::Tracker.new(options)
|
291
|
-
end
|
292
233
|
end
|
293
|
-
# rubocop:enable Metrics/AbcSize
|
294
|
-
# rubocop:enable Metrics/MethodLength
|
295
234
|
end
|
296
235
|
# rubocop:enable Metrics/ClassLength
|
297
236
|
end
|
@@ -1,22 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'blanket'
|
4
|
+
require 'story_branch/tracker_base'
|
4
5
|
require_relative './project'
|
5
6
|
|
6
7
|
module StoryBranch
|
7
8
|
module Pivotal
|
8
9
|
# Utility class for integration with PivotalTracker. It relies on Blanket
|
9
10
|
# wrapper to communicate with pivotal tracker's api.
|
10
|
-
class Tracker
|
11
|
+
class Tracker < StoryBranch::TrackerBase
|
11
12
|
API_URL = 'https://www.pivotaltracker.com/services/v5/'
|
12
|
-
TYPE = 'pivotal'
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
def initialize(project_id, api_key)
|
14
|
+
def initialize(project_id:, api_key:, **)
|
17
15
|
@project_id = project_id
|
18
16
|
@api_key = api_key
|
19
|
-
@type = TYPE
|
20
17
|
end
|
21
18
|
|
22
19
|
def valid?
|
@@ -41,9 +38,7 @@ module StoryBranch
|
|
41
38
|
|
42
39
|
private
|
43
40
|
|
44
|
-
def
|
45
|
-
raise 'API key must be specified' unless @api_key
|
46
|
-
|
41
|
+
def configure_api
|
47
42
|
Blanket.wrap API_URL, headers: { 'X-TrackerToken' => @api_key }
|
48
43
|
end
|
49
44
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
module StoryBranch
|
6
|
+
# Base story branch tracker class that will define the expected interface
|
7
|
+
class TrackerBase
|
8
|
+
def valid?
|
9
|
+
raise 'valid? > must be implemented in the custom tracker'
|
10
|
+
end
|
11
|
+
|
12
|
+
# TODO: This should probably be renamed to something more meaningful
|
13
|
+
# in the sense that it should be workable stories/issues
|
14
|
+
# which depend on the tracker's workflow. PivotalTracker they need to
|
15
|
+
# be started and estimated, while for Github they just need to be open
|
16
|
+
def stories
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_story_by_id(_story_id)
|
21
|
+
[]
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def api
|
27
|
+
raise 'API key must be specified' unless @api_key
|
28
|
+
|
29
|
+
@api ||= configure_api
|
30
|
+
end
|
31
|
+
|
32
|
+
def project
|
33
|
+
return @project if @project
|
34
|
+
raise 'project key must be set' unless @project_id
|
35
|
+
|
36
|
+
raise 'project > must be implemented in the custom tracker'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/story_branch/version.rb
CHANGED
data/story_branch.gemspec
CHANGED
@@ -61,8 +61,9 @@ Gem::Specification.new do |spec|
|
|
61
61
|
spec.add_runtime_dependency 'tty-config', '~> 0.2.0'
|
62
62
|
spec.add_runtime_dependency 'tty-pager', '~> 0.12'
|
63
63
|
spec.add_runtime_dependency 'tty-prompt', '~> 0.18'
|
64
|
+
spec.add_runtime_dependency 'xdg', '~> 3.0'
|
64
65
|
|
65
|
-
spec.add_development_dependency 'bundler', '~>
|
66
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
66
67
|
spec.add_development_dependency 'fakefs', '~> 0.14'
|
67
68
|
spec.add_development_dependency 'git', '~> 1.5'
|
68
69
|
spec.add_development_dependency 'ostruct', '~> 0.1'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: story_branch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0.alpha
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rui Baltazar
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: exe
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2020-01-25 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: blanket_wrapper
|
@@ -126,20 +126,34 @@ dependencies:
|
|
126
126
|
- - "~>"
|
127
127
|
- !ruby/object:Gem::Version
|
128
128
|
version: '0.18'
|
129
|
+
- !ruby/object:Gem::Dependency
|
130
|
+
name: xdg
|
131
|
+
requirement: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - "~>"
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '3.0'
|
136
|
+
type: :runtime
|
137
|
+
prerelease: false
|
138
|
+
version_requirements: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - "~>"
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '3.0'
|
129
143
|
- !ruby/object:Gem::Dependency
|
130
144
|
name: bundler
|
131
145
|
requirement: !ruby/object:Gem::Requirement
|
132
146
|
requirements:
|
133
147
|
- - "~>"
|
134
148
|
- !ruby/object:Gem::Version
|
135
|
-
version: '
|
149
|
+
version: '2.0'
|
136
150
|
type: :development
|
137
151
|
prerelease: false
|
138
152
|
version_requirements: !ruby/object:Gem::Requirement
|
139
153
|
requirements:
|
140
154
|
- - "~>"
|
141
155
|
- !ruby/object:Gem::Version
|
142
|
-
version: '
|
156
|
+
version: '2.0'
|
143
157
|
- !ruby/object:Gem::Dependency
|
144
158
|
name: fakefs
|
145
159
|
requirement: !ruby/object:Gem::Requirement
|
@@ -274,6 +288,7 @@ files:
|
|
274
288
|
- README.md
|
275
289
|
- Rakefile
|
276
290
|
- Roadmap.md
|
291
|
+
- docs/index.md
|
277
292
|
- exe/git-finish
|
278
293
|
- exe/git-start
|
279
294
|
- exe/git-story
|
@@ -286,7 +301,6 @@ files:
|
|
286
301
|
- lib/story_branch/commands/add.rb
|
287
302
|
- lib/story_branch/commands/create.rb
|
288
303
|
- lib/story_branch/commands/finish.rb
|
289
|
-
- lib/story_branch/commands/migrate.rb
|
290
304
|
- lib/story_branch/commands/start.rb
|
291
305
|
- lib/story_branch/commands/unstart.rb
|
292
306
|
- lib/story_branch/config_manager.rb
|
@@ -313,6 +327,7 @@ files:
|
|
313
327
|
- lib/story_branch/templates/migrate/.gitkeep
|
314
328
|
- lib/story_branch/templates/start/.gitkeep
|
315
329
|
- lib/story_branch/templates/unstart/.gitkeep
|
330
|
+
- lib/story_branch/tracker_base.rb
|
316
331
|
- lib/story_branch/version.rb
|
317
332
|
- story_branch.gemspec
|
318
333
|
homepage: https://github.com/story-branch/story_branch
|
@@ -337,11 +352,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
337
352
|
version: '2.7'
|
338
353
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
339
354
|
requirements:
|
340
|
-
- - "
|
355
|
+
- - ">"
|
341
356
|
- !ruby/object:Gem::Version
|
342
|
-
version:
|
357
|
+
version: 1.3.1
|
343
358
|
requirements: []
|
344
|
-
rubygems_version: 3.0.
|
359
|
+
rubygems_version: 3.0.3
|
345
360
|
signing_key:
|
346
361
|
specification_version: 4
|
347
362
|
summary: Create git branches based on your preferred tracker tickets
|
@@ -1,103 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../config_manager'
|
4
|
-
require_relative '../command'
|
5
|
-
require 'yaml'
|
6
|
-
require 'fileutils'
|
7
|
-
|
8
|
-
module StoryBranch
|
9
|
-
module Commands
|
10
|
-
# Migrate command is intended to make the migration from old version
|
11
|
-
# of story branch to the latest one easier.
|
12
|
-
class Migrate < StoryBranch::Command
|
13
|
-
GLOBAL_CONFIG_FILE = "#{Dir.home}/.story_branch"
|
14
|
-
LOCAL_CONFIG_FILE = '.story_branch'
|
15
|
-
OLD_CONFIG_FILES = [LOCAL_CONFIG_FILE, GLOBAL_CONFIG_FILE].freeze
|
16
|
-
|
17
|
-
def initialize(options)
|
18
|
-
@options = options
|
19
|
-
@config = ConfigManager.init_config(Dir.home)
|
20
|
-
end
|
21
|
-
|
22
|
-
def execute(_input: $stdin, output: $stdout)
|
23
|
-
if missing_old_config?
|
24
|
-
error_migrating(output, old_config_file_not_found)
|
25
|
-
return
|
26
|
-
end
|
27
|
-
@config.set(project_id, :api_key, value: api_key)
|
28
|
-
@config.write(force: true)
|
29
|
-
create_local_config
|
30
|
-
clean_old_config_files
|
31
|
-
output.puts 'Migration complete'
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def project_id
|
37
|
-
return @project_id if @project_id
|
38
|
-
|
39
|
-
@project_id = old_config_value('project', 'PIVOTAL_PROJECT_ID')
|
40
|
-
@project_id
|
41
|
-
end
|
42
|
-
|
43
|
-
def api_key
|
44
|
-
return @api_key if @api_key
|
45
|
-
|
46
|
-
@api_key = old_config_value('api', 'PIVOTAL_API_KEY')
|
47
|
-
@api_key
|
48
|
-
end
|
49
|
-
|
50
|
-
def error_migrating(output, error_message)
|
51
|
-
output.puts error_message
|
52
|
-
end
|
53
|
-
|
54
|
-
def missing_old_config?
|
55
|
-
OLD_CONFIG_FILES.each { |file| return false if File.exist?(file) }
|
56
|
-
return false if env_set?
|
57
|
-
|
58
|
-
true
|
59
|
-
end
|
60
|
-
|
61
|
-
def env_set?
|
62
|
-
ENV['PIVOTAL_API_KEY'].length.positive? ||
|
63
|
-
ENV['PIVOTAL_PROJECT_ID'].length.positive?
|
64
|
-
end
|
65
|
-
|
66
|
-
def old_config_value(key, env)
|
67
|
-
OLD_CONFIG_FILES.each do |config_file|
|
68
|
-
if File.exist? config_file
|
69
|
-
old_config = YAML.load_file config_file
|
70
|
-
return old_config[key].to_s if old_config && old_config[key]
|
71
|
-
end
|
72
|
-
end
|
73
|
-
ENV[env]
|
74
|
-
end
|
75
|
-
|
76
|
-
def create_local_config
|
77
|
-
local_config = ConfigManager.init_config('.')
|
78
|
-
local_config.set(:project_id, value: project_id)
|
79
|
-
local_config.write
|
80
|
-
end
|
81
|
-
|
82
|
-
def clean_old_config_files
|
83
|
-
[GLOBAL_CONFIG_FILE, LOCAL_CONFIG_FILE].each do |file|
|
84
|
-
FileUtils.rm file if File.exist? file
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def old_config_file_not_found
|
89
|
-
<<~MESSAGE
|
90
|
-
Old configuration not found.
|
91
|
-
Trying to start from scratch? Use story_branch add
|
92
|
-
MESSAGE
|
93
|
-
end
|
94
|
-
|
95
|
-
def cant_migrate_missing_value
|
96
|
-
<<~MESSAGE
|
97
|
-
Old configuration not found. Nothing has been migrated
|
98
|
-
Trying to start from scratch? Use story_branch add
|
99
|
-
MESSAGE
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|