1*2d57dc69SVladimir Kotal# 2*2d57dc69SVladimir Kotal# CDDL HEADER START 3*2d57dc69SVladimir Kotal# 4*2d57dc69SVladimir Kotal# The contents of this file are subject to the terms of the 5*2d57dc69SVladimir Kotal# Common Development and Distribution License (the "License"). 6*2d57dc69SVladimir Kotal# You may not use this file except in compliance with the License. 7*2d57dc69SVladimir Kotal# 8*2d57dc69SVladimir Kotal# See LICENSE.txt included in this distribution for the specific 9*2d57dc69SVladimir Kotal# language governing permissions and limitations under the License. 10*2d57dc69SVladimir Kotal# 11*2d57dc69SVladimir Kotal# When distributing Covered Code, include this CDDL HEADER in each 12*2d57dc69SVladimir Kotal# file and include the License file at LICENSE.txt. 13*2d57dc69SVladimir Kotal# If applicable, add the following below this CDDL HEADER, with the 14*2d57dc69SVladimir Kotal# fields enclosed by brackets "[]" replaced with your own identifying 15*2d57dc69SVladimir Kotal# information: Portions Copyright [yyyy] [name of copyright owner] 16*2d57dc69SVladimir Kotal# 17*2d57dc69SVladimir Kotal# CDDL HEADER END 18*2d57dc69SVladimir Kotal# 19*2d57dc69SVladimir Kotal 20*2d57dc69SVladimir Kotal# 21*2d57dc69SVladimir Kotal# Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. 22*2d57dc69SVladimir Kotal# Portions Copyright (c) 2020, Krystof Tulinger <k.tulinger@seznam.cz> 23*2d57dc69SVladimir Kotal# 24*2d57dc69SVladimir Kotal 25*2d57dc69SVladimir Kotalfrom shutil import which 26*2d57dc69SVladimir Kotal 27*2d57dc69SVladimir Kotalfrom .repository import Repository, RepositoryException 28*2d57dc69SVladimir Kotalfrom ..utils.command import Command 29*2d57dc69SVladimir Kotal 30*2d57dc69SVladimir Kotal 31*2d57dc69SVladimir Kotalclass MercurialRepository(Repository): 32*2d57dc69SVladimir Kotal def __init__(self, logger, path, project, command, env, hooks, timeout): 33*2d57dc69SVladimir Kotal super().__init__(logger, path, project, command, env, hooks, timeout) 34*2d57dc69SVladimir Kotal 35*2d57dc69SVladimir Kotal self.command = self._repository_command(command, default=lambda: which('hg')) 36*2d57dc69SVladimir Kotal 37*2d57dc69SVladimir Kotal if not self.command: 38*2d57dc69SVladimir Kotal raise RepositoryException("Cannot get hg command") 39*2d57dc69SVladimir Kotal 40*2d57dc69SVladimir Kotal def get_branch(self): 41*2d57dc69SVladimir Kotal hg_command = [self.command, "branch"] 42*2d57dc69SVladimir Kotal cmd = self.getCommand(hg_command, work_dir=self.path, 43*2d57dc69SVladimir Kotal env_vars=self.env, logger=self.logger) 44*2d57dc69SVladimir Kotal cmd.execute() 45*2d57dc69SVladimir Kotal self.logger.info("output of {}:".format(cmd)) 46*2d57dc69SVladimir Kotal self.logger.info(cmd.getoutputstr()) 47*2d57dc69SVladimir Kotal if cmd.getretcode() != 0 or cmd.getstate() != Command.FINISHED: 48*2d57dc69SVladimir Kotal cmd.log_error("failed to get branch") 49*2d57dc69SVladimir Kotal return None 50*2d57dc69SVladimir Kotal else: 51*2d57dc69SVladimir Kotal if not cmd.getoutput(): 52*2d57dc69SVladimir Kotal self.logger.error("no output from {}". 53*2d57dc69SVladimir Kotal format(hg_command)) 54*2d57dc69SVladimir Kotal return None 55*2d57dc69SVladimir Kotal if len(cmd.getoutput()) == 0: 56*2d57dc69SVladimir Kotal self.logger.error("empty output from {}". 57*2d57dc69SVladimir Kotal format(hg_command)) 58*2d57dc69SVladimir Kotal return None 59*2d57dc69SVladimir Kotal return cmd.getoutput()[0].strip() 60*2d57dc69SVladimir Kotal 61*2d57dc69SVladimir Kotal def reposync(self): 62*2d57dc69SVladimir Kotal branch = self.get_branch() 63*2d57dc69SVladimir Kotal if not branch: 64*2d57dc69SVladimir Kotal # Error logged already in get_branch(). 65*2d57dc69SVladimir Kotal return 1 66*2d57dc69SVladimir Kotal 67*2d57dc69SVladimir Kotal hg_command = [self.command, "pull"] 68*2d57dc69SVladimir Kotal if branch != "default": 69*2d57dc69SVladimir Kotal hg_command.append("-b") 70*2d57dc69SVladimir Kotal hg_command.append(branch) 71*2d57dc69SVladimir Kotal cmd = self.getCommand(hg_command, work_dir=self.path, 72*2d57dc69SVladimir Kotal env_vars=self.env, logger=self.logger) 73*2d57dc69SVladimir Kotal cmd.execute() 74*2d57dc69SVladimir Kotal self.logger.info("output of {}:".format(cmd)) 75*2d57dc69SVladimir Kotal self.logger.info(cmd.getoutputstr()) 76*2d57dc69SVladimir Kotal if cmd.getretcode() != 0 or cmd.getstate() != Command.FINISHED: 77*2d57dc69SVladimir Kotal cmd.log_error("failed to perform pull") 78*2d57dc69SVladimir Kotal return 1 79*2d57dc69SVladimir Kotal 80*2d57dc69SVladimir Kotal hg_command = [self.command, "update"] 81*2d57dc69SVladimir Kotal # Avoid remote branch lookup for default branches since 82*2d57dc69SVladimir Kotal # some servers do not support it. 83*2d57dc69SVladimir Kotal if branch == "default": 84*2d57dc69SVladimir Kotal hg_command.append("--check") 85*2d57dc69SVladimir Kotal cmd = self.getCommand(hg_command, work_dir=self.path, 86*2d57dc69SVladimir Kotal env_vars=self.env, logger=self.logger) 87*2d57dc69SVladimir Kotal cmd.execute() 88*2d57dc69SVladimir Kotal self.logger.info("output of {}:".format(cmd)) 89*2d57dc69SVladimir Kotal self.logger.info(cmd.getoutputstr()) 90*2d57dc69SVladimir Kotal if cmd.getretcode() != 0 or cmd.getstate() != Command.FINISHED: 91*2d57dc69SVladimir Kotal cmd.log_error("failed to perform pull and update") 92*2d57dc69SVladimir Kotal return 1 93*2d57dc69SVladimir Kotal 94*2d57dc69SVladimir Kotal return 0 95*2d57dc69SVladimir Kotal 96*2d57dc69SVladimir Kotal def incoming_check(self): 97*2d57dc69SVladimir Kotal branch = self.get_branch() 98*2d57dc69SVladimir Kotal if not branch: 99*2d57dc69SVladimir Kotal # Error logged already in get_branch(). 100*2d57dc69SVladimir Kotal raise RepositoryException('cannot get branch for repository {}'. 101*2d57dc69SVladimir Kotal format(self)) 102*2d57dc69SVladimir Kotal 103*2d57dc69SVladimir Kotal hg_command = [self.command, 'incoming'] 104*2d57dc69SVladimir Kotal if branch != "default": 105*2d57dc69SVladimir Kotal hg_command.append("-b") 106*2d57dc69SVladimir Kotal hg_command.append(branch) 107*2d57dc69SVladimir Kotal cmd = self.getCommand(hg_command, work_dir=self.path, 108*2d57dc69SVladimir Kotal env_vars=self.env, logger=self.logger) 109*2d57dc69SVladimir Kotal cmd.execute() 110*2d57dc69SVladimir Kotal self.logger.info("output of {}:".format(cmd)) 111*2d57dc69SVladimir Kotal self.logger.info(cmd.getoutputstr()) 112*2d57dc69SVladimir Kotal retcode = cmd.getretcode() 113*2d57dc69SVladimir Kotal if cmd.getstate() != Command.FINISHED or retcode not in [0, 1]: 114*2d57dc69SVladimir Kotal cmd.log_error("failed to perform incoming") 115*2d57dc69SVladimir Kotal raise RepositoryException('failed to perform incoming command ' 116*2d57dc69SVladimir Kotal 'for repository {}'.format(self)) 117*2d57dc69SVladimir Kotal 118*2d57dc69SVladimir Kotal if retcode == 0: 119*2d57dc69SVladimir Kotal return True 120*2d57dc69SVladimir Kotal else: 121*2d57dc69SVladimir Kotal return False 122