Class: GitMaintain::Repo

Inherits:
Object
  • Object
show all
Defined in:
lib/repo.rb

Constant Summary collapse

ACTION_LIST =
[
    :list_branches,
    # Internal commands for completion
    :list_suffixes, :submit_release
]
ACTION_HELP =
[
    "* submit_release: Push the to stable and create the release packages",
]
@@VALID_REPO =
"github"
@@STABLE_REPO =
"stable"
@@SUBMIT_BINARY =
"git-release"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path = nil) ⇒ Repo



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
# File 'lib/repo.rb', line 39

def initialize(path=nil)
    GitMaintain::checkDirectConstructor(self.class)

    @path = path
    @branch_list=nil
    @stable_branches=nil
    @suffix_list=nil

    if path == nil
        @path = Dir.pwd()
    end

    @valid_repo = runGit("config maintain.valid-repo 2> /dev/null").chomp()
    @valid_repo = @@VALID_REPO if @valid_repo == ""
    @stable_repo = runGit("config maintain.stable-repo 2>/dev/null").chomp()
    @stable_repo = @@STABLE_REPO if @stable_repo == ""

    @remote_valid=runGit("remote -v | egrep '^#{@valid_repo}' | grep fetch |
                        awk '{ print $2}' | sed -e 's/.*://' -e 's/\\.git//'")
    @remote_stable=runGit("remote -v | egrep '^#{@stable_repo}' | grep fetch |
                              awk '{ print $2}' | sed -e 's/.*://' -e 's/\\.git//'")

    @branch_format_raw = runGit("config maintain.branch-format 2> /dev/null").chomp()
    @branch_format = Regexp.new(/#{@branch_format_raw}/)
    @stable_branch_format = runGit("config maintain.stable-branch-format 2> /dev/null").chomp()
    @stable_base_format = runGit("config maintain.stable-base-format 2> /dev/null").chomp()

    @stable_base_patterns=
        runGit("config --get-regexp   stable-base | egrep '^stable-base\.' | "+
               "sed -e 's/stable-base\.//' -e 's/---/\\//g'").split("\n").inject({}){ |m, x|
        y=x.split(" ");
        m[y[0]] = y[1]
        m
    }
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



74
75
76
# File 'lib/repo.rb', line 74

def path
  @path
end

#remote_stableObject (readonly)

Returns the value of attribute remote_stable.



74
75
76
# File 'lib/repo.rb', line 74

def remote_stable
  @remote_stable
end

#remote_validObject (readonly)

Returns the value of attribute remote_valid.



74
75
76
# File 'lib/repo.rb', line 74

def remote_valid
  @remote_valid
end

#stable_repoObject (readonly)

Returns the value of attribute stable_repo.



74
75
76
# File 'lib/repo.rb', line 74

def stable_repo
  @stable_repo
end

#valid_repoObject (readonly)

Returns the value of attribute valid_repo.



74
75
76
# File 'lib/repo.rb', line 74

def valid_repo
  @valid_repo
end

Class Method Details

.check_opts(opts) ⇒ Object



22
23
24
25
26
27
28
# File 'lib/repo.rb', line 22

def self.check_opts(opts)
    if opts[:action] == :submit_release then
        if opts[:br_suff] != "master" then
            raise "Action #{opts[:action]} can only be done on 'master' suffixed branches"
        end
    end
end

.execAction(opts, action) ⇒ Object



30
31
32
33
34
35
36
37
# File 'lib/repo.rb', line 30

def self.execAction(opts, action)
    repo   = Repo::load()

    if action == :submit_release then
        repo.stableUpdate()
    end
    repo.send(action, opts)
end

.load(path = ".") ⇒ Object



16
17
18
19
20
# File 'lib/repo.rb', line 16

def self.load(path=".")
    dir = Dir.pwd()
    repo_name = File.basename(dir)
    return GitMaintain::loadClass(Repo, repo_name, dir)
end

Instance Method Details

#find_alts(commit) ⇒ Object



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/repo.rb', line 259

def find_alts(commit)
    alts=[]

    subj=runGit("log -1 --pretty='%s' #{commit}")
    return alts if $? != 0

    branches = getStableBranchList().map(){|v| @@STABLE_REPO + "/" + versionToStableBranch(v)}

    runGit("log -F --grep \"$#{subj}\" --format=\"%H\" #{branches.join(" ")}").
        split("\n").each(){|c|
        next if c == commit
        cursubj=runGit("log -1 --pretty='%s' #{c}")
        alts << c if subj == cursubj
    }

    return alts
end

#findStableBase(branch) ⇒ Object



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/repo.rb', line 233

def findStableBase(branch)
    base=nil
    if branch =~ @branch_format then
        base = branch.gsub(/^\*?\s*#{@branch_format_raw}\/.*$/, @stable_base_format)
    end

    @stable_base_patterns.each(){|pattern, b|
        if branch =~ /#{pattern}\// || branch =~ /#{pattern}$/
            base = b
            break
        end
    }
    raise("Could not a find a stable base for branch #{branch}") if base == nil
    return base
end

#getBranchList(br_suff) ⇒ Object



119
120
121
122
123
124
125
126
127
128
# File 'lib/repo.rb', line 119

def getBranchList(br_suff)
    return @branch_list if @branch_list != nil

    @branch_list=runGit("branch").split("\n").map(){|x|
        x=~ /#{@branch_format_raw}\/#{br_suff}$/ ? 
            $1 : nil
    }.compact().uniq()

    return @branch_list
end

#getCommitHeadline(sha) ⇒ Object



111
112
113
# File 'lib/repo.rb', line 111

def getCommitHeadline(sha)
    return runGit("show --format=oneline --no-patch --no-decorate #{sha}")
end

#getStableBranchListObject



130
131
132
133
134
135
136
137
138
139
# File 'lib/repo.rb', line 130

def getStableBranchList()
    return @stable_branches if @stable_branches != nil

    @stable_branches=runGit("branch -a").split("\n").map(){|x|
        x=~ /remotes\/#{@@STABLE_REPO}\/#{@stable_branch_format.gsub(/\\1/, '([0-9]+)')}$/ ?
            $1 : nil
    }.compact().uniq()

    return @stable_branches
end

#getSuffixListObject



141
142
143
144
145
146
147
148
149
150
151
# File 'lib/repo.rb', line 141

def getSuffixList()
    return @suffix_list if @suffix_list != nil

    @suffix_list = runGit("branch").split("\n").map(){|x|
        x=~ @branch_format ? 
            /^\*?\s*#{@branch_format_raw}\/([a-zA-Z0-9_-]+)\s*$/.match(x)[-1] :
            nil
    }.compact().uniq()

    return @suffix_list
end

#list_branches(opts) ⇒ Object



249
250
251
# File 'lib/repo.rb', line 249

def list_branches(opts)
    puts getBranchList(opts[:br_suff])
end

#list_suffixes(opts) ⇒ Object



252
253
254
# File 'lib/repo.rb', line 252

def list_suffixes(opts)
    puts getSuffixList()
end

#log(lvl, str) ⇒ Object



76
77
78
# File 'lib/repo.rb', line 76

def log(lvl, str)
    GitMaintain::log(lvl, str)
end

#run(cmd) ⇒ Object



80
81
82
# File 'lib/repo.rb', line 80

def run(cmd)
    return `cd #{@path} && #{cmd}`
end

#runBashObject



101
102
103
104
105
106
107
108
109
# File 'lib/repo.rb', line 101

def runBash()
    runSystem("bash")
    if $? == 0 then
        log(:INFO, "Continuing...")
    else
        log(:ERROR, "Shell exited with code #{$?}. Exiting")
        raise("Cancelled by user")
    end
end

#runGit(cmd) ⇒ Object



86
87
88
89
90
# File 'lib/repo.rb', line 86

def runGit(cmd)
    log(:DEBUG, "Called from #{caller[1]}")
    log(:DEBUG, "Running git command '#{cmd}'")
    return `git --work-tree=#{@path} #{cmd}`.chomp()
end

#runGitImap(cmd) ⇒ Object



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

def runGitImap(cmd)
    return `export GIT_ASKPASS=$(dirname $(dirname $(which git)))/lib/git-core/git-gui--askpass;
          if [ ! -f $GIT_ASKPASS ]; then
            export GIT_ASKPASS=$(dirname $(which git))/git-gui--askpass;
          fi;
          if [ ! -f $GIT_ASKPASS ]; then
            export GIT_ASKPASS=/usr/lib/ssh/ssh-askpass;
          fi; git --work-tree=#{@path} imap-send #{cmd}`
end

#runSystem(cmd) ⇒ Object



83
84
85
# File 'lib/repo.rb', line 83

def runSystem(cmd)
    return system("cd #{@path} && #{cmd}")
end

#stableUpdateObject



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

def stableUpdate()
    log(:VERBOSE, "Fetching stable updates...")
    runGit("fetch #{@stable_repo}")
end

#submit_release(opts) ⇒ Object



255
256
257
# File 'lib/repo.rb', line 255

def submit_release(opts)
    submitReleases(opts)
end

#submitReleases(opts) ⇒ Object



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/repo.rb', line 153

def submitReleases(opts)
    remote_tags=runGit("ls-remote --tags #{@stable_repo} |
                         egrep 'refs/tags/v[0-9.]*$'").split("\n").map(){
        |x| x.gsub(/.*refs\/tags\//, '')
    }
    local_tags =runGit("tag -l | egrep '^v[0-9.]*$'").split("\n")

    new_tags = local_tags - remote_tags
    if new_tags.empty? then
        log(:INFO,  "All tags are already submitted.")
        return
    end

    log(:WARNING, "This will officially release these tags: #{new_tags.join(", ")}")
    rep = GitMaintain::confirm(opts, "release them")
    if rep != 'y' then
        raise "Aborting.."
    end

    if @NOTIFY_RELEASE != false
        mail_path=`mktemp`.chomp()
        mail = File.open(mail_path, "w+")
        mail.puts "From " + runGit("rev-parse HEAD") + " " + `date`.chomp()
        mail.puts "From: " + runGit("config user.name") +
                  " <" + runGit("config user.email") +">"
        mail.puts "To: " + runGit("config patch.target")
        mail.puts "Date: " + `date -R`.chomp()

        if new_tags.length > 4 then
            mail.puts "Subject: [ANNOUNCE] " + File.basename(@path) + ": new stable releases"
            mail.puts ""
            mail.puts "These version were tagged/released:\n * " +
                      new_tags.join("\n * ")
            mail.puts ""
        else
            mail.puts "Subject: [ANNOUNCE] " + File.basename(@path) + " " +
                      (new_tags.length > 1 ?
                           (new_tags[0 .. -2].join(", ") + " and " + new_tags[-1] + " have ") :
                           (new_tags.join(" ") + " has ")) +
                      " been tagged/released"
            mail.puts ""
        end
        mail.puts "It's available at the normal places:"
        mail.puts ""
        mail.puts "git://github.com/#{@remote_stable}"
        mail.puts "https://github.com/#{@remote_stable}/releases"
        mail.puts ""
        mail.puts "---"
        mail.puts ""
        mail.puts "Here's the information from the tags:"
        new_tags.sort().each(){|tag|
            mail.puts `git show #{tag} --no-decorate -q | awk '!p;/^-----END PGP SIGNATURE-----/{p=1}'`
            mail.puts ""
        }
        mail.puts "It's available at the normal places:"
        mail.puts ""
        mail.puts "git://github.com/#{@remote_stable}"
        mail.puts "https://github.com/#{@remote_stable}/releases"
        mail.close()

        puts runGitImap("< #{mail_path}; rm -f #{mail_path}")
    end

    log(:WARNING, "Last chance to cancel before submitting")
    rep= GitMaintain::confirm(opts, "submit these releases")
    if rep != 'y' then
        raise "Aborting.."
    end
    puts `#{@@SUBMIT_BINARY}`
end

#versionToLocalBranch(version, suff) ⇒ Object



224
225
226
227
# File 'lib/repo.rb', line 224

def versionToLocalBranch(version, suff)
    return @branch_format_raw.gsub(/\\\//, '/').
        gsub(/\(.*\)/, version) + "/#{suff}"
end

#versionToStableBranch(version) ⇒ Object



229
230
231
# File 'lib/repo.rb', line 229

def versionToStableBranch(version)
    return version.gsub(/^(.*)$/, @stable_branch_format)
end