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.2.1"
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
- #current_branch_name ⇒ Object
- #current_commit_key ⇒ Object
- #current_sha ⇒ Object
- #current_tag_names ⇒ Object
- #fetch ⇒ 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.
- #puts_info(msg) ⇒ Object
- #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.
20 21 22 23 24 25 |
# File 'lib/scm_workspace.rb', line 20 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
27 28 29 |
# File 'lib/scm_workspace.rb', line 27 def logger @logger ||= Tengine::Support::NullLogger.new end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
16 17 18 |
# File 'lib/scm_workspace.rb', line 16 def root @root end |
#svn_branch_prefix ⇒ Object
Returns the value of attribute svn_branch_prefix.
18 19 20 |
# File 'lib/scm_workspace.rb', line 18 def svn_branch_prefix @svn_branch_prefix end |
#verbose ⇒ Object
Returns the value of attribute verbose.
19 20 21 |
# File 'lib/scm_workspace.rb', line 19 def verbose @verbose end |
Class Method Details
.guess_scm_type(url) ⇒ Object
319 320 321 322 323 324 325 |
# File 'lib/scm_workspace.rb', line 319 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
178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/scm_workspace.rb', line 178 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
97 98 99 100 101 102 103 |
# File 'lib/scm_workspace.rb', line 97 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
87 88 89 90 91 92 93 94 95 |
# File 'lib/scm_workspace.rb', line 87 def clear return unless Dir.exist?(repo_dir) Dir.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
262 263 264 |
# File 'lib/scm_workspace.rb', line 262 def cleared? !configured? end |
#commit_info ⇒ Object
169 170 171 172 173 174 175 176 |
# File 'lib/scm_workspace.rb', line 169 def commit_info { "scm_type" => scm_type.to_s, "url" => url, "branch" => current_branch_name, "commit_key" => current_commit_key } end |
#configure(url) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/scm_workspace.rb', line 60 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 Dir.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") puts_info "cd #{@root} && " + cmd system(cmd) end else raise "Unknown SCM type: #{url}" end end |
#configured? ⇒ Boolean
258 259 260 |
# File 'lib/scm_workspace.rb', line 258 def configured? Dir.exist?(File.join(repo_dir, ".git")) end |
#current_branch_name ⇒ Object
210 211 212 213 214 215 216 |
# File 'lib/scm_workspace.rb', line 210 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
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/scm_workspace.rb', line 152 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
148 149 150 |
# File 'lib/scm_workspace.rb', line 148 def current_sha system_at_root!("git log -1").scan(/^commit ([0-9a-f]+)$/).flatten.first end |
#current_tag_names ⇒ Object
248 249 250 251 |
# File 'lib/scm_workspace.rb', line 248 def current_tag_names return nil unless configured? system_at_root!("git describe --tags #{current_sha}").lines.map(&:strip) rescue [] end |
#fetch ⇒ Object
114 115 116 117 118 119 120 |
# File 'lib/scm_workspace.rb', line 114 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 |
#git_current_branch_name(dir = repo_dir) ⇒ Object
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/scm_workspace.rb', line 218 def git_current_branch_name(dir = repo_dir) return nil unless Dir.exist?(dir) Dir.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
289 290 291 292 |
# File 'lib/scm_workspace.rb', line 289 def git_repo? return nil unless configured? !remotes.empty? rescue false end |
#in_root ⇒ Object Also known as: in_repo_dir
311 312 313 314 315 |
# File 'lib/scm_workspace.rb', line 311 def in_root Dir.chdir(repo_dir) do return yield end end |
#puts_info(msg) ⇒ Object
31 32 33 34 |
# File 'lib/scm_workspace.rb', line 31 def puts_info(msg) logger.info(msg) $stdout.puts(msg) if verbose end |
#remotes ⇒ Object
190 191 192 193 194 195 |
# File 'lib/scm_workspace.rb', line 190 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
254 255 256 |
# File 'lib/scm_workspace.rb', line 254 def repo_dir @root end |
#reset_hard(tag) ⇒ Object Also known as: move
105 106 107 108 109 110 111 |
# File 'lib/scm_workspace.rb', line 105 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
299 300 301 302 303 304 |
# File 'lib/scm_workspace.rb', line 299 def scm_type return nil unless configured? return :git if git_repo? return :svn if svn_repo? nil end |
#status ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/scm_workspace.rb', line 122 def status logger.info("-" * 100) case scm_type when :git then # puts_info("git status") 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
240 241 242 243 244 245 246 |
# File 'lib/scm_workspace.rb', line 240 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
306 307 308 309 |
# File 'lib/scm_workspace.rb', line 306 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
294 295 296 297 |
# File 'lib/scm_workspace.rb', line 294 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 |
# 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 logger.info("\e[33mSUCCESS: %s\e[0m" % cmd) return buf.join 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
56 57 58 |
# File 'lib/scm_workspace.rb', line 56 def system_at_root!(cmd) Dir.chdir(root){ system!(cmd) } end |
#tag_names ⇒ Object
197 198 199 200 |
# File 'lib/scm_workspace.rb', line 197 def tag_names return nil unless configured? system_at_root!("git tag").lines.map{|path| path.strip.strip } end |
#url ⇒ Object
202 203 204 205 206 207 208 |
# File 'lib/scm_workspace.rb', line 202 def url return nil unless configured? case scm_type when :git then remotes["origin"] when :svn then svn_info[:repository_root] end end |