source: tailor/vcpx/repository/p4/source.py @ 1336

Revision 1336, 3.7 KB checked in by Dustin Sallings <dustin@…>, 6 years ago (diff)

First pass at a perforce source

Line 
1# -*- mode: python; coding: utf-8 -*-
2# :Progetto: vcpx -- p4 source
3# :Creato:   Fri Mar 16 23:06:43 PDT 2007
4# :Autore:   Dustin Sallings <dustin@spy.net>
5# :Licenza:  GNU General Public License
6#
7
8"""
9This module implements the source backend for p4.
10"""
11
12__docformat__ = 'reStructuredText'
13
14from vcpx.shwrap import ExternalCommand, PIPE
15from vcpx.config import ConfigurationError
16from vcpx.source import UpdatableSourceWorkingDir, GetUpstreamChangesetsFailure
17from vcpx.source import ChangesetApplicationFailure
18from vcpx.changes import Changeset
19from vcpx.tzinfo import UTC
20
21from datetime import datetime
22import exceptions
23import string
24import time
25import os
26
27import p4lib
28
29P4_DATE_FMT="%Y/%m/%d %H:%M:%S"
30
31class NotForMe(exceptions.Exception):
32    def __init__(self, s):
33        self.s=s
34    def __repr__(self):
35        "<NotForMe:  " + self.s + ">"
36    __str__=__repr__
37
38class P4SourceWorkingDir(UpdatableSourceWorkingDir):
39    def __getNativeChanges(self, sincerev):
40        changes=p4lib.P4().changes(self.repository.repo_path + "...")
41        changes.reverse()
42        # Get rid of changes that are too low
43        changes=filter(lambda c: int(c['change']) > sincerev, changes)
44        return changes
45
46    def __parseDate(self, d):
47        return datetime.fromtimestamp(time.mktime(
48            time.strptime(d, P4_DATE_FMT)), UTC)
49
50    def __adaptChanges(self, changes):
51        p4=p4lib.P4()
52        descrs=[p4.describe(c['change'], shortForm=True) for c in changes]
53        return [Changeset(d['change'], self.__parseDate(d['date']), \
54            d['user'], d['description']) for d in descrs]
55
56    def _getUpstreamChangesets(self, sincerev):
57        return self.__adaptChanges(self.__getNativeChanges(sincerev))
58
59    def __getLocalFilename(self, f, dp):
60        trans=string.maketrans(" ", "_")
61        fn=f['depotFile']
62        rv=fn
63        if fn.startswith(dp):
64            rv=fn[len(dp):]
65            if rv[0]=='/':
66                rv=rv[1:]
67        else:
68            raise NotForMe(f)
69        return rv
70
71    def __ensureDirFor(self, lf):
72        rv=False
73        d=os.path.dirname(lf)
74        if d != '' and not os.path.exists(d):
75            rv=True
76            os.makedirs(d)
77        return rv
78
79    def __getFiles(self, desc):
80        p4=p4lib.P4()
81        stuff={'add':[], 'delete':[], 'edit':[], 'integrate':[]}
82        for f in desc['files']:
83            lf=self.__getLocalFilename(f, self.repository.repo_path)
84            fqlf=os.path.join(self.repository.basedir, lf)
85            self.__ensureDirFor(fqlf)
86            if f['action'] == 'delete':
87                os.unlink(fqlf)
88            else:
89                p4.print_([f['depotFile'] + "#" + `f['rev']`], localFile=fqlf)
90                assert os.path.exists(fqlf)
91            stuff[f['action']].append(lf)
92            self.log.debug("%s -> %s", str(f), str(lf))
93        return stuff
94
95    def _applyChangeset(self, changeset):
96        stuff=self.__getFiles(p4lib.P4().describe(
97            changeset.revision, shortForm=True))
98        for k,v in stuff.iteritems():
99            for f in v:
100                e=changeset.addEntry(f, changeset.revision)
101                if k == 'add':
102                    e.action_kind = e.ADDED
103                elif k == 'delete':
104                    e.action_kind = e.DELETED
105                elif k in ['edit', 'integrate']:
106                    e.action_kind = e.UPDATED
107                else:
108                    assert False
109        return []
110
111    def _checkoutUpstreamRevision(self, revision):
112        if revision == 'INITIAL':
113            revision = self.__getNativeChanges(-1)[0]['change']
114        p4=p4lib.P4()
115        desc=p4.describe(revision, shortForm=True)
116
117        self.__getFiles(desc)
118
119        ts=self.__parseDate(desc['date'])
120
121        return Changeset(revision, ts, desc['user'], desc['description'])
Note: See TracBrowser for help on using the repository browser.