git-prepare-branch 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2d820e9fda828430f381da9a0173811a060e2c73
4
+ data.tar.gz: 27d972cc3a0993b61e6479a312eebf0f8d628e94
5
+ SHA512:
6
+ metadata.gz: b2ffc9dd90b096e11080164a6f31db67b9fa4f6bcb8023ae69b38d1c7241108857dafc46248163a195480626ab1c7a2c9cb44614e9195c5537e1a929519d7421
7
+ data.tar.gz: 3565a768eae5d3387864727057cdcc3925eace47b57f34f8db568a1729fb58b3da6528f8de2b4e0a0def4ca36adbb0de50eb4cc00c7970a16bf680be3694b61a
@@ -0,0 +1,70 @@
1
+ # git-prepare-branch
2
+
3
+ This tool is for developers who prefer to use interactive rebasing to prepare
4
+ their branches for code review and merging. It provides a wrapper around some
5
+ git commands along with shortcut keys.
6
+
7
+ ## Installation
8
+
9
+ Currently installation is via rubygems
10
+
11
+ ```
12
+ gem install git-prepare-branch
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ With your feature branch checked out and assuming you are merging into master
18
+
19
+ ```
20
+ git prepare-branch
21
+ ```
22
+
23
+ If you are merging into another branch run
24
+
25
+ ```
26
+ git prepare-branch some-other-branch
27
+ ```
28
+
29
+ You will then see a log of all the commits to be merged.
30
+
31
+ Pressing `?` will bring up a list of the available command keys. They array_to_sentence_string
32
+
33
+ ```
34
+ f filter files Filters commits to just those affected files that match the specified filter
35
+
36
+ r begin rebase Start an interactive rebase
37
+
38
+ s show Show a specific commit
39
+
40
+ d sum diff Show the combined diff from one SHA to another (inclusive)
41
+
42
+ v cycle view Cycles through applying different view options to the list of commits
43
+ ```
44
+
45
+ If you pause mid rebase - for example if you have chosen to edit a commit - there are a different set of commands available
46
+
47
+ ```
48
+ a abort rebase Abort the current rebase
49
+
50
+ c continue rebase Continue with the current rebase
51
+ ```
52
+
53
+ If you pause mid rebase and there are conflicts detected, another set of commands are available
54
+
55
+ ```
56
+ a abort rebase Abort the current rebase
57
+
58
+ m show my changes Show the diff of the content in this branch causing the conflict
59
+
60
+ t show other commits Show the commits that may have introduced the conflicting changes
61
+
62
+ o show other diff Show the combined diff of the commits that may have introduced the change
63
+
64
+ d show diff Show the diff of the conflicts
65
+ ```
66
+
67
+ ## What are the actual git commands being run?
68
+
69
+ The entire set of commands are defined in [bin/git-prepare-branch](bin/git-prepare-branch).
70
+ The rest of the code in the application is to allow for the interface and the declarative DSL.
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/git-prepare-branch'
4
+
5
+ LOG_FILE = ENV['LOG']
6
+
7
+ if LOG_FILE
8
+ logger = GitPrepareBranch::Logger.new(
9
+ stream: IO.new(IO.sysopen(LOG_FILE, 'a+'))
10
+ )
11
+ else
12
+ logger = GitPrepareBranch::NullLogger.new
13
+ end
14
+
15
+ onto = ARGV[0] || 'master'
16
+
17
+ VIEWS = [
18
+ 'log --oneline --decorate --reverse ',
19
+ 'log --oneline --decorate --reverse --stat --name-only',
20
+ 'log --oneline --decorate --reverse --stat',
21
+ 'diff --stat',
22
+ 'diff --dirstat'
23
+ ]
24
+
25
+ GitPrepareBranch::App.configure(logger: logger) do
26
+ on :load do
27
+ variable :view, value: VIEWS[0]
28
+ variable :file_filter
29
+ variable :current_branch, capture: 'git rev-parse --abbrev-ref HEAD'
30
+ variable :prefix, capture: 'git rev-parse --show-prefix'
31
+ variable :num_commits, capture: 'git rev-list --count %{onto}..'
32
+ variable :num_files, capture: 'git diff --name-only %{onto}.. | wc -l'
33
+ end
34
+
35
+ on :display do
36
+ variable :mid_rebase?,
37
+ value: ->(context) {
38
+ context.terminal.capture(
39
+ 'if test -d "$(git rev-parse --git-path rebase-merge)" || test -d "$(git rev-parse --git-path rebase-apply)"; then echo 1; fi'
40
+ ).strip == '1'
41
+ }
42
+
43
+ variable :conflicts?,
44
+ value: ->(context) {
45
+ !context.terminal.capture("git status -s | grep -e '^UU'").strip.empty?
46
+ }
47
+ end
48
+
49
+ screen :default do
50
+ heading '❯ %{current_branch} => %{onto} - %{num_commits} commits, %{num_files} files', style: :header
51
+ display 'git %{view} %{onto}.. *%{file_filter}*'
52
+ description "prepare-branch\n\nPrepare a branch for rebasing"
53
+
54
+ command 'f', 'filter files',
55
+ -> (context, inputs) {
56
+ context.variables[:file_filter] = inputs[:file_filter]
57
+ },
58
+ description: 'Filters commits to just those affected files that match the specified filter',
59
+ input: {
60
+ file_filter: {
61
+ prompt: 'Enter a file pattern',
62
+ autocomplete_strategy: :file
63
+ }
64
+ }
65
+
66
+ command 'r', 'begin rebase',
67
+ 'git rebase -i %{onto}',
68
+ description: 'Start an interactive rebase'
69
+
70
+ command 's', 'show',
71
+ 'git show %{sha}',
72
+ input: {
73
+ sha: {
74
+ prompt: 'Enter a sha',
75
+ autocomplete_strategy: :sha
76
+ }
77
+ },
78
+ description: 'Show a specific commit',
79
+ prompt_to_continue: true
80
+
81
+ command 'd', 'sum diff',
82
+ 'git diff -w --find-renames --find-copies --patience %{start_sha}~...%{end_sha}',
83
+ input: {
84
+ start_sha: {
85
+ prompt: 'Enter the starting sha',
86
+ autocomplete_strategy: :sha
87
+ },
88
+ end_sha: {
89
+ prompt: 'Enter the end sha',
90
+ autocomplete_strategy: :sha
91
+ }
92
+ },
93
+ description: 'Show the combined diff from one sha to another (inclusive)',
94
+ prompt_to_continue: true
95
+
96
+ command 'D', 'entire diff',
97
+ 'git diff -w --find-renames --find-copies --patience %{onto}..',
98
+ description: 'Show the entire combined diff as if the branch was squashed into a single commit',
99
+ prompt_to_continue: true
100
+
101
+ command 'v', 'cycle view',
102
+ -> (context, _) {
103
+ context.variables[:view] = VIEWS[(VIEWS.index(context.variables[:view]) + 1) % VIEWS.length]
104
+ },
105
+ description: 'Cycles through applying different view options to the list of commits'
106
+
107
+ command 'V', 'cycle view (reverse)',
108
+ -> (context, _) {
109
+ context.variables[:view] = VIEWS[(VIEWS.index(context.variables[:view]) - 1) % VIEWS.length]
110
+ },
111
+ description: 'Cycles back through applying different view options to the list of commits (reverse of v)'
112
+
113
+ end
114
+
115
+ screen :mid_rebase do
116
+ heading '❯ Rebasing %{current_branch} onto %{onto} (paused)', style: :header_ok
117
+ display 'git show --stat'
118
+ description "prepare-branch - mid rebase"
119
+
120
+ command 'a', 'abort rebase', 'git rebase --abort', description: 'Abort the current rebase'
121
+ command 'c', 'continue rebase', 'git rebase --continue', description: 'Continue with the current rebase'
122
+ end
123
+
124
+ screen :conflicts do
125
+ heading '❯ Conflicts rebasing %{current_branch} onto %{onto}', style: :header_warning
126
+ display 'git status -s'
127
+ description "prepare-branch - conflicts"
128
+
129
+ command 'a', 'abort rebase', 'git rebase --abort', description: 'Abort the current rebase'
130
+
131
+ command 'm', 'show my changes',
132
+ 'git diff --name-only --diff-filter=U --relative=%{prefix} | xargs git show $(< $(git rev-parse --git-path rebase-merge/stopped-sha)) --oneline',
133
+ description: 'Show the diff of the content in this branch causing the conflict',
134
+ prompt_to_continue: true
135
+
136
+ command 't', 'show other commits',
137
+ 'git diff --name-only --relative=%{prefix} --diff-filter=U | xargs git log $(git merge-base HEAD $(< $(git rev-parse --git-path rebase-merge/stopped-sha)))... --oneline',
138
+ description: 'Show the commits that may have introduced the conflicting changes',
139
+ prompt_to_continue: true
140
+
141
+ command 'o', 'show other diff',
142
+ 'git diff --name-only --relative=%{prefix} --diff-filter=U | xargs git diff $(git merge-base HEAD $(< $(git rev-parse --git-path rebase-merge/stopped-sha)))...',
143
+ description: 'Show the combined diff of the commits that may have introduced the change',
144
+ prompt_to_continue: true
145
+
146
+ command 'd', 'show diff',
147
+ 'git diff',
148
+ description: 'Show the diff of the conflicts',
149
+ prompt_to_continue: true
150
+ end
151
+
152
+ routing -> (context) {
153
+ if context.variables.mid_rebase?
154
+ return :conflicts if context.variables.conflicts?
155
+ return :mid_rebase
156
+ end
157
+ :default
158
+ }
159
+ end.start(
160
+ onto: { value: onto }
161
+ )
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'git-prepare-branch/app'
4
+ require_relative 'git-prepare-branch/command'
5
+ require_relative 'git-prepare-branch/configurator'
6
+ require_relative 'git-prepare-branch/context'
7
+ require_relative 'git-prepare-branch/logger'
8
+ require_relative 'git-prepare-branch/null_logger'
9
+ require_relative 'git-prepare-branch/screen'
10
+ require_relative 'git-prepare-branch/styles'
11
+ require_relative 'git-prepare-branch/terminal'
12
+ require_relative 'git-prepare-branch/variable'
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ostruct'
4
+
5
+ require_relative 'logger'
6
+ require_relative 'configurator'
7
+ require_relative 'context'
8
+ require_relative 'terminal'
9
+ require_relative 'variable'
10
+
11
+ module GitPrepareBranch
12
+ class App
13
+ attr_reader :logger
14
+
15
+ attr_accessor :title, :router
16
+
17
+ def initialize(logger: nil)
18
+ @logger = logger || Logger.new
19
+ end
20
+
21
+ def add_event_handler(event, &block)
22
+ event_handlers[event] ||= []
23
+ event_handlers[event] << block
24
+ end
25
+
26
+ def add_screen screen
27
+ screen.context = context
28
+ screens[screen.name] = screen
29
+ end
30
+
31
+ def add_variable name, capture: nil, value: nil
32
+ context.variables[name] = Variable.new(name, context: context, capture: capture, value: value).value
33
+ end
34
+
35
+ def configure(&block)
36
+ Configurator.new(self).apply(&block)
37
+ self
38
+ end
39
+
40
+ def context
41
+ @context ||= Context.new(
42
+ terminal: terminal,
43
+ variables: {}
44
+ )
45
+ end
46
+
47
+ def current_screen
48
+ screens[current_screen_name]
49
+ end
50
+
51
+ def current_screen_name
52
+ router.call(context)
53
+ end
54
+
55
+ def screens
56
+ @screens ||= {}
57
+ end
58
+
59
+ def start(variables = [])
60
+ variables.each { |name, args| add_variable(name, args) }
61
+ trigger :load
62
+ while true do
63
+ begin
64
+ terminal.clear
65
+ trigger :display
66
+ terminal.write_line format(current_screen.heading, context.variables.to_h), current_screen.heading_style
67
+ terminal.call current_screen.display, context.variables.to_h
68
+ terminal.say 'Press a command key or ? for help', :hint
69
+ begin
70
+ result = terminal.wait_for_keypress
71
+ current_screen.handle_keypress result, context
72
+ rescue Interrupt
73
+ end
74
+ rescue Interrupt
75
+ exit
76
+ end
77
+ end
78
+ end
79
+
80
+ def terminal
81
+ @terminal ||= Terminal.new(logger: logger)
82
+ end
83
+
84
+ def trigger event
85
+ return unless event_handlers[event]
86
+
87
+ event_handlers[event].each do |block|
88
+ block.call(context)
89
+ end
90
+ end
91
+
92
+ class << self
93
+ def configure(*options, &block)
94
+ self.new(*options).configure(&block)
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ def event_handlers
101
+ @event_handlers ||= {}
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GitPrepareBranch
4
+ class Command
5
+ attr_reader :key, :name, :command, :options
6
+
7
+ def initialize(key, name, command, options={})
8
+ @key = key
9
+ @name = name
10
+ @command = command
11
+ @options = options
12
+ end
13
+
14
+ def call(context)
15
+ inputs = capture_inputs(context)
16
+ run_proc(context, inputs) if command.is_a?(Proc)
17
+ run_as_shell_command(context, inputs) if command.is_a?(String)
18
+ context.terminal.prompt_to_continue if options[:prompt_to_continue]
19
+ end
20
+
21
+ def description
22
+ options[:description]
23
+ end
24
+
25
+ private
26
+
27
+ def capture_inputs(context)
28
+ return {} unless options[:input]
29
+ options[:input].each_with_object({}) do |(key, value), object|
30
+ object[key] = context.terminal.ask value[:prompt], autocomplete_strategy: [value[:autocomplete_strategy], context.variables]
31
+ end
32
+ end
33
+
34
+ def run_as_shell_command(context, inputs)
35
+ context.terminal.call format(
36
+ command,
37
+ context.variables.to_h.merge(inputs)
38
+ )
39
+ end
40
+
41
+ def run_proc(context, inputs)
42
+ command.call(context, inputs)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,6 @@
1
+ module GitPrepareBranch
2
+ class CommandKeys
3
+ CTRL_C = "\u0003"
4
+ CTRL_D = "\u0004"
5
+ end
6
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'screen'
4
+
5
+ module GitPrepareBranch
6
+ class Configurator
7
+ attr_reader :app
8
+
9
+ def initialize(app)
10
+ @app = app
11
+ end
12
+
13
+ def apply(&block)
14
+ instance_exec(&block)
15
+ end
16
+
17
+ def on(event, &block)
18
+ app.add_event_handler event, &block
19
+ end
20
+
21
+ def routing(routes)
22
+ @app.router = routes
23
+ end
24
+
25
+ def screen(name, &block)
26
+ app.add_screen ScreenDSL.new(Screen.new(name)).apply(&block).screen
27
+ end
28
+
29
+ def title(value)
30
+ app.title = value
31
+ end
32
+
33
+ def variable(name, capture: nil, value: nil)
34
+ app.add_variable name, capture: capture, value: value
35
+ end
36
+
37
+ class ScreenDSL
38
+ attr_reader :screen
39
+
40
+ def initialize(screen)
41
+ @screen = screen
42
+ end
43
+
44
+ def apply(&block)
45
+ self.tap do |s|
46
+ instance_exec(&block)
47
+ end
48
+ end
49
+
50
+ def command(*args)
51
+ screen.add_command(*args)
52
+ end
53
+
54
+ def description(value)
55
+ screen.description = value
56
+ end
57
+
58
+ def display(command)
59
+ screen.display = command
60
+ end
61
+
62
+ def heading(message, options={})
63
+ screen.heading = message
64
+ screen.heading_style = options[:style]
65
+ end
66
+
67
+ def title(value)
68
+ screen.title = value
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GitPrepareBranch
4
+ class Context
5
+ attr_reader :terminal, :variables
6
+
7
+ def initialize(terminal:, variables:)
8
+ @terminal = terminal
9
+ @variables = OpenStruct.new(variables)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ module GitPrepareBranch
2
+ class Logger
3
+ def initialize(stream: $stdout)
4
+ @stream = stream
5
+ end
6
+
7
+ def log message
8
+ stream << format_message(message)
9
+ stream.flush
10
+ end
11
+
12
+ private
13
+
14
+ attr_reader :stream
15
+
16
+ def format_message(message)
17
+ "#{Time.now}: #{message}\n"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ module GitPrepareBranch
2
+ class NullLogger
3
+ def initialize(stream:nil); end
4
+ def log(message); end
5
+ end
6
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'command'
4
+ require_relative 'command_keys'
5
+
6
+ module GitPrepareBranch
7
+ class Screen
8
+ attr_reader :name, :context
9
+ attr_accessor :context, :title, :heading, :heading_style, :description, :display
10
+
11
+ def initialize(name)
12
+ @name = name
13
+ end
14
+
15
+ def add_command(key, name, command, options={})
16
+ commands[key] = Command.new(key, name, command, options)
17
+ end
18
+
19
+ def commands
20
+ @commands ||= {}
21
+ end
22
+
23
+ def handle_keypress key, context
24
+ help if ['h', '?'].include?(key)
25
+ exit if ['q', CommandKeys::CTRL_C, CommandKeys::CTRL_D].include?(key)
26
+ return unless commands.keys.include?(key)
27
+ commands[key].call(context)
28
+ end
29
+
30
+ def help
31
+ terminal.clear
32
+ terminal.say "DESCRIPTION"
33
+ terminal.hr
34
+ terminal.say "#{description}\n\n"
35
+ terminal.say "COMMANDS"
36
+ terminal.hr
37
+ commands.each_with_object('') do |(key, command), result|
38
+ terminal.say "#{key} #{command.name.ljust(longest_command_name_length)} #{command.description}"
39
+ terminal.say "\n"
40
+ end
41
+ terminal.prompt_to_continue
42
+ end
43
+
44
+ def longest_command_name_length
45
+ @longest_command_name_length ||= commands.collect{|(_, c)| c.name.length}.max
46
+ end
47
+
48
+ private
49
+
50
+ def terminal
51
+ context.terminal
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,48 @@
1
+ require 'rainbow'
2
+
3
+ module GitPrepareBranch
4
+ class Styles
5
+ def initialize(styler: nil)
6
+ @styler = styler || Rainbow.global.method(:wrap)
7
+ end
8
+
9
+ def apply(text, style = :default)
10
+ return text if style == :default
11
+ send(style, text)
12
+ end
13
+
14
+ def bold(text)
15
+ style(text).bright
16
+ end
17
+
18
+ def footer(text)
19
+ style(text).color(:dimgray)
20
+ end
21
+
22
+ def header(text)
23
+ style(text).color(:white).bg(:darkslateblue)
24
+ end
25
+
26
+ def header_ok(text)
27
+ style(text).color(:white).bg(:darkgreen)
28
+ end
29
+
30
+ def header_warning(text)
31
+ style(text).color(:white).bg(:red)
32
+ end
33
+
34
+ def hint(text)
35
+ style(text).color(:dimgray)
36
+ end
37
+
38
+ alias hr footer
39
+
40
+ private
41
+
42
+ attr_reader :styler
43
+
44
+ def style(text)
45
+ styler.call(text)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,132 @@
1
+ require 'readline'
2
+ require 'io/console'
3
+
4
+ require_relative 'styles'
5
+
6
+ module GitPrepareBranch
7
+ class Terminal
8
+ CLEAR = 'clear'
9
+ DEFAULT_PROMPT = ' ❯ '
10
+ DEFAULT_WIDTH = 20
11
+ HR_CHARACTER = '─'
12
+ BLANK_CHARACTER = ' '
13
+ NUM_BLANK_LINES_BEFORE_PROMPT = 3
14
+
15
+ AUTOCOMPLETE_STRATEGIES = {
16
+ default: -> (_, _) {},
17
+ sha: -> (variables, s) {
18
+ `git rev-list #{variables[:onto]}...`
19
+ .split(/\n/)
20
+ .grep(/^#{s}/)
21
+ },
22
+ file: ->(variables, s) {
23
+ `git diff --name-only --relative=#{variables[:prefix]} #{variables[:onto]}...`
24
+ .split(/\n/)
25
+ .grep(/#{s}/)
26
+ }
27
+ }
28
+
29
+ def initialize(out: $stdout, err: $stderr, prompt: DEFAULT_PROMPT, logger: nil, styles: nil)
30
+ @out = out
31
+ @err = err
32
+ @prompt = prompt
33
+ @logger = logger || Logger.new
34
+ @styles = styles || Styles.new
35
+ end
36
+
37
+ def ask(question, autocomplete_strategy: :default)
38
+ set_autocomplete_strategy autocomplete_strategy
39
+ Readline.readline("#{question}#{prompt}", true).chomp.strip
40
+ end
41
+
42
+ def blank_lines(quantity = 1)
43
+ quantity.times { out.puts }
44
+ end
45
+
46
+ def call(command, values = {})
47
+ command = normalise_command(command, values)
48
+ logger.log "CMD: #{command}"
49
+ result = system command, out: out, err: err
50
+ logger.log "OUT: #{out}"
51
+ logger.log "ERR: #{err}"
52
+ result
53
+ end
54
+
55
+ def capture(command, values = {})
56
+ command = normalise_command(command, values)
57
+ logger.log "CAP: #{command}"
58
+ result = `#{command}`.chomp.strip
59
+ logger.log "OUT: #{result}"
60
+ result
61
+ end
62
+
63
+ def clear
64
+ call CLEAR
65
+ end
66
+
67
+ def enable_raw
68
+ system("stty raw -echo")
69
+ end
70
+
71
+ def hr
72
+ out.puts styles.hr(HR_CHARACTER * width)
73
+ end
74
+
75
+ def prompt_to_continue
76
+ blank_lines NUM_BLANK_LINES_BEFORE_PROMPT
77
+ hr
78
+ say styles.footer('Press any key to continue')
79
+ wait_for_keypress {}
80
+ end
81
+
82
+ def reset_raw
83
+ system("stty -raw echo")
84
+ end
85
+
86
+ def say(output, style = :default)
87
+ puts styles.apply(output, style)
88
+ end
89
+
90
+ def wait_for_keypress
91
+ while true do
92
+ begin
93
+ enable_raw
94
+ char = STDIN.getc
95
+ return char
96
+ ensure
97
+ reset_raw
98
+ end
99
+ end
100
+ end
101
+
102
+ def write_line(output, style = :default)
103
+ puts styles.apply(make_full_width(output), style)
104
+ end
105
+
106
+ private
107
+
108
+ attr_reader :out, :err, :prompt, :logger, :styles
109
+
110
+ def normalise_command(command, values = {})
111
+ format(command, values)
112
+ end
113
+
114
+ def set_autocomplete_strategy strategy
115
+ Readline.completion_append_character = " "
116
+ strategy = Array(strategy)
117
+ Readline.completion_proc = AUTOCOMPLETE_STRATEGIES[strategy[0]].curry.call(strategy[1])
118
+ end
119
+
120
+ def width
121
+ begin
122
+ IO.console.winsize[1]
123
+ rescue NotImplementedError
124
+ DEFAULT_WIDTH
125
+ end
126
+ end
127
+
128
+ def make_full_width(text)
129
+ text + (BLANK_CHARACTER * [width - text.length, 0].max)
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GitPrepareBranch
4
+ class Variable
5
+ attr_reader :name, :context, :value, :capture
6
+
7
+ def initialize(name, context:, value: nil, capture: nil)
8
+ @name = name
9
+ @context = context
10
+ @capture = capture
11
+ @value = calculate_value(value)
12
+ end
13
+
14
+ private
15
+
16
+ def calculate_value(value)
17
+ return context.terminal.capture(capture_with_variables_injected) unless capture.nil?
18
+ return value.call(context) if value.kind_of? Proc
19
+ value
20
+ end
21
+
22
+ def capture_with_variables_injected
23
+ format(capture, context.variables.to_h)
24
+ end
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git-prepare-branch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Phillips
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-04-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rainbow
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry-byebug
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest-reporters
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.2'
55
+ description: Command to assist in preparing Git branches for review
56
+ email: adam@29ways.co.uk
57
+ executables:
58
+ - git-prepare-branch
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - README.md
63
+ - bin/git-prepare-branch
64
+ - lib/git-prepare-branch.rb
65
+ - lib/git-prepare-branch/app.rb
66
+ - lib/git-prepare-branch/command.rb
67
+ - lib/git-prepare-branch/command_keys.rb
68
+ - lib/git-prepare-branch/configurator.rb
69
+ - lib/git-prepare-branch/context.rb
70
+ - lib/git-prepare-branch/logger.rb
71
+ - lib/git-prepare-branch/null_logger.rb
72
+ - lib/git-prepare-branch/screen.rb
73
+ - lib/git-prepare-branch/styles.rb
74
+ - lib/git-prepare-branch/terminal.rb
75
+ - lib/git-prepare-branch/variable.rb
76
+ homepage: https://github.com/adamphillips/git-prepare-branch
77
+ licenses:
78
+ - MIT
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.6.13
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Command to assist in preparing Git branches for review
100
+ test_files: []