]> git.ipfire.org Git - people/jschlag/pbs.git/blame - src/buildservice/git.py
Use autotools
[people/jschlag/pbs.git] / src / buildservice / git.py
CommitLineData
83be3106
MT
1#!/usr/bin/python
2
3import datetime
4import logging
5import os
6import subprocess
7
8import base
9import sources
10
11class Repo(base.Object):
12 def __init__(self, pakfire, id, mode="normal"):
13 base.Object.__init__(self, pakfire)
14
15 assert mode in ("normal", "bare", "mirror")
16
17 # Get the source object.
18 self.source = sources.Source(pakfire, id)
19 self.mode = mode
20
21 @property
22 def path(self):
23 return os.path.join("/var/cache/pakfire/git-repos", self.source.identifier, self.mode)
24
25 def git(self, cmd, path=None):
26 if not path:
27 path = self.path
28
29 cmd = "cd %s && git %s" % (path, cmd)
30
31 logging.debug("Running command: %s" % cmd)
32
33 return subprocess.check_output(["/bin/sh", "-c", cmd])
34
35 @property
36 def cloned(self):
37 """
38 Say if the repository is already cloned.
39 """
40 return os.path.exists(self.path)
41
42 def clone(self):
43 if self.cloned:
44 return
45
46 path = os.path.dirname(self.path)
47 repo = os.path.basename(self.path)
48
49 # Create the repository home directory if not exists.
50 if not os.path.exists(path):
51 os.makedirs(path)
52
53 command = ["clone"]
54 if self.mode == "bare":
55 command.append("--bare")
56 elif self.mode == "mirror":
57 command.append("--mirror")
58
59 command.append(self.source.url)
60 command.append(repo)
61
62 # Clone the repository.
63 try:
64 self.git(" ".join(command), path=path)
65 except Exception:
66 shutil.rmtree(self.path)
67 raise
68
69 def fetch(self):
70 # Make sure, the repository was already cloned.
71 if not self.cloned:
72 self.clone()
73
74 self.git("fetch")
75
76 def rev_list(self, revision=None):
77 if not revision:
78 if self.source.head_revision:
79 revision = self.source.head_revision.revision
80 else:
81 revision = self.source.start_revision
82
83 command = "rev-list %s..%s" % (revision, self.source.branch)
84
85 # Get all merge commits.
86 merges = self.git("%s --merges" % command).splitlines()
87
88 revisions = []
89 for commit in self.git(command).splitlines():
90 # Check if commit is a normal commit or merge commit.
91 merge = commit in merges
92
93 revisions.append((commit, merge))
94
95 return [r for r in reversed(revisions)]
96
97 def import_revisions(self):
98 # Get all pending revisions.
99 revisions = self.rev_list()
100
101 for revision, merge in revisions:
102 # Actually import the revision.
103 self._import_revision(revision, merge)
104
105 def _import_revision(self, revision, merge):
106 logging.debug("Going to import revision %s (merge: %s)." % (revision, merge))
107
108 rev_author = self.git("log -1 --format=\"%%an <%%ae>\" %s" % revision)
109 rev_committer = self.git("log -1 --format=\"%%cn <%%ce>\" %s" % revision)
110 rev_subject = self.git("log -1 --format=\"%%s\" %s" % revision)
111 rev_body = self.git("log -1 --format=\"%%b\" %s" % revision)
112 rev_date = self.git("log -1 --format=\"%%at\" %s" % revision)
113 rev_date = datetime.datetime.utcfromtimestamp(float(rev_date))
114
115 # Convert strings properly. No idea why I have to do that.
116 #rev_author = rev_author.decode("latin-1").strip()
117 #rev_committer = rev_committer.decode("latin-1").strip()
118 #rev_subject = rev_subject.decode("latin-1").strip()
119 #rev_body = rev_body.decode("latin-1").rstrip()
120
121 # Create a new commit object in the database
122 commit = sources.Commit.create(self.pakfire, self.source, revision,
123 rev_author, rev_committer, rev_subject, rev_body, rev_date)
124
125 def checkout(self, revision, update=False):
126 for update in (0, 1):
127 if update:
128 self.fetch()
129
130 try:
131 self.git("checkout %s" % revision)
132
133 except subprocess.CalledProcessError:
134 if not update:
135 continue
136
137 raise
138
139 def changed_files(self, revision):
140 files = self.git("diff --name-only %s^ %s" % (revision, revision))
141
142 return [os.path.join(self.path, f) for f in files.splitlines()]
143
144 def get_all_files(self):
145 files = self.git("ls-files")
146
147 return [os.path.join(self.path, f) for f in files.splitlines()]