story_branch 0.6.1 → 0.7.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- 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
|