diff options
author | Shawn O. Pearce <sop@google.com> | 2012-08-02 14:57:37 -0700 |
---|---|---|
committer | Shawn O. Pearce <sop@google.com> | 2012-08-02 15:18:10 -0700 |
commit | 5e7127d00baf5bdad3e52cf8784c8aaa736395e1 (patch) | |
tree | b28b86ba1eb092483d0f5e02f73e6532a167e8c9 /project.py | |
parent | 5d0efdb14a31d651a0f6061ffb73452a20b7ed77 (diff) | |
download | git-repo-5e7127d00baf5bdad3e52cf8784c8aaa736395e1.tar.gz |
Use curl command line tool for clone.bundlev1.10.3
urllib2 is not thread safe and may be causing sync to lock up or
not work correctly on various platforms. Instead use the command
line curl program.
Change-Id: I36eaf18bb4df089d26ea99d533cb015e7c616eb0
Diffstat (limited to 'project.py')
-rw-r--r-- | project.py | 132 |
1 files changed, 30 insertions, 102 deletions
@@ -20,19 +20,9 @@ import random | |||
20 | import re | 20 | import re |
21 | import shutil | 21 | import shutil |
22 | import stat | 22 | import stat |
23 | import subprocess | ||
23 | import sys | 24 | import sys |
24 | import time | 25 | import time |
25 | import urllib2 | ||
26 | |||
27 | try: | ||
28 | import threading as _threading | ||
29 | except ImportError: | ||
30 | import dummy_threading as _threading | ||
31 | |||
32 | try: | ||
33 | from os import SEEK_END | ||
34 | except ImportError: | ||
35 | SEEK_END = 2 | ||
36 | 26 | ||
37 | from color import Coloring | 27 | from color import Coloring |
38 | from git_command import GitCommand | 28 | from git_command import GitCommand |
@@ -41,11 +31,10 @@ from error import DownloadError | |||
41 | from error import GitError, HookError, ImportError, UploadError | 31 | from error import GitError, HookError, ImportError, UploadError |
42 | from error import ManifestInvalidRevisionError | 32 | from error import ManifestInvalidRevisionError |
43 | from progress import Progress | 33 | from progress import Progress |
34 | from trace import IsTrace, Trace | ||
44 | 35 | ||
45 | from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M | 36 | from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M |
46 | 37 | ||
47 | _urllib_lock = _threading.Lock() | ||
48 | |||
49 | def _lwrite(path, content): | 38 | def _lwrite(path, content): |
50 | lock = '%s.lock' % path | 39 | lock = '%s.lock' % path |
51 | 40 | ||
@@ -1553,100 +1542,39 @@ class Project(object): | |||
1553 | return ok | 1542 | return ok |
1554 | 1543 | ||
1555 | def _FetchBundle(self, srcUrl, tmpPath, dstPath, quiet): | 1544 | def _FetchBundle(self, srcUrl, tmpPath, dstPath, quiet): |
1556 | keep = True | 1545 | if os.path.exists(dstPath): |
1557 | done = False | 1546 | os.remove(dstPath) |
1558 | dest = open(tmpPath, 'a+b') | ||
1559 | try: | ||
1560 | dest.seek(0, SEEK_END) | ||
1561 | pos = dest.tell() | ||
1562 | 1547 | ||
1563 | _urllib_lock.acquire() | 1548 | cmd = ['curl', '--output', tmpPath, '--netrc', '--location'] |
1564 | try: | 1549 | if quiet: |
1565 | req = urllib2.Request(srcUrl) | 1550 | cmd += ['--silent'] |
1566 | if pos > 0: | 1551 | if os.path.exists(tmpPath): |
1567 | req.add_header('Range', 'bytes=%d-' % (pos,)) | 1552 | size = os.stat(tmpPath).st_size |
1568 | 1553 | if size >= 1024: | |
1569 | try: | 1554 | cmd += ['--continue-at', '%d' % (size,)] |
1570 | r = urllib2.urlopen(req) | 1555 | else: |
1571 | except urllib2.HTTPError, e: | 1556 | os.remove(tmpPath) |
1572 | def _content_type(): | 1557 | if 'http_proxy' in os.environ and 'darwin' == sys.platform: |
1573 | try: | 1558 | cmd += ['--proxy', os.environ['http_proxy']] |
1574 | return e.info()['content-type'] | 1559 | cmd += [srcUrl] |
1575 | except: | ||
1576 | return None | ||
1577 | |||
1578 | if e.code in (401, 403, 404): | ||
1579 | keep = False | ||
1580 | return False | ||
1581 | elif _content_type() == 'text/plain': | ||
1582 | try: | ||
1583 | msg = e.read() | ||
1584 | if len(msg) > 0 and msg[-1] == '\n': | ||
1585 | msg = msg[0:-1] | ||
1586 | msg = ' (%s)' % (msg,) | ||
1587 | except: | ||
1588 | msg = '' | ||
1589 | else: | ||
1590 | try: | ||
1591 | from BaseHTTPServer import BaseHTTPRequestHandler | ||
1592 | res = BaseHTTPRequestHandler.responses[e.code] | ||
1593 | msg = ' (%s: %s)' % (res[0], res[1]) | ||
1594 | except: | ||
1595 | msg = '' | ||
1596 | raise DownloadError('HTTP %s%s' % (e.code, msg)) | ||
1597 | except urllib2.URLError, e: | ||
1598 | raise DownloadError('%s: %s ' % (req.get_host(), str(e))) | ||
1599 | finally: | ||
1600 | _urllib_lock.release() | ||
1601 | |||
1602 | p = None | ||
1603 | try: | ||
1604 | size = pos + int(r.headers.get('content-length', 0)) | ||
1605 | unit = 1 << 10 | ||
1606 | 1560 | ||
1607 | if size and not quiet: | 1561 | if IsTrace(): |
1608 | if size > 1024 * 1.3: | 1562 | Trace('%s', ' '.join(cmd)) |
1609 | unit = 1 << 20 | 1563 | try: |
1610 | desc = 'MB' | 1564 | proc = subprocess.Popen(cmd) |
1611 | else: | 1565 | except OSError: |
1612 | desc = 'KB' | 1566 | return False |
1613 | p = Progress( | ||
1614 | 'Downloading %s' % (self.relpath,), | ||
1615 | int(size) / unit, | ||
1616 | units=desc) | ||
1617 | if pos > 0: | ||
1618 | p.update(pos / unit) | ||
1619 | |||
1620 | s = 0 | ||
1621 | while True: | ||
1622 | d = r.read(8192) | ||
1623 | if d == '': | ||
1624 | done = True | ||
1625 | return True | ||
1626 | dest.write(d) | ||
1627 | if p: | ||
1628 | s += len(d) | ||
1629 | if s >= unit: | ||
1630 | p.update(s / unit) | ||
1631 | s = s % unit | ||
1632 | if p: | ||
1633 | if s >= unit: | ||
1634 | p.update(s / unit) | ||
1635 | else: | ||
1636 | p.update(1) | ||
1637 | finally: | ||
1638 | r.close() | ||
1639 | if p: | ||
1640 | p.end() | ||
1641 | finally: | ||
1642 | dest.close() | ||
1643 | 1567 | ||
1644 | if os.path.exists(dstPath): | 1568 | ok = proc.wait() == 0 |
1645 | os.remove(dstPath) | 1569 | if os.path.exists(tmpPath): |
1646 | if done: | 1570 | if ok and os.stat(tmpPath).st_size > 16: |
1647 | os.rename(tmpPath, dstPath) | 1571 | os.rename(tmpPath, dstPath) |
1648 | elif not keep: | 1572 | return True |
1573 | else: | ||
1649 | os.remove(tmpPath) | 1574 | os.remove(tmpPath) |
1575 | return False | ||
1576 | else: | ||
1577 | return False | ||
1650 | 1578 | ||
1651 | def _Checkout(self, rev, quiet=False): | 1579 | def _Checkout(self, rev, quiet=False): |
1652 | cmd = ['checkout'] | 1580 | cmd = ['checkout'] |