Line 0
Link Here
|
0 |
- |
1 |
# Copyright 2005-2018 Gentoo Foundation |
|
|
2 |
# Distributed under the terms of the GNU General Public License v2 |
3 |
|
4 |
import logging |
5 |
import subprocess |
6 |
|
7 |
import portage |
8 |
from portage import os |
9 |
from portage.util import writemsg_level, shlex_split |
10 |
from portage.output import create_color_func |
11 |
good = create_color_func("GOOD") |
12 |
bad = create_color_func("BAD") |
13 |
warn = create_color_func("WARN") |
14 |
from portage.sync.syncbase import NewBase |
15 |
|
16 |
|
17 |
class MercurialSync(NewBase): |
18 |
'''Mercurial sync class''' |
19 |
|
20 |
short_desc = "Perform sync operations on mercurial based repositories" |
21 |
|
22 |
@staticmethod |
23 |
def name(): |
24 |
return "MercurialSync" |
25 |
|
26 |
|
27 |
def __init__(self): |
28 |
NewBase.__init__(self, "hg", portage.const.HG_PACKAGE_ATOM) |
29 |
|
30 |
|
31 |
def exists(self, **kwargs): |
32 |
'''Tests whether the repo actually exists''' |
33 |
return os.path.exists(os.path.join(self.repo.location, '.hg')) |
34 |
|
35 |
|
36 |
def new(self, **kwargs): |
37 |
'''Do the initial clone of the repository''' |
38 |
if kwargs: |
39 |
self._kwargs(kwargs) |
40 |
try: |
41 |
if not os.path.exists(self.repo.location): |
42 |
os.makedirs(self.repo.location) |
43 |
self.logger(self.xterm_titles, |
44 |
'Created new directory %s' % self.repo.location) |
45 |
except IOError: |
46 |
return (1, False) |
47 |
|
48 |
sync_uri = self.repo.sync_uri |
49 |
if sync_uri.startswith("file://"): |
50 |
sync_uri = sync_uri[7:] |
51 |
|
52 |
hg_cmd_opts = "" |
53 |
if self.repo.module_specific_options.get('sync-mercurial-env'): |
54 |
shlexed_env = shlex_split(self.repo.module_specific_options['sync-mercurial-env']) |
55 |
env = dict((k, v) for k, _, v in (assignment.partition('=') for assignment in shlexed_env) if k) |
56 |
self.spawn_kwargs['env'].update(env) |
57 |
|
58 |
if self.repo.module_specific_options.get('sync-mercurial-clone-env'): |
59 |
shlexed_env = shlex_split(self.repo.module_specific_options['sync-mercurial-clone-env']) |
60 |
clone_env = dict((k, v) for k, _, v in (assignment.partition('=') for assignment in shlexed_env) if k) |
61 |
self.spawn_kwargs['env'].update(clone_env) |
62 |
|
63 |
if self.settings.get("PORTAGE_QUIET") == "1": |
64 |
hg_cmd_opts += " --quiet" |
65 |
if self.repo.module_specific_options.get('sync-mercurial-clone-extra-opts'): |
66 |
hg_cmd_opts += " %s" % self.repo.module_specific_options['sync-mercurial-clone-extra-opts'] |
67 |
hg_cmd = "%s clone%s %s ." % (self.bin_command, hg_cmd_opts, |
68 |
portage._shell_quote(sync_uri)) |
69 |
writemsg_level(hg_cmd + "\n") |
70 |
|
71 |
exitcode = portage.process.spawn_bash("cd %s ; exec %s" % ( |
72 |
portage._shell_quote(self.repo.location), hg_cmd), |
73 |
**self.spawn_kwargs) |
74 |
if exitcode != os.EX_OK: |
75 |
msg = "!!! hg clone error in %s" % self.repo.location |
76 |
self.logger(self.xterm_titles, msg) |
77 |
writemsg_level(msg + "\n", level=logging.ERROR, noiselevel=-1) |
78 |
return (exitcode, False) |
79 |
return (os.EX_OK, True) |
80 |
|
81 |
|
82 |
def update(self): |
83 |
''' Update existing mercurial repository, and ignore the syncuri. We are |
84 |
going to trust the user and assume that the user is in the branch |
85 |
that he/she wants updated. We'll let the user manage branches with |
86 |
hg directly. |
87 |
''' |
88 |
|
89 |
hg_cmd_opts = "" |
90 |
if self.repo.module_specific_options.get('sync-mercurial-env'): |
91 |
shlexed_env = shlex_split(self.repo.module_specific_options['sync-mercurial-env']) |
92 |
env = dict((k, v) for k, _, v in (assignment.partition('=') for assignment in shlexed_env) if k) |
93 |
self.spawn_kwargs['env'].update(env) |
94 |
|
95 |
if self.repo.module_specific_options.get('sync-mercurial-pull-env'): |
96 |
shlexed_env = shlex_split(self.repo.module_specific_options['sync-mercurial-pull-env']) |
97 |
pull_env = dict((k, v) for k, _, v in (assignment.partition('=') for assignment in shlexed_env) if k) |
98 |
self.spawn_kwargs['env'].update(pull_env) |
99 |
|
100 |
if self.settings.get("PORTAGE_QUIET") == "1": |
101 |
hg_cmd_opts += " --quiet" |
102 |
if self.repo.module_specific_options.get('sync-mercurial-pull-extra-opts'): |
103 |
hg_cmd_opts += " %s" % self.repo.module_specific_options['sync-mercurial-pull-extra-opts'] |
104 |
hg_cmd = "%s pull -u%s" % (self.bin_command, hg_cmd_opts) |
105 |
writemsg_level(hg_cmd + "\n") |
106 |
|
107 |
rev_cmd = [self.bin_command, "id", "--id", "--rev", "tip"] |
108 |
previous_rev = subprocess.check_output(rev_cmd, |
109 |
cwd=portage._unicode_encode(self.repo.location)) |
110 |
|
111 |
exitcode = portage.process.spawn_bash("cd %s ; exec %s" % ( |
112 |
portage._shell_quote(self.repo.location), hg_cmd), |
113 |
**self.spawn_kwargs) |
114 |
if exitcode != os.EX_OK: |
115 |
msg = "!!! hg pull error in %s" % self.repo.location |
116 |
self.logger(self.xterm_titles, msg) |
117 |
writemsg_level(msg + "\n", level=logging.ERROR, noiselevel=-1) |
118 |
return (exitcode, False) |
119 |
|
120 |
current_rev = subprocess.check_output(rev_cmd, |
121 |
cwd=portage._unicode_encode(self.repo.location)) |
122 |
|
123 |
return (os.EX_OK, current_rev != previous_rev) |
124 |
|
125 |
def retrieve_head(self, **kwargs): |
126 |
'''Get information about the head commit''' |
127 |
if kwargs: |
128 |
self._kwargs(kwargs) |
129 |
rev_cmd = [self.bin_command, "id", "--id", "--rev", "tip"] |
130 |
try: |
131 |
ret = (os.EX_OK, |
132 |
portage._unicode_decode(subprocess.check_output(rev_cmd, |
133 |
cwd=portage._unicode_encode(self.repo.location)))) |
134 |
except subprocess.CalledProcessError: |
135 |
ret = (1, False) |
136 |
return ret |