Class: ScmWorkspace
- Inherits:
-
Object
- Object
- ScmWorkspace
- Defined in:
- lib/scm_workspace.rb,
lib/scm_workspace/version.rb
Defined Under Namespace
Classes: Error
Constant Summary collapse
- CONFIGURE_OPTIONS =
{ svn: { "A" => "authors_file", "b" => "branches", "m!" => "minimize_rul", "q+" => "quiet", "r" => "revision", "s" => "stdlayout", "t" => "tags", "T" => "trunk", }, git: { 'n' => 'no_checkout', 'l' => 'local', 's' => 'shared', 'o' => 'origin', 'b' => 'branch', 'u' => 'upload_pack', 'c' => 'config', } }
- VERSION =
"0.3.0"
Instance Attribute Summary collapse
- #logger ⇒ Object
-
#root ⇒ Object
readonly
Returns the value of attribute root.
-
#svn_branch_prefix ⇒ Object
Returns the value of attribute svn_branch_prefix.
-
#verbose ⇒ Object
Returns the value of attribute verbose.
Class Method Summary collapse
Instance Method Summary collapse
- #branch_names ⇒ Object
- #checkout(branch_name) ⇒ Object
- #clear ⇒ Object
- #cleared? ⇒ Boolean
- #commit_info ⇒ Object
- #configure(url) ⇒ Object
- #configured? ⇒ Boolean
- #contains?(obj) ⇒ Boolean
- #current_branch_name ⇒ Object
- #current_commit_key ⇒ Object
- #current_sha ⇒ Object
- #current_tag_names ⇒ Object
- #fetch ⇒ Object
- #fileutils ⇒ Object
- #git_current_branch_name(dir = repo_dir) ⇒ Object
- #git_repo? ⇒ Boolean
- #in_root ⇒ Object (also: #in_repo_dir)
-
#initialize(config, options = {}) ⇒ ScmWorkspace
constructor
A new instance of ScmWorkspace.
- #remotes ⇒ Object
- #repo_dir ⇒ Object
- #reset_hard(tag) ⇒ Object (also: #move)
- #scm_type ⇒ Object
- #status ⇒ Object
- #svn_current_branch_name ⇒ Object
- #svn_info ⇒ Object
- #svn_repo? ⇒ Boolean
- #system!(cmd) ⇒ Object
- #system_at_root!(cmd) ⇒ Object
- #tag_names ⇒ Object
- #url ⇒ Object
Constructor Details
#initialize(config, options = {}) ⇒ ScmWorkspace
Returns a new instance of ScmWorkspace.
21 22 23 24 25 26 |
# File 'lib/scm_workspace.rb', line 21 def initialize(config, = {}) @root = config[:workspace] @logger = [:logger] @verbose = [:verbose] || (ENV["VERBOSE"] =~ /true|yes|on/) @svn_branch_prefix = [:svn_branch_prefix] || ENV["SVN_BRANCH_PREFIX"] || "branches" end |
Instance Attribute Details
#logger ⇒ Object
28 29 30 |
# File 'lib/scm_workspace.rb', line 28 def logger @logger ||= Tengine::Support::NullLogger.new end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
17 18 19 |
# File 'lib/scm_workspace.rb', line 17 def root @root end |
#svn_branch_prefix ⇒ Object
Returns the value of attribute svn_branch_prefix.
19 20 21 |
# File 'lib/scm_workspace.rb', line 19 def svn_branch_prefix @svn_branch_prefix end |
#verbose ⇒ Object
Returns the value of attribute verbose.
20 21 22 |
# File 'lib/scm_workspace.rb', line 20 def verbose @verbose end |
Class Method Details
.guess_scm_type(url) ⇒ Object
326 327 328 329 330 331 332 |
# File 'lib/scm_workspace.rb', line 326 def guess_scm_type(url) case url when /\Agit:\/\//, /\Agit\@/, /\.git\Z/ then :git when /svn/ then :svn else nil end end |
Instance Method Details
#branch_names ⇒ Object
181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/scm_workspace.rb', line 181 def branch_names return nil unless configured? case scm_type when :git then result = system_at_root!("git branch -r").lines.map{|path| path.sub(/\A\s*origin\//, '').strip } result.delete_if{|name| name =~ /\AHEAD ->/} result when :svn then system_at_root!("git branch -r").lines.map{|path| path.strip } end end |
#checkout(branch_name) ⇒ Object
101 102 103 104 105 106 107 |
# File 'lib/scm_workspace.rb', line 101 def checkout(branch_name) logger.info("-" * 100) system_at_root!("git checkout #{branch_name}") case scm_type when :git then system_at_root!("git reset --hard origin/#{branch_name}") end end |
#clear ⇒ Object
91 92 93 94 95 96 97 98 99 |
# File 'lib/scm_workspace.rb', line 91 def clear return unless Dir.exist?(repo_dir) fileutils.chdir(repo_dir) do (Dir.glob("*") + Dir.glob(".*")).each do |d| next if d =~ /\A\.+\Z/ fileutils.remove_entry_secure(d) end end end |
#cleared? ⇒ Boolean
265 266 267 |
# File 'lib/scm_workspace.rb', line 265 def cleared? !configured? end |
#commit_info ⇒ Object
172 173 174 175 176 177 178 179 |
# File 'lib/scm_workspace.rb', line 172 def commit_info { "scm_type" => scm_type.to_s, "url" => url, "branch" => current_branch_name, "commit_key" => current_commit_key } end |
#configure(url) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/scm_workspace.rb', line 65 def configure(url) if configured? msg = "#{repo_dir} is not empty. You must clear it" msg << "\nls -la #{repo_dir}" << `ls -la #{repo_dir}` if verbose raise msg end url, opt = url.split(/\s+/, 2) scm_type = self.class.guess_scm_type(url) case scm_type when :git then logger.info("*" * 100) logger.info("SCM configure") system!("git clone #{url} #{repo_dir} #{opt}") when :svn then fileutils.chdir(@root) do cmd = "git svn clone #{url} #{repo_dir} #{opt}" cmd << " > /dev/null 2>&1" unless verbose logger.info("*" * 100) logger.info("SCM configure") system(cmd) end else raise "Unknown SCM type: #{url}" end end |
#configured? ⇒ Boolean
261 262 263 |
# File 'lib/scm_workspace.rb', line 261 def configured? Dir.exist?(File.join(repo_dir, ".git")) end |
#contains?(obj) ⇒ Boolean
269 270 271 |
# File 'lib/scm_workspace.rb', line 269 def contains?(obj) !!system_at_root!("git show #{obj} --oneline --quiet") rescue false end |
#current_branch_name ⇒ Object
213 214 215 216 217 218 219 |
# File 'lib/scm_workspace.rb', line 213 def current_branch_name return nil unless configured? case scm_type when :git then git_current_branch_name when :svn then svn_current_branch_name end end |
#current_commit_key ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/scm_workspace.rb', line 155 def current_commit_key return nil unless configured? result = current_sha case scm_type when :svn then rev = nil cnt = 0 while rev.nil? rev = in_repo_dir{ `git svn find-rev #{result}`.strip } cnt += 1 raise "failed to get svn revision for #{result}" if cnt > 10 end result << ':' << rev end result end |
#current_sha ⇒ Object
151 152 153 |
# File 'lib/scm_workspace.rb', line 151 def current_sha system_at_root!("git log -1").scan(/^commit ([0-9a-f]+)$/).flatten.first end |
#current_tag_names ⇒ Object
251 252 253 254 |
# File 'lib/scm_workspace.rb', line 251 def current_tag_names return nil unless configured? system_at_root!("git describe --tags #{current_sha}").lines.map(&:strip) rescue [] end |
#fetch ⇒ Object
118 119 120 121 122 123 124 |
# File 'lib/scm_workspace.rb', line 118 def fetch logger.info("-" * 100) case scm_type when :git then system_at_root!("git fetch origin") when :svn then system_at_root!("git svn fetch") end end |
#fileutils ⇒ Object
32 33 34 |
# File 'lib/scm_workspace.rb', line 32 def fileutils @fileutils ||= FileUtils.with_logger(logger) end |
#git_current_branch_name(dir = repo_dir) ⇒ Object
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/scm_workspace.rb', line 221 def git_current_branch_name(dir = repo_dir) return nil unless Dir.exist?(dir) fileutils.chdir(dir) do # http://qiita.com/sugyan/items/83e060e895fa8ef2038c result = `git symbolic-ref --short HEAD`.strip return result unless result.nil? || result.empty? result = `git status`.scan(/On branch\s*(.+)\s*$/).flatten.first return result unless result.nil? || result.empty? work = `git log --decorate -1`.scan(/^commit\s[0-9a-f]+\s\((.+)\)/). flatten.first.split(/,/).map(&:strip).reject{|s| s =~ /HEAD\Z/} r = work.select{|s| s =~ /origin\//}.first r ||= work.first result = r.sub(/\Aorigin\//, '') return result end rescue => e # puts "[#{e.class}] #{e.message}" # puts "Dir.pwd: #{Dir.pwd}" # puts "git status\n" << `git status` raise e end |
#git_repo? ⇒ Boolean
296 297 298 299 |
# File 'lib/scm_workspace.rb', line 296 def git_repo? return nil unless configured? !remotes.empty? rescue false end |
#in_root ⇒ Object Also known as: in_repo_dir
318 319 320 321 322 |
# File 'lib/scm_workspace.rb', line 318 def in_root fileutils.chdir(repo_dir) do return yield end end |
#remotes ⇒ Object
193 194 195 196 197 198 |
# File 'lib/scm_workspace.rb', line 193 def remotes system_at_root!("git remote -v show").lines.each_with_object({}) do |line, d| name, url, other = line.strip.split(/[\t\s]+/, 3) d[name] = url end end |
#repo_dir ⇒ Object
257 258 259 |
# File 'lib/scm_workspace.rb', line 257 def repo_dir @root end |
#reset_hard(tag) ⇒ Object Also known as: move
109 110 111 112 113 114 115 |
# File 'lib/scm_workspace.rb', line 109 def reset_hard(tag) logger.info("-" * 100) case scm_type when :git then system_at_root!("git reset --hard #{tag}") when :svn then raise "Illegal operation for svn" end end |
#scm_type ⇒ Object
306 307 308 309 310 311 |
# File 'lib/scm_workspace.rb', line 306 def scm_type return nil unless configured? return :git if git_repo? return :svn if svn_repo? nil end |
#status ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/scm_workspace.rb', line 126 def status logger.info("-" * 100) case scm_type when :git then status_text = system_at_root!("git status") # in_repo_dir{ `git status` } value = status_text.scan(/Your branch is behind 'origin\/#{current_branch_name}' by (\d+\s+commits)/) if value && !value.empty? "There is/are #{value.flatten.join}" else "everything is up-to-dated." end when :svn then status_text = system_at_root!("git log --branches --oneline #{current_sha}..") lines = status_text.split(/\n/) if lines.empty? "everything is up-to-dated." else latest_sha = lines.first "There is/are #{lines.length} commits." << " current revision: " << system_at_root!("git svn find-rev #{current_sha}").strip << " latest revision: " << system_at_root!("git svn find-rev #{latest_sha}").strip end end end |
#svn_current_branch_name ⇒ Object
243 244 245 246 247 248 249 |
# File 'lib/scm_workspace.rb', line 243 def svn_current_branch_name info = svn_info r = info[:url].sub(info[:repository_root], '') r.sub!(/\A\//, '') r.sub!(svn_branch_prefix + "/", '') r end |
#svn_info ⇒ Object
313 314 315 316 |
# File 'lib/scm_workspace.rb', line 313 def svn_info txt = system_at_root!("git svn info") return txt.scan(/^(.+?): (.*)$/).each_with_object({}){|(k,v), d| d[k.downcase.gsub(/\s/, '_').to_sym] = v } end |
#svn_repo? ⇒ Boolean
301 302 303 304 |
# File 'lib/scm_workspace.rb', line 301 def svn_repo? return nil unless configured? Dir.exist?(File.join(repo_dir, '.git', 'svn')) end |
#system!(cmd) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/scm_workspace.rb', line 36 def system!(cmd) logger.info("executing: #{cmd}") buf = [] IO.popen("#{cmd} 2>&1") do |io| while line = io.gets # puts line buf << line end end if $?.exitstatus == 0 msg = "\e[33mSUCCESS: %s\e[0m" % cmd r = buf.join msg << "\n" << r.strip if verbose logger.info(msg) return r else msg = "\e[31mFAILURE: %s\n%s\e[0m" % [cmd, buf.join.strip] logger.error(msg) raise Error, msg end end |
#system_at_root!(cmd) ⇒ Object
59 60 61 62 63 |
# File 'lib/scm_workspace.rb', line 59 def system_at_root!(cmd) fileutils.chdir(root) do return system!(cmd) end end |
#tag_names ⇒ Object
200 201 202 203 |
# File 'lib/scm_workspace.rb', line 200 def tag_names return nil unless configured? system_at_root!("git tag").lines.map{|path| path.strip.strip } end |
#url ⇒ Object
205 206 207 208 209 210 211 |
# File 'lib/scm_workspace.rb', line 205 def url return nil unless configured? case scm_type when :git then remotes["origin"] when :svn then svn_info[:repository_root] end end |