Class: Git::Story::App

Inherits:
Object
  • Object
show all
Extended by:
Utils
Includes:
ComplexConfig::Provider::Shortcuts, Utils, Tins::GO
Defined in:
lib/git/story/app.rb

Defined Under Namespace

Modules: StoryAccessors

Constant Summary collapse

BRANCH_NAME_REGEX =
/\A(?:story|feature)_([a-z0-9-]+)_(\d+)(?:\-[0-9a-f]+)?\z/

Instance Method Summary collapse

Methods included from Utils

ask, capture, sh

Constructor Details

#initialize(argv = ARGV, debug: ENV['DEBUG'].to_i == 1) ⇒ App

Returns a new instance of App.



30
31
32
33
34
# File 'lib/git/story/app.rb', line 30

def initialize(argv = ARGV, debug: ENV['DEBUG'].to_i == 1)
  @argv    = argv
  @command = @argv.shift&.to_sym
  @debug   = debug
end

Instance Method Details

#build_status(branch = current(check: false)) ⇒ Object



89
90
91
92
93
94
95
96
# File 'lib/git/story/app.rb', line 89

def build_status(branch = current(check: false))
  auth_token = complex_config.story.semaphore_auth_token
  project    = complex_config.story.semaphore_project
  url        = "https://semaphoreci.com/api/v1/projects/#{project}/#{branch}/status?auth_token=#{auth_token}"
  Git::Story::SemaphoreResponse.get(url)
rescue => e
  "Getting #{url.inspect} => #{e.class}: #{e}".red
end

#create(story_id = nil) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/git/story/app.rb', line 182

def create(story_id = nil)
  sh 'git fetch'
  name = provide_name(story_id) or
    error "Cannot provide a new story name for story ##{story_id}: #{@reason.inspect}"
  if old_story = stories.find { |s| s.story_id == @story_id }
    error "story ##{@story_id} already exists in #{old_story}".red
  end
  puts "Now creating story #{name.inspect}".green
  sh "git checkout --track -b #{name}"
  sh "git push -u origin #{name}"
  "Story #{name} created.".green
end

#current(check: true) ⇒ Object



61
62
63
64
# File 'lib/git/story/app.rb', line 61

def current(check: true)
  check and check_current
  current_branch
end

#deploy_diff(ref = nil) ⇒ Object



168
169
170
171
172
# File 'lib/git/story/app.rb', line 168

def deploy_diff(ref = nil)
  fetch_tags
  opts = '-u'
  capture("git diff --color #{opts} #{ref} #{deploy_tags.last}")
end

#deploy_logObject



161
162
163
164
165
# File 'lib/git/story/app.rb', line 161

def deploy_log
  fetch_tags
  opts = '--pretty=tformat:"%C(yellow)%h%Creset %C(green)%ci%Creset %s (%Cred%an <%ae>%Creset)"'
  capture("git log #{opts} #{deploy_tags.last}..")
end

#deploy_migrate_diff(ref = nil) ⇒ Object



175
176
177
178
179
# File 'lib/git/story/app.rb', line 175

def deploy_migrate_diff(ref = nil)
  fetch_tags
  opts = '-u'
  capture("git diff --color #{opts} #{deploy_tags.last} #{ref} -- db/migrate")
end

#deploy_status(server = complex_config.story.semaphore_default_server) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/git/story/app.rb', line 99

def deploy_status(server = complex_config.story.semaphore_default_server)
  auth_token = complex_config.story.semaphore_auth_token
  project    = complex_config.story.semaphore_project
  url        = "https://semaphoreci.com/api/v1/projects/#{project}/servers/#{server}?auth_token=#{auth_token}"
  server   = Git::Story::SemaphoreResponse.get(url)
  deploys  = server.deploys
  upcoming = deploys.select(&:pending?)&.last
  current  = deploys.find(&:passed?)
  "    Server: \#{server.server_name&.green}\n    Branch: \#{server.branch_name&.color('#ff5f00')}\n    Semaphore: \#{server.server_url}\n    Strategy: \#{server.strategy}\n    Upcoming: \#{upcoming}\n    Current: \#{current}\n  end\nrescue => e\n  \"Getting \#{url.inspect} => \#{e.class}: \#{e}\".red\n"

#deploy_tagsObject



137
138
139
140
141
142
# File 'lib/git/story/app.rb', line 137

def deploy_tags
  fetch_tags
  capture(
    "git tag | grep ^#{complex_config.story.deploy_tag_prefix} | sort"
  ).lines.map(&:chomp)
end

#deploy_tags_lastObject



150
151
152
# File 'lib/git/story/app.rb', line 150

def deploy_tags_last
  deploy_tags.last
end

#deploysObject



145
146
147
# File 'lib/git/story/app.rb', line 145

def deploys
  deploy_tags.map { |t| format_tag_time(t).green + " #{t.yellow}" }
end

#deploys_lastObject



155
156
157
158
# File 'lib/git/story/app.rb', line 155

def deploys_last
  tag = deploy_tags_last
  format_tag_time(tag).green + " #{tag.yellow}"
end

#helpObject



50
51
52
53
54
55
56
57
58
# File 'lib/git/story/app.rb', line 50

def help
  result = [ 'Available commands are:' ]
  longest = command_annotations.keys.map(&:size).max
  result.concat(
    command_annotations.map { |name, a|
      "#{name.to_s.ljust(longest)} #{a[:doc]}"
    }
  )
end

#list(author = nil, mark_red: current(check: false)) ⇒ Object



120
121
122
123
124
125
# File 'lib/git/story/app.rb', line 120

def list(author = nil, mark_red: current(check: false))
  stories.map { |b|
    next if author && !b..include?(author)
    (bn = b.story_base_name) == mark_red ? bn.red : bn.green
  }.compact
end

#list_details(author = nil, mark_red: current(check: false)) ⇒ Object



128
129
130
131
132
133
134
# File 'lib/git/story/app.rb', line 128

def list_details(author = nil, mark_red: current(check: false))
  stories.sort_by { |b| -b.story_created_at.to_f }.map { |b|
    next if author && !b..include?(author)
    name = (bn = b.story_base_name) == mark_red ? bn.red : bn.green
    "#{name} #{b.story_author} #{b.story_created_at.iso8601.yellow}"
  }.compact
end

#provide_name(story_id = nil) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/git/story/app.rb', line 66

def provide_name(story_id = nil)
  until story_id.present?
    story_id = ask(prompt: 'Story id? ').strip
  end
  story_id = story_id.gsub(/[^0-9]+/, '')
  @story_id = Integer(story_id)
  if stories.any? { |s| s.story_id == @story_id }
    @reason = "story for ##@story_id already created"
    return
  end
  if name = fetch_story_name(@story_id)
    name = normalize_name(
      name,
      max_size: 128 - 'story'.size - @story_id.to_s.size - 2 * ?_.size
    ).full? || name
    [ 'story', name, @story_id ] * ?_
  else
    @reason = "name for ##@story_id could not be fetched from tracker"
    return
  end
end

#runObject



36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/git/story/app.rb', line 36

def run
  Git::Story::Setup.perform
  if command_of(@command)
    puts __send__(@command, *@argv)
  else
    @command and @command = @command.inspect
    @command ||= 'n/a'
    STDERR.puts "Unknown command #{@command}\n\n#{help.join(?\n)}"
    exit 1
  end
rescue Errno::EPIPE
end

#switch(pattern = nil) ⇒ Object



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/git/story/app.rb', line 196

def switch(pattern = nil)
  sh 'git fetch'
  ss = stories.map(&:story_base_name)
  if pattern.present?
    b = apply_pattern(pattern, ss)
    if b.size == 1
      b = b.first
    else
      b = nil
    end
  end
  loop do
    unless b
      b = complete prompt: 'Story <TAB>? '.bright_blue do |pattern|
        apply_pattern(pattern, ss)
      end&.strip
      b.empty? and return
    end
    if branch = ss.find { |f| f == b }
      sh "git checkout #{branch}"
      return "Switched to story: #{branch}".green
    else
      b = nil
    end
  end
rescue Interrupt
end