1 # Copyright (C) 2007, Thomas Leonard
2 # See the README file for details, or visit http://0install.net.
5 from zeroinstall
import SafeException
6 from logging
import info
9 def __init__(self
, local_iface
, options
):
10 self
.local_iface
= local_iface
11 self
.options
= options
14 def _run(self
, args
, **kwargs
):
15 info("Running git %s", ' '.join(args
))
16 return subprocess
.Popen(["git"] + args
, cwd
= os
.path
.dirname(self
.local_iface
.uri
), **kwargs
)
18 def _run_check(self
, args
, **kwargs
):
19 child
= self
._run
(args
, **kwargs
)
22 raise SafeException("Git %s failed with exit code %d" % (repr(args
), code
))
24 def _run_stdout(self
, args
, **kwargs
):
25 child
= self
._run
(args
, stdout
= subprocess
.PIPE
, **kwargs
)
26 stdout
, unused
= child
.communicate()
28 raise SafeException('Failed to get current branch! Exit code %d: %s' % (child
.returncode
, stdout
))
31 def reset_hard(self
, revision
):
32 self
._run
_check
(['reset', '--hard', revision
])
34 def ensure_committed(self
):
35 child
= self
._run
(["status", "-a"], stdout
= subprocess
.PIPE
)
36 stdout
, unused
= child
.communicate()
37 if not child
.returncode
:
38 raise SafeException('Uncommitted changes! Use "git-commit -a" to commit them. Changes are:\n' + stdout
)
40 def make_tag(self
, version
):
43 def tag(self
, version
, revision
):
44 tag
= self
.make_tag(version
)
46 key_opts
= ['-u', self
.options
.key
]
49 self
._run
_check
(['tag', '-s'] + key_opts
+ ['-m', 'Release %s' % version
, tag
, revision
])
50 print "Tagged as %s" % tag
52 def get_current_branch(self
):
53 current_branch
= self
._run
_stdout
(['symbolic-ref', 'HEAD']).strip()
54 info("Current branch is %s", current_branch
)
57 def delete_branch(self
, branch
):
58 self
._run
_check
(['branch', '-D', branch
])
60 def push_head_and_release(self
, version
):
61 self
._run
_check
(['push', self
.options
.public_scm_repository
, self
.make_tag(version
), self
.get_current_branch()])
63 def ensure_no_tag(self
, version
):
64 tag
= self
.make_tag(version
)
65 child
= self
._run
(['tag', '-l', '-q', tag
])
68 raise SafeException(("Release %s is already tagged! If you want to replace it, do\n" +
69 "git-tag -d %s") % (version
, tag
))
71 def export(self
, prefix
, archive_file
):
72 child
= self
._run
(['archive', '--format=tar', '--prefix=' + prefix
+ '/', 'HEAD'], stdout
= subprocess
.PIPE
)
73 subprocess
.check_call(['bzip2', '-'], stdin
= child
.stdout
, stdout
= file(archive_file
, 'w'))
76 if os
.path
.exists(archive_file
):
77 os
.unlink(archive_file
)
78 raise SafeException("git-archive failed with exit code %d" % status
)
80 def commit(self
, message
, branch
, parent
):
81 self
._run
_check
(['add', '-u']) # Commit all changed tracked files to index
82 tree
= self
._run
_stdout
(['write-tree']).strip()
83 child
= self
._run
(['commit-tree', tree
, '-p', parent
], stdin
= subprocess
.PIPE
, stdout
= subprocess
.PIPE
)
84 stdout
, unused
= child
.communicate(message
)
85 commit
= stdout
.strip()
86 info("Committed as %s", commit
)
87 self
._run
_check
(['branch', '-f', branch
, commit
])
90 def get_head_revision(self
):
91 proc
= self
._run
(['rev-parse', 'HEAD'], stdout
= subprocess
.PIPE
)
92 stdout
, unused
= proc
.communicate()
94 raise Exception("git rev-parse failed with exit code %d" % proc
.returncode
)
99 def export_changelog(self
, last_release_version
, head
, stream
):
100 if last_release_version
:
101 self
._run
_check
(['log', 'refs/tags/v' + last_release_version
+ '..' + head
], stdout
= stream
)
103 self
._run
_check
(['log', head
], stdout
= stream
)