Skip to content

Commit f73c656

Browse files
author
Vladimir Kotal
committed
check incoming changes
fixes #2399
1 parent ce21220 commit f73c656

File tree

4 files changed

+128
-47
lines changed

4 files changed

+128
-47
lines changed

opengrok-tools/src/main/python/opengrok_tools/all/scm/git.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#
2323

2424
from ..utils.command import Command
25-
from .repository import Repository
25+
from .repository import Repository, RepositoryException
2626
from shutil import which
2727

2828

@@ -41,8 +41,8 @@ def __init__(self, logger, path, project, command, env, hooks, timeout):
4141
raise OSError
4242

4343
def reposync(self):
44-
hg_command = [self.command, "pull", "--ff-only"]
45-
cmd = self.getCommand(hg_command, work_dir=self.path,
44+
git_command = [self.command, "pull", "--ff-only"]
45+
cmd = self.getCommand(git_command, work_dir=self.path,
4646
env_vars=self.env, logger=self.logger)
4747
cmd.execute()
4848
self.logger.info(cmd.getoutputstr())
@@ -51,3 +51,18 @@ def reposync(self):
5151
return 1
5252

5353
return 0
54+
55+
def incoming(self):
56+
git_command = [self.command, "pull", "--dry-run"]
57+
cmd = self.getCommand(git_command, work_dir=self.path,
58+
env_vars=self.env, logger=self.logger)
59+
cmd.execute()
60+
if cmd.getretcode() != 0 or cmd.getstate() != Command.FINISHED:
61+
cmd.log_error("failed to perform pull")
62+
raise RepositoryException('failed to check for incoming in '
63+
'repository {}'.format(self))
64+
65+
if len(cmd.getoutput()) == 0:
66+
return False
67+
else:
68+
return True

opengrok-tools/src/main/python/opengrok_tools/all/scm/mercurial.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#
2323

2424
from ..utils.command import Command
25-
from .repository import Repository
25+
from .repository import Repository, RepositoryException
2626
from shutil import which
2727

2828

@@ -63,7 +63,7 @@ def get_branch(self):
6363
def reposync(self):
6464
branch = self.get_branch()
6565
if not branch:
66-
# Error logged allready in get_branch().
66+
# Error logged already in get_branch().
6767
return 1
6868

6969
hg_command = [self.command, "pull"]
@@ -92,3 +92,28 @@ def reposync(self):
9292
return 1
9393

9494
return 0
95+
96+
def incoming(self):
97+
branch = self.get_branch()
98+
if not branch:
99+
# Error logged already in get_branch().
100+
raise RepositoryException('cannot get branch for repository {}'.
101+
format(self))
102+
103+
hg_command = [self.command, 'incoming']
104+
if branch != "default":
105+
hg_command.append("-b")
106+
hg_command.append(branch)
107+
cmd = self.getCommand(hg_command, work_dir=self.path,
108+
env_vars=self.env, logger=self.logger)
109+
cmd.execute()
110+
self.logger.debug(cmd.getoutputstr())
111+
if cmd.getstate() != Command.FINISHED:
112+
cmd.log_error("failed to perform incoming")
113+
raise RepositoryException('failed to perform incoming command '
114+
'for repository {}'.format(self))
115+
116+
if cmd.getretcode() == 0:
117+
return True
118+
else:
119+
return False

opengrok-tools/src/main/python/opengrok_tools/all/scm/repository.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@
2525
from ..utils.command import Command
2626

2727

28+
class RepositoryException(Exception):
29+
"""
30+
Exception returned when repository operation failed.
31+
"""
32+
pass
33+
34+
2835
class Repository:
2936
"""
3037
abstract class wrapper for Source Code Management repository
@@ -63,3 +70,11 @@ def reposync(self):
6370
Return 1 on failure, 0 on success.
6471
"""
6572
raise NotImplementedError()
73+
74+
def incoming(self):
75+
"""
76+
Check if there are any incoming changes.
77+
78+
Return True if so, False otherwise.
79+
"""
80+
return True

opengrok-tools/src/main/python/opengrok_tools/mirror.py

Lines changed: 68 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@
4343
from all.utils.readconfig import read_config
4444
from all.utils.repofactory import get_repository
4545
from all.utils.utils import is_exe, check_create_dir, get_int, diff_list
46+
from all.scm.repository import RepositoryException
47+
4648

4749
major_version = sys.version_info[0]
48-
if (major_version < 3):
50+
if major_version < 3:
4951
print("Need Python 3, you are running {}".format(major_version))
5052
sys.exit(1)
5153

52-
__version__ = "0.2"
54+
__version__ = "0.3"
5355

5456
# "constants"
5557
HOOK_TIMEOUT_PROPERTY = 'hook_timeout'
@@ -68,53 +70,46 @@
6870
CONTINUE_EXITVAL = 2
6971

7072

71-
def get_repos_for_project(logger, project, source_root, config, proxy,
72-
command_timeout, ignored_repos, uri):
73+
def get_repos_for_project(logger, project, ignored_repos, **kwargs):
7374
"""
7475
:param logger: logger
7576
:param project: project name
76-
:param source_root: source root path
77-
:param config: configuration dictionary
78-
:param proxy: proxy
79-
:param command_timeout: command timeout
8077
:param ignored_repos: list of ignored repositories
81-
:param uri: URI for the web application
82-
:return: tuple of lists of Repository objects and return value
83-
(1 on failure, 0 on success)
78+
:param kwargs: argument dictionary
79+
:return: list of Repository objects
8480
"""
8581
repos = []
86-
ret = 0
87-
for repo_path in get_repos(logger, project, uri):
82+
for repo_path in get_repos(logger, project, kwargs['uri']):
8883
logger.debug("Repository path = {}".format(repo_path))
8984

9085
if repo_path in ignored_repos:
9186
logger.info("repository {} ignored".format(repo_path))
9287
continue
9388

94-
repo_type = get_repo_type(logger, repo_path, uri)
89+
repo_type = get_repo_type(logger, repo_path, kwargs['uri'])
9590
if not repo_type:
96-
logger.error("cannot determine type of {}".
97-
format(repo_path))
98-
continue
91+
raise RepositoryException("cannot determine type of repository {}".
92+
format(repo_path))
9993

10094
logger.debug("Repository type = {}".format(repo_type))
10195

10296
repo = get_repository(logger,
103-
source_root + repo_path,
97+
# Not joining the path since the form
98+
# of repo_path is absolute path.
99+
kwargs['source_root'] + repo_path,
104100
repo_type,
105101
project,
106-
config.get(COMMANDS_PROPERTY),
107-
proxy,
102+
kwargs['commands'],
103+
kwargs['proxy'],
108104
None,
109-
command_timeout)
105+
kwargs['command_timeout'])
110106
if not repo:
111-
logger.error("Cannot get repository for {}".
112-
format(repo_path))
113-
ret = 1
107+
raise RepositoryException("Cannot get repository for {}".
108+
format(repo_path))
114109
else:
115-
repos.add(repo)
110+
repos.append(repo)
116111

117-
return repos, ret
112+
return repos
118113

119114

120115
def main():
@@ -133,6 +128,9 @@ def main():
133128
help='batch mode - will log into a file')
134129
parser.add_argument('-B', '--backupcount', default=8,
135130
help='how many log files to keep around in batch mode')
131+
parser.add_argument('-I', '--incoming', action='store_true',
132+
help='Check for incoming changes, terminate the '
133+
'processing if not found.')
136134
args = parser.parse_args()
137135

138136
if args.debug:
@@ -166,10 +164,10 @@ def main():
166164

167165
uri = args.uri
168166
if not uri:
169-
logger.error("uri of the webapp not specified")
167+
logger.error("URI of the web application not specified")
170168
sys.exit(1)
171169

172-
logger.debug("Uri = {}".format(uri))
170+
logger.debug("URI = {}".format(uri))
173171

174172
source_root = get_config_value(logger, 'sourceRoot', uri)
175173
if not source_root:
@@ -251,7 +249,7 @@ def main():
251249

252250
ignored_repos = project_config.get(IGNORED_REPOS_PROPERTY)
253251
if ignored_repos:
254-
if type(ignored_repos) is not list:
252+
if not isinstance(ignored_repos, list):
255253
logger.error("{} for project {} is not a list".
256254
format(IGNORED_REPOS_PROPERTY, args.project))
257255
sys.exit(1)
@@ -347,18 +345,46 @@ def main():
347345
# Cache the repositories first. This way it will be known that
348346
# something is not right, avoiding any needless pre-hook run.
349347
#
350-
repos, ret = get_repos_for_project(logger, args.project,
351-
source_root, config, proxy,
352-
command_timeout, ignored_repos,
353-
uri)
354-
if ret == 1:
355-
# The error was already logged in get_repos_for_project()
348+
repos = []
349+
try:
350+
repos = get_repos_for_project(logger, args.project,
351+
ignored_repos,
352+
commands=config.
353+
get(COMMANDS_PROPERTY),
354+
proxy=proxy,
355+
command_timeout=command_timeout,
356+
source_root=source_root,
357+
uri=uri)
358+
except RepositoryException:
359+
logger.error('failed to get repositories for project {}'.
360+
format(args.project))
356361
sys.exit(1)
357-
if len(repos) == 0:
362+
363+
if not repos:
358364
logger.info("No repositories for project {}".
359365
format(args.project))
360366
sys.exit(CONTINUE_EXITVAL)
361367

368+
# Check if any of the repositories contains incoming changes.
369+
if args.incoming:
370+
got_incoming = False
371+
for repo in repos:
372+
try:
373+
if repo.incoming():
374+
logger.debug('Repository {} has incoming changes'.
375+
format(repo))
376+
got_incoming = True
377+
break
378+
except RepositoryException:
379+
logger.error('Cannot determine incoming changes for '
380+
'repository {}, driving on'.format(repo))
381+
382+
if not got_incoming:
383+
logger.info('No incoming changes for repositories in '
384+
'project {}'.
385+
format(args.project))
386+
sys.exit(CONTINUE_EXITVAL)
387+
362388
if prehook:
363389
logger.info("Running pre hook")
364390
if run_hook(logger, prehook,
@@ -374,12 +400,12 @@ def main():
374400
# is treated as failed, i.e. the program will return 1.
375401
#
376402
for repo in repos:
377-
logger.info("Synchronizing repository {}".
378-
format(repo.path))
379-
if repo.sync() != 0:
380-
logger.error("failed to sync repository {}".
381-
format(repo.path))
382-
ret = 1
403+
logger.info("Synchronizing repository {}".
404+
format(repo.path))
405+
if repo.sync() != 0:
406+
logger.error("failed to sync repository {}".
407+
format(repo.path))
408+
ret = 1
383409

384410
if posthook:
385411
logger.info("Running post hook")

0 commit comments

Comments
 (0)