Module: GitP4Sync

Defined in:
lib/git_p4_sync.rb

Instance Method Summary collapse

Instance Method Details

#add_slash(path) ⇒ Object



115
116
117
118
# File 'lib/git_p4_sync.rb', line 115

def add_slash(path)
  path += "/" unless path[-1..-1] == "/"
  path
end

#is_ignored?(file) ⇒ Boolean

Returns:

  • (Boolean)


108
109
110
111
112
113
# File 'lib/git_p4_sync.rb', line 108

def is_ignored?(file)
  @ignore_list.each {|ignore|
    return true if lambda_ignore(ignore).call(file)
  }
  return false
end

#lambda_ignore(item) ⇒ Object



103
104
105
106
# File 'lib/git_p4_sync.rb', line 103

def lambda_ignore(item)
  re = Regexp.compile(/#{item}/)
  lambda {|diff| diff =~ re }
end

#p4_add_recursively(path) ⇒ Object



124
125
126
# File 'lib/git_p4_sync.rb', line 124

def p4_add_recursively(path)
  "find #{path} -type f -print | p4 -x - add -f"
end

#run(options) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
86
87
88
89
# File 'lib/git_p4_sync.rb', line 3

def run(options)
  # branch    = options[:branch] || "master"
  branch = "master"
  git_path  = options[:git]
  p4_path   = options[:p4]
  simulate  = options[:simulate] || false
  pull      = options[:pull] || false
  submit    = options[:submit] || false

  @ignore_list = [".git"]
  if options[:ignore]
    if options[:ignore].include?(":")
      @ignore_list = @ignore_list.concat(options[:ignore].split(":"))
    elsif options[:ignore].include?(",")
      @ignore_list = @ignore_list.concat(options[:ignore].split(","))
    else
      @ignore_list = @ignore_list.insert(-1, options[:ignore])
    end
  end

  git_path = add_slash(File.expand_path(git_path))
  p4_path = add_slash(File.expand_path(p4_path))
  
  verify_path_exist!(git_path)
  verify_path_exist!(p4_path)
  
  if pull
    Dir.chdir(git_path) do
      puts "Pulling Git from remote server."
      run_cmd "git pull", simulate
    end
  end

  if File.exist?(gitignore = File.join(git_path, ".gitignore"))
    @ignore_list = @ignore_list.concat(File.read(gitignore).split(/\n/).reject{|i| (i.size == 0) or i.strip.start_with?("#") }.map {|i| i.gsub("*",".*") } )
  end

  diff = diff_dirs(p4_path, git_path)
  
  if diff.size > 0
    diff.each do |d|
      action = d[0]
      file = strip_leading_slash(d[1])

      # todo: skip ignored files/directories
      next if is_ignored?(file)
      
      puts "#{action.to_s.upcase} in Git: #{file}"
      
      Dir.chdir(p4_path) do
        case action
        when :new
          run_cmd "cp -r '#{git_path}#{file}' '#{p4_path}#{file}'", simulate
          run_cmd "#{p4_add_recursively("'#{p4_path}#{file}'")}", simulate
        when :deleted
          file_path="#{p4_path}#{file}"
          Find.find(file_path) do |f|
            puts "DELETED in Git (dir contents): #{f}" if file_path != f
            run_cmd("p4 delete '#{f}'", simulate)
          end
          FileUtils.remove_entry_secure(file_path,:force => true)
        when :modified
          run_cmd "p4 edit '#{p4_path}#{file}'", simulate
          run_cmd "cp '#{git_path}#{file}' '#{p4_path}#{file}'", simulate
        else
          puts "Unknown change type #{action}. Stopping."
          exit 1
        end
      end
    end
    
    if submit
      git_head_commit = ""
      Dir.chdir(git_path) do
        git_head_commit = `git show -v -s --pretty=oneline`.split("\n")[0]
      end
      
      Dir.chdir(p4_path) do
        puts "Submitting changes to Perforce"
        run_cmd "p4 submit -d '#{git_head_commit.gsub("'", "''")}'", simulate
      end
    end
  else
    puts "Directories are identical. Nothing to do."
    exit 0
  end
end

#run_cmd(cmd, simulate = false, puts_prefix = " ") ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/git_p4_sync.rb', line 91

def run_cmd(cmd, simulate = false, puts_prefix = "  ")
  if simulate
    puts "#{puts_prefix}simulation: #{cmd}"
  else
    puts "#{puts_prefix}#{cmd}"
  end
  
  output = ""
  output = `#{cmd}` unless simulate
  [output, $?]
end

#strip_leading_slash(path) ⇒ Object



120
121
122
# File 'lib/git_p4_sync.rb', line 120

def strip_leading_slash(path)
  path.sub(/^\//, "")
end

#verify_path_exist!(path) ⇒ Object



128
129
130
131
132
133
# File 'lib/git_p4_sync.rb', line 128

def verify_path_exist!(path)
  if !File.exist?(path) || !File.directory?(path)
    puts "#{path} must exist and be a directory."
    exit 1
  end
end