Class: CookbookRelease::GitUtilities

Inherits:
Object
  • Object
show all
Defined in:
lib/cookbook-release/git-utilities.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ GitUtilities

Returns a new instance of GitUtilities.



14
15
16
17
18
19
20
21
22
# File 'lib/cookbook-release/git-utilities.rb', line 14

def initialize(options={})
  @tag_prefix = options[:tag_prefix] || ''
  cwd = options[:cwd] || Dir.pwd
  @sub_dir = options[:sub_dir] # if nil takes the cwd
  @shellout_opts = {
    cwd: cwd
  }
  @g = Git.open(cwd)
end

Instance Attribute Details

#no_promptObject

Returns the value of attribute no_prompt.



11
12
13
# File 'lib/cookbook-release/git-utilities.rb', line 11

def no_prompt
  @no_prompt
end

#sub_dirObject (readonly)

Returns the value of attribute sub_dir.



12
13
14
# File 'lib/cookbook-release/git-utilities.rb', line 12

def sub_dir
  @sub_dir
end

Class Method Details

.find_root(dir = Dir.pwd) ⇒ Object



28
29
30
31
32
33
34
35
# File 'lib/cookbook-release/git-utilities.rb', line 28

def self.find_root(dir = Dir.pwd)
  # Do not consider given dir as part of the git repo if not in git hierarchy or dir is not tracked
  return if ::Mixlib::ShellOut.new('git ls-files --error-unmatch .', cwd: dir).run_command.error?

  cmd = Mixlib::ShellOut.new("git rev-parse --show-toplevel", cwd: dir)
  cmd.run_command
  cmd.error? ? nil : cmd.stdout.chomp
end

.git?(dir) ⇒ Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/cookbook-release/git-utilities.rb', line 24

def self.git?(dir)
  File.directory?(::File.join(dir, '.git'))
end

Instance Method Details

#_compute_last_releaseObject



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/cookbook-release/git-utilities.rb', line 54

def _compute_last_release
  tag = Mixlib::ShellOut.new([
    'git describe',
    "--abbrev=0",
    "--tags",
    "--match \"#{@tag_prefix}[0-9]*\.[0-9]*\.[0-9]*\""
  ].join(" "), @shellout_opts)
  tag.run_command
  rel = tag.stdout.sub(/^#{@tag_prefix}/, '').chomp
  rel.empty? ? nil : rel
end

#choose_remoteObject



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/cookbook-release/git-utilities.rb', line 101

def choose_remote
  cmd = Mixlib::ShellOut.new("git remote", @shellout_opts)
  cmd.run_command
  cmd.error!
  remotes = cmd.stdout.split("\n")
  if remotes.size == 1 || @no_prompt
    puts "Choosing remote #{remotes.first}" if @no_prompt
    remotes.first
  else
    choose(*remotes)
  end
end

#clean_index!Object



50
51
52
# File 'lib/cookbook-release/git-utilities.rb', line 50

def clean_index!
  raise "All changes must be committed!" unless clean_index?
end

#clean_index?Boolean

Returns:

  • (Boolean)


42
43
44
45
46
47
48
# File 'lib/cookbook-release/git-utilities.rb', line 42

def clean_index?
  clean_index = Mixlib::ShellOut.new("git diff --exit-code", @shellout_opts)
  clean_index.run_command
  clean_staged = Mixlib::ShellOut.new("git diff --exit-code --cached", @shellout_opts)
  clean_staged.run_command
  !clean_index.error? && !clean_staged.error?
end

#compute_changelog(since, short_sha = true) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/cookbook-release/git-utilities.rb', line 79

def compute_changelog(since, short_sha = true)
  ref = "#{@tag_prefix}#{since}"
  @g.log(500).object(@sub_dir).between(ref, 'HEAD').execute.map do |commit|
    message = commit.message.lines.map(&:chomp).compact.delete_if(&:empty?)
    Commit.new(
      author: commit.author.name,
      email: commit.author.email,
      subject: message.delete_at(0),
      hash: short_sha ? commit.sha[0,7] : commit.sha,
      body: message.empty? ? nil : message.join("\n"),
      is_merge_commit: commit.parents.length > 1,
      nodes_only: @g.diff(commit.sha, "#{commit.sha}~1").name_status.reject do |path, change_type|
        path.include?('nodes/') && ['A', 'D'].include?(change_type) # basic node additions or deletions only
      end.count.zero?
    )
  end.reject { |commit| commit[:is_merge_commit] }
end

#compute_last_releaseObject



70
71
72
73
74
75
76
77
# File 'lib/cookbook-release/git-utilities.rb', line 70

def compute_last_release
  last = _compute_last_release
  unless last
    $stderr.puts "No last release found, defaulting to 0.1.0"
    last = '0.1.0'
  end
  last.to_version
end

#has_any_release?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/cookbook-release/git-utilities.rb', line 66

def has_any_release?
  !!_compute_last_release
end

#push_tag(version) ⇒ Object



114
115
116
117
118
119
# File 'lib/cookbook-release/git-utilities.rb', line 114

def push_tag(version)
  remote = choose_remote
  cmd = Mixlib::ShellOut.new("git push #{remote} #{@tag_prefix}#{version}", @shellout_opts)
  cmd.run_command
  cmd.error!
end

#reset_command(new_version) ⇒ Object



37
38
39
40
# File 'lib/cookbook-release/git-utilities.rb', line 37

def reset_command(new_version)
  remote = choose_remote
  "git tag -d #{new_version} ; git push #{remote} :#{new_version}"
end

#tag(version) ⇒ Object



97
98
99
# File 'lib/cookbook-release/git-utilities.rb', line 97

def tag(version)
  @g.add_tag("#{@tag_prefix}#{version}")
end