Module: Overcommit::Utils

Defined in:
lib/overcommit/utils.rb

Overview

Utility functions for general use.

Class Method Summary collapse

Class Method Details

.broken_symlink?(file) ⇒ true, false

Returns whether a file is a broken symlink.

Returns:

  • (true, false)


130
131
132
133
134
# File 'lib/overcommit/utils.rb', line 130

def broken_symlink?(file)
  # JRuby's implementation of File.exist? returns true for broken
  # symlinks, so we need use File.size?
  File.symlink?(file) && File.size?(file).nil?
end

.camel_case(str) ⇒ Object

Converts a string containing underscores/hyphens/spaces into CamelCase.



68
69
70
# File 'lib/overcommit/utils.rb', line 68

def camel_case(str)
  str.split(/_|-| /).map { |part| part.sub(/^\w/) { |c| c.upcase } }.join
end

.convert_glob_to_absolute(glob) ⇒ String

Convert a glob pattern to an absolute path glob pattern rooted from the repository root directory.

Parameters:

  • glob (String)

Returns:

  • (String)


141
142
143
# File 'lib/overcommit/utils.rb', line 141

def convert_glob_to_absolute(glob)
  File.join(repo_root, glob)
end

.execute(args) ⇒ Object

Wrap external subshell calls. This is necessary in order to allow Overcommit to call other Ruby executables without requiring that they be specified in Overcommit’s Gemfile–a nasty consequence of using ‘bundle exec overcommit` while developing locally.



102
103
104
105
106
107
108
109
110
111
# File 'lib/overcommit/utils.rb', line 102

def execute(args)
  if args.include?('|')
    raise Overcommit::Exceptions::InvalidCommandArgs,
          'Cannot pipe commands with the `execute` helper'
  end

  with_environment 'RUBYOPT' => nil do
    Subprocess.spawn(args)
  end
end

.git_dir(repo_dir = repo_root) ⇒ String

Returns an absolute path to the .git directory for a repo.

Parameters:

  • repo_dir (String) (defaults to: repo_root)

    root directory of git repo

Returns:

  • (String)


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/overcommit/utils.rb', line 38

def git_dir(repo_dir = repo_root)
  @git_dir ||=
    begin
      git_dir = File.expand_path('.git', repo_dir)

      # .git could also be a file that contains the location of the git directory
      unless File.directory?(git_dir)
        git_dir = File.read(git_dir)[/^gitdir: (.*)$/, 1]

        # Resolve relative paths
        unless git_dir.start_with?('/')
          git_dir = File.expand_path(git_dir, repo_dir)
        end
      end

      git_dir
    end
end

.in_path?(cmd) ⇒ Boolean

Returns whether a command can be found given the current environment path.

Returns:

  • (Boolean)


87
88
89
90
91
92
93
94
95
96
# File 'lib/overcommit/utils.rb', line 87

def in_path?(cmd)
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
    exts.each do |ext|
      exe = File.join(path, "#{cmd}#{ext}")
      return true if File.executable?(exe)
    end
  end
  false
end

.matches_path?(pattern, path) ⇒ Boolean

Return whether a pattern matches the given path.

Parameters:

  • pattern (String)
  • path (String)

Returns:

  • (Boolean)


149
150
151
152
153
154
# File 'lib/overcommit/utils.rb', line 149

def matches_path?(pattern, path)
  File.fnmatch?(pattern, path,
                File::FNM_PATHNAME | # Wildcard doesn't match separator
                File::FNM_DOTMATCH   # Wildcards match dotfiles
  )
end

.repo_rootString

Returns an absolute path to the root of the repository.

We do this ourselves rather than call ‘git rev-parse –show-toplevel` to solve an issue where the .git directory might not actually be valid in tests.

Returns:

  • (String)


19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/overcommit/utils.rb', line 19

def repo_root
  @repo_root ||=
    begin
      git_dir = Pathname.new(File.expand_path('.')).enum_for(:ascend).find do |path|
        File.exist?(File.join(path, '.git'))
      end

      unless git_dir
        raise Overcommit::Exceptions::InvalidGitRepo, 'no .git directory found'
      end

      git_dir.to_s
    end
end

.script_path(script) ⇒ Object



8
9
10
# File 'lib/overcommit/utils.rb', line 8

def script_path(script)
  File.join(OVERCOMMIT_HOME, 'libexec', script)
end

.snake_case(str) ⇒ Object

Shamelessly stolen from: stackoverflow.com/questions/1509915/converting-camel-case-to-underscore-case-in-ruby



59
60
61
62
63
64
65
# File 'lib/overcommit/utils.rb', line 59

def snake_case(str)
  str.gsub(/::/, '/').
      gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
      gsub(/([a-z\d])([A-Z])/, '\1_\2').
      tr('-', '_').
      downcase
end

.supported_hook_type_classesObject

Returns a list of supported hook classes (PreCommit, CommitMsg, etc.)



80
81
82
83
84
# File 'lib/overcommit/utils.rb', line 80

def supported_hook_type_classes
  supported_hook_types.map do |file|
    file.split('-').map(&:capitalize).join
  end
end

.supported_hook_typesObject

Returns a list of supported hook types (pre-commit, commit-msg, etc.)



73
74
75
76
77
# File 'lib/overcommit/utils.rb', line 73

def supported_hook_types
  Dir[File.join(OVERCOMMIT_HOME, 'lib', 'overcommit', 'hook', '*')].
    select { |file| File.directory?(file) }.
    map { |file| File.basename(file, '.rb').gsub('_', '-') }
end

.with_environment(env) ⇒ Object

Calls a block of code with a modified set of environment variables, restoring them once the code has executed.



115
116
117
118
119
120
121
122
123
124
125
# File 'lib/overcommit/utils.rb', line 115

def with_environment(env)
  old_env = {}
  env.each do |var, value|
    old_env[var] = ENV[var.to_s]
    ENV[var.to_s] = value
  end

  yield
ensure
  old_env.each { |var, value| ENV[var.to_s] = value }
end