def master_hook(ui, repo, **kwargs):
    ui.debug('running tamarin master_hook\n')
    ui.debug('kwargs: %s\n' % kwargs)
    # The mercurial hook script expects the equivalent of an exit code back from
    # this call:
    #   False = 0 = No Error : allow push
    #   True = 1 = Error : abort push
    error = False
    error = error or diff_check(ui, repo, **kwargs)

    if error:
        # Save the commit message so it can be reused by user
        desc = repo[repo[kwargs['node']].rev()].description()
        ui.debug('Description: %s\n' % desc)
        try:
            f = open('%s/.hg/commit.save' % repo.root, 'w')
            f.write(desc)
            f.close()
            ui.warn(
                'Commit message saved to .hg/commit.save\nSaved message can be recommitted using -l .hg/commit.save\n'
            )
        except IOError:
            ui.warn('Error writing .hg/commit.save file')

    return error
def get_config(ui: ui, item: str) -> str:
    try:
        # config returns configuration value.
        return ui.config("zulip", item)
    except IndexError:
        ui.warn(f"Zulip: Could not find required item {item} in hg config.")
        sys.exit(1)
def get_config(ui: ui, item: str) -> str:
    try:
        # config returns configuration value.
        return ui.config('zulip', item)
    except IndexError:
        ui.warn("Zulip: Could not find required item {} in hg config.".format(item))
        sys.exit(1)
def run(ui, repo, **kwargs):
	http = HTTPConnection(jenkins_server_adress+':'+jenkins_port)
	http.request("GET",jenkins_server_adress+':'+jenkins_port+"/job/"
			+job_name+"/build")
	ui.warn(jenkins_server_adress+':'+jenkins_port+"/job/"
			+job_name+"/build\n")
	ui.warn(str(http.getresponse().read())+'\n')
	return False
def get_config(ui, item):
    # type: (ui, str) -> str
    try:
        # config returns configuration value.
        return ui.config('zulip', item)
    except IndexError:
        ui.warn("Zulip: Could not find required item {} in hg config.".format(item))
        sys.exit(1)
Example #6
0
def get_config(ui, item):
    # type: (ui, str) -> str
    try:
        # config returns configuration value.
        return ui.config('yakkl', item)
    except IndexError:
        ui.warn("Yakkl: Could not find required item {} in hg config.".format(
            item))
        sys.exit(1)
def get_config(ui, item):
    # type: (ui, str) -> str
    try:
        # configlist returns everything in lists.
        return ui.configlist('zulip', item)[0]
    except IndexError:
        ui.warn("Zulip: Could not find required item {} in hg config.".format(
            item))
        sys.exit(1)
Example #8
0
def _list(ui, repo, opts):
    l = [repo.root]
    for subtree in _subtreelist(ui, repo, opts):
        dir = repo.wjoin(subtree)
        if os.path.exists(dir):
            lr = hg.repository(ui, dir)
            l += _list(lr.ui, lr, opts)
        else:
            ui.warn('repo %s is missing subtree %s\n' % (repo.root, subtree))
    return l
Example #9
0
def reposetup(ui, repo):
    # TODO: decide use of config section for this extension
    global _ui
    _ui = ui
    if not os.path.supports_unicode_filenames:
        ui.warn(_("[win32mbcs] cannot activate on this platform.\n"))
        return
    # install features of this extension
    install()
    ui.debug(_("[win32mbcs] activeted with encoding: %s\n") % util._encoding)
Example #10
0
def reposetup(ui, repo):
    # TODO: decide use of config section for this extension
    global _ui
    _ui = ui
    if not os.path.supports_unicode_filenames:
        ui.warn(_("[win32mbcs] cannot activate on this platform.\n"))
        return
    # install features of this extension
    install()
    ui.debug(_("[win32mbcs] activeted with encoding: %s\n") % util._encoding)
Example #11
0
def _list(ui, repo, opts):
    l = [repo.root]
    for subtree in _subtreelist(ui, repo, opts):
        dir = repo.wjoin(subtree)
        if os.path.exists(dir):
            lr = hg.repository(ui, dir)
            l += _list(lr.ui, lr, opts)
        else:
            ui.warn('repo %s is missing subtree %s\n' % (repo.root, subtree))
    return l
def security_check(ui, repo, **kwargs):
    ui.debug('running security_check\n')
    error = False

    ui.pushbuffer()
    _quiet(
        ui, lambda: commands.log(ui,
                                 repo,
                                 rev=['%s:tip' % kwargs['node']],
                                 template='{node}\n',
                                 date=None,
                                 user=None,
                                 logfile=None))
    nodes = ui.popbuffer().split('\n')

    # reenable this code if we need to blacklist a node
    for node in nodes:
        if node.startswith('8555e8551203') or node.startswith('e09bb3ece6c7'):
            ui.warn('blacklisted changeid found: node %s is blacklisted\n' %
                    node)
            error = True  # fail the push

    # Look for blacklisted bugs
    blacklist = [
        # Serrano
        580489,
        604354,
        # Wasabi
        507624,
        # Cyril
        570049,
        628834,
    ]

    bugs = re.compile('(%s)' % '|'.join([str(bug) for bug in blacklist]))

    ui.pushbuffer()
    _quiet(
        ui, lambda: commands.log(ui,
                                 repo,
                                 rev=['%s:tip' % kwargs['node']],
                                 template='{desc}',
                                 date=None,
                                 user=None,
                                 logfile=None))
    descs = ui.popbuffer()

    searchDescs = bugs.search(descs)
    if searchDescs:
        ui.warn('blacklisted bug found: %s\n' % searchDescs.groups()[0])
        error = True

    return error
Example #13
0
def run(ui, *pats, **opts):
    try:
        path = opts.get('bundle') or paths.find_root()
        repo = hg.repository(ui, path=path)
    except error.RepoError:
        ui.warn(_('No repository found here') + '\n')
        return None

    pats = hglib.canonpaths(pats)
    if opts.get('canonpats'):
        pats = list(pats) + opts['canonpats']

    return visualdiff(ui, repo, pats, opts)
Example #14
0
def security_check(ui, repo, **kwargs):
    ui.debug("running security_check\n")
    error = False

    ui.pushbuffer()
    _quiet(
        ui,
        lambda: commands.log(
            ui, repo, rev=["%s:tip" % kwargs["node"]], template="{node}\n", date=None, user=None, logfile=None
        ),
    )
    nodes = ui.popbuffer().split("\n")

    # reenable this code if we need to blacklist a node
    for node in nodes:
        if node.startswith("8555e8551203") or node.startswith("e09bb3ece6c7"):
            ui.warn("blacklisted changeid found: node %s is blacklisted\n" % node)
            error = True  # fail the push

    # Look for blacklisted bugs
    blacklist = [
        # Serrano
        580489,
        604354,
        # Wasabi
        507624,
        # Cyril
        570049,
        628834,
    ]

    bugs = re.compile("(%s)" % "|".join([str(bug) for bug in blacklist]))

    ui.pushbuffer()
    _quiet(
        ui,
        lambda: commands.log(
            ui, repo, rev=["%s:tip" % kwargs["node"]], template="{desc}", date=None, user=None, logfile=None
        ),
    )
    descs = ui.popbuffer()

    searchDescs = bugs.search(descs)
    if searchDescs:
        ui.warn("blacklisted bug found: %s\n" % searchDescs.groups()[0])
        error = True

    return error
Example #15
0
def _publish(ui, repo, commitlog_path, rebuild=False):
    u"发布一个库至svn"

    # 编译当前库
    publish_path = ui.config("opm", "publish-path")

    if not publish_path:
        ui.warn("%s: no publish path\n" % repo.root)
    else:
        # 编译当前库
        runcmd(ui, repo, "svn update %s --force --accept theirs-full" % publish_path)
        commands.ui.prefix = repo.root + ": "
        commands.ui.fout = ui.fout  # 输入导出到客户端
        commands.publish(repo.root, publish_path, rebuild=rebuild)
        commands.ui.prefix = ""
        runcmd(ui, repo, "svn commit %s -F %s" % (publish_path, commitlog_path), "nothing to commit.")
Example #16
0
def run(ui, repo, **kwargs):
	user_branch = repo['tip'].branch()
	user_changeset = repo.changelog.tip()
	user_name = repo['tip'].user()
	user_repository_url = os.getcwd()
	#rev = repo[None].rev()
	#ui.warn('branch name: %s \n' %(str(user_branch)))
	#ui.warn('changeset: %s \n' %(hex(user_changeset)))
	#ui.warn('user: %s \n' %(user_name))
	#ui.warn('repo_url: %s \n' %(user_repository_url))
	#ui.warn('rev: %s \n' %(str(rev)))
	http = HTTPConnection(hg_server_adress+':'+jenkins_port)
	data = {"user_branch":str(user_branch), "user_changeset":hex(user_changeset),"user_name":user_name,"user_repository_url":"file://"+user_repository_url }
	#ui.warn("http://192.168.19.105:8080/job/Github-test%200.01/buildWithParameters?"+urlencode(data)+'\n')
	http.request("GET",hg_server_adress+':'+jenkins_port+"/job/Github-test%200.01/buildWithParameters?"+urlencode(data)+'\n')
	ui.warn(str(http.getresponse())+'\n')
	return False
Example #17
0
def profile(checkargs):        
    import hotshot, hotshot.stats
    prof = hotshot.Profile("hg.prof")
    try:
        try:
            return prof.runcall(checkargs)            
        except:
            try:
                ui.warn(_('exception raised - generating '
                         'profile anyway\n'))
            except:
                pass
            raise
    finally:
        prof.close()
        stats = hotshot.stats.load("hg.prof")
        stats.strip_dirs()
        stats.sort_stats('cumulative', 'time', 'calls')
        stats.print_stats(40)
Example #18
0
def query(ui, repo, names, match, list_ignored, list_clean, list_unknown=True):
    sock = socket.socket(socket.AF_UNIX)
    sockpath = repo.join('inotify.sock')
    sock.connect(sockpath)

    def genquery():
        for n in names or []:
            yield n
        states = 'almrx!'
        if list_ignored:
            raise ValueError('this is insanity')
        if list_clean: states += 'n'
        if list_unknown: states += '?'
        yield states

    req = '\0'.join(genquery())

    sock.sendall(chr(common.version))
    sock.sendall(req)
    sock.shutdown(socket.SHUT_WR)

    cs = common.recvcs(sock)
    version = ord(cs.read(1))

    if version != common.version:
        ui.warn(_('(inotify: received response from incompatible server '
                  'version %d)\n') % version)
        return None

    try:
        resphdr = struct.unpack(common.resphdrfmt, cs.read(common.resphdrsize))
    except struct.error:
        return None

    def readnames(nbytes):
        if nbytes:
            names = cs.read(nbytes)
            if names:
                return filter(match, names.split('\0'))
        return []

    return map(readnames, resphdr)
Example #19
0
def master_hook(ui, repo, **kwargs):
    ui.debug('running tamarin master_hook\n')
    ui.debug('kwargs: %s\n' % kwargs)
    # The mercurial hook script expects the equivalent of an exit code back from
    # this call:
    #   False = 0 = No Error : allow push
    #   True = 1 = Error : abort push
    error = False
    error = error or diff_check(ui, repo, **kwargs)

    if error:
        # Save the commit message so it can be reused by user
        desc = repo[repo[kwargs['node']].rev()].description()
        ui.debug('Description: %s\n' % desc)
        try:
            f = open('%s/.hg/commit.save' % repo.root, 'w')
            f.write(desc)
            f.close()
            ui.warn('Commit message saved to .hg/commit.save\nSaved message can be recommitted using -l .hg/commit.save\n')
        except IOError:
            ui.warn('Error writing .hg/commit.save file')

    return error
Example #20
0
def check_user_for_valid_email(ui, changeset, operation):
    user = changeset.user()
    ui.debug('\ncheck_user_for_valid_email: %s' % user)
    has_email = has_email_in_brackets(user)
    if not has_email:
        ui.warn('\nUser missing email address for changeset %s: \n  %s\n'
                % (changeset, user))
        response = prompt_yesno(ui, operation)
        if response == 0:
            ui.warn('Aborting %s due to user missing email.\n' % operation)
            return True;
    else:
        has_domain = has_email_with_domain(user)
        if not has_domain:
            ui.warn('\nUser email missing domain for changeset %s: \n  %s\n'
                    % (changeset, user))
            response = prompt_yesno(ui, operation)
            if response == 0:
                ui.warn('Aborting %s due to email without domain.\n' % operation)
                return True;

    return False;
def check_user_for_valid_email(ui, changeset, operation):
    user = changeset.user()
    ui.debug('\ncheck_user_for_valid_email: %s' % user)
    has_email = has_email_in_brackets(user)
    if not has_email:
        ui.warn('\nUser missing email address for changeset %s: \n  %s\n' %
                (changeset, user))
        response = prompt_yesno(ui, operation)
        if response == 0:
            ui.warn('Aborting %s due to user missing email.\n' % operation)
            return True
    else:
        has_domain = has_email_with_domain(user)
        if not has_domain:
            ui.warn('\nUser email missing domain for changeset %s: \n  %s\n' %
                    (changeset, user))
            response = prompt_yesno(ui, operation)
            if response == 0:
                ui.warn('Aborting %s due to email without domain.\n' %
                        operation)
                return True

    return False
Example #22
0
def hook(ui, repo, **kwargs):
    # type: (ui, repo, Optional[Text]) -> None
    """
    Invoked by configuring a [hook] entry in .hg/hgrc.
    """
    hooktype = kwargs["hooktype"]
    node = kwargs["node"]

    ui.debug("Zulip: received {hooktype} event\n".format(hooktype=hooktype))

    if hooktype != "changegroup":
        ui.warn("Zulip: {hooktype} not supported\n".format(hooktype=hooktype))
        exit(1)

    ctx = repo.changectx(node)
    branch = ctx.branch()

    # If `branches` isn't specified, notify on all branches.
    branch_whitelist = get_config(ui, "branches")
    branch_blacklist = get_config(ui, "ignore_branches")

    if branch_whitelist:
        # Only send notifications on branches we are watching.
        watched_branches = [b.lower().strip() for b in branch_whitelist.split(",")]
        if branch.lower() not in watched_branches:
            ui.debug("Zulip: ignoring event for {branch}\n".format(branch=branch))
            exit(0)

    if branch_blacklist:
        # Don't send notifications for branches we've ignored.
        ignored_branches = [b.lower().strip() for b in branch_blacklist.split(",")]
        if branch.lower() in ignored_branches:
            ui.debug("Zulip: ignoring event for {branch}\n".format(branch=branch))
            exit(0)

    # The first and final commits in the changeset.
    base = repo[node].rev()
    tip = len(repo)

    email = get_config(ui, "email")
    api_key = get_config(ui, "api_key")
    site = get_config(ui, "site")

    if not (email and api_key):
        ui.warn("Zulip: missing email or api_key configurations\n")
        ui.warn("in the [zulip] section of your .hg/hgrc.\n")
        exit(1)

    stream = get_config(ui, "stream")
    # Give a default stream if one isn't provided.
    if not stream:
        stream = "commits"

    web_url = get_config(ui, "web_url")
    user = ctx.user()
    content = format_summary_line(web_url, user, base, tip, branch, node)
    content += format_commit_lines(web_url, repo, base, tip)

    subject = branch

    ui.debug("Sending to Zulip:\n")
    ui.debug(content + "\n")

    send_zulip(email, api_key, site, stream, subject, content)
Example #23
0
def thgdispatch(ui, path=None, args=[]):
    '''
    Replicate functionality of mercurial dispatch but force the use
    of the passed in ui for all purposes
    '''
    # read --config before doing anything else
    # (e.g. to change trust settings for reading .hg/hgrc)
    config = _earlygetopt(['--config'], args)
    if config:
        ui.updateopts(config=_parseconfig(config))

    # check for cwd
    cwd = _earlygetopt(['--cwd'], args)
    if cwd:
        os.chdir(cwd[-1])

    # read the local repository .hgrc into a local ui object
    path = rootpath(path) or ""
    if path:
        try:
            ui.readconfig(os.path.join(path, ".hg", "hgrc"))
        except IOError:
            pass

    # now we can expand paths, even ones in .hg/hgrc
    rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
    if rpath:
        path = ui.expandpath(rpath[-1])

    extensions.loadall(ui)
    if not hasattr(extensions, 'extensions'):
        extensions.extensions = lambda: () # pre-0.9.5, loadall did below
    for name, module in extensions.extensions():
        if name in _loaded:
            continue

        # setup extensions
        extsetup = getattr(module, 'extsetup', None)
        if extsetup:
            extsetup()

        cmdtable = getattr(module, 'cmdtable', {})
        overrides = [cmd for cmd in cmdtable if cmd in commands.table]
        if overrides:
            ui.warn(_("extension '%s' overrides commands: %s\n")
                    % (name, " ".join(overrides)))
        commands.table.update(cmdtable)
        _loaded[name] = 1

    # check for fallback encoding
    fallback = ui.config('ui', 'fallbackencoding')
    if fallback:
        util._fallbackencoding = fallback

    fullargs = args
    cmd, func, args, options, cmdoptions = parse(ui, args)

    if options["encoding"]:
        util._encoding = options["encoding"]
    if options["encodingmode"]:
        util._encodingmode = options["encodingmode"]
    ui.updateopts(options["verbose"], options["debug"], options["quiet"],
                 not options["noninteractive"], options["traceback"])

    if options['help']:
        return commands.help_(ui, cmd, options['version'])
    elif options['version']:
        return commands.version_(ui)
    elif not cmd:
        return commands.help_(ui, 'shortlist')

    repo = None
    if cmd not in commands.norepo.split():
        try:
            repo = hg.repository(ui, path=path)
            repo.ui = ui
            ui.setconfig("bundle", "mainreporoot", repo.root)
            if not repo.local():
                raise util.Abort(_("repository '%s' is not local") % path)
        except RepoError:
            if cmd not in commands.optionalrepo.split():
                if not path:
                    raise RepoError(_("There is no Mercurial repository here"
                                         " (.hg not found)"))
                raise
        d = lambda: func(ui, repo, *args, **cmdoptions)
    else:
        d = lambda: func(ui, *args, **cmdoptions)

    # run pre-hook, and abort if it fails
    ret = hook.hook(ui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
    if ret:
        return ret

    # Run actual command
    try:
        ret = d()
    except TypeError, inst:
        # was this an argument error?
        tb = traceback.extract_tb(sys.exc_info()[2])
        if len(tb) != 2: # no
            raise
        raise ParseError(cmd, _("invalid arguments"))
Example #24
0
def review(ui, repo, *dest, **opts):
    """create a code review for some changesets on kiln
    
    Review creates a brand new code review on kiln for a changeset on kiln.
    If no revision is specified, the code review defaults to the most recent
    changeset.
    
    Specify people to peek at your review by passing a comma-separated list
    of people to review your code, by passing multiple -p flags, or both.
      hg review -p tim,alex,ben -p joey
    
    You can specify revisions by passing a hash-range,
      hg review -r 13bs32abc:tip
    or by passing individual changesets
      hg review -r 75c471319a5b -r 41056495619c
    
    Using -e will open up your favorite editor and includes all the changeset
    descriptions for any revisions selected as the code review comment.
    """
    prefix = repo.ui.config("auth","kiln.prefix")
    current_user = repo.ui.config("auth","kiln.username") or repo.ui.config("ui","username")
    if prefix is None:
        ui.warn("In order to work, in your hgrc please set:\n\n")
        ui.warn("[auth]\n")
        ui.warn("kiln.prefix = https://kilnrepo.kilnhg.com\n")
        ui.warn("kiln.username = [email protected]\n")
        ui.warn("kiln.password = keymash\n")
        return 0
    
    review_params = {}
    
    changesets = ['tip']
    if opts.get('revs'):
        revs = opts.get('revs')
        changesets = [repo[rev].hex()[:12] for rev in scmutil.revrange(repo, revs)]
    review_params['revs'] = changesets

    comment = opts.get('comment')
    if opts.get('editor'):
        if opts.get('comment'):
            default_comment = opts['comment']
        else:
            changeset_descs = [repo[rev].description() for rev in changesets]
            default_comment = "\n".join(changeset_descs)
        comment = ui.edit(default_comment, current_user)
    if comment:
        review_params['sDescription'] = comment
    
    if opts.get('title'):
        review_params['sTitle'] = opts.get('title')
    
    token = _token()
    review_params['token'] = token
    
    if dest:
        dest = dest[0]
    rev_repo = _get_user_repos(ui, repo, dest)
    if rev_repo:
        all_repos = _get_kiln_paths(ui, repo, token)
        kiln_repo = all_repos[rev_repo]
        review_params["ixRepo"] = kiln_repo["ixRepo"]

    reviewers = _get_reviewers(ui, repo, token, opts.get('people'))
    review_params['ixReviewers'] = [r['ixPerson'] for r in reviewers]
    
    review_status = _make_review(review_params)
    if review_status:
        ui.status("Review created!\n")
        ui.status("%s/Review/%s" % (prefix, review_status['ixReview']))
        return 1
    else:
        return 0
Example #25
0
def check(ui, repo, node, **kwargs):
    if HOOKS_PATH is None:
        ui.warn(
            "HG_HOOKS_PATH environmental variable isn't set, StyleCop cannot be hooked\n"
            +
            "Go to your \"hooks\" directory and run Initialize.bat to set this variable\n"
        )
        return 0

    #Путь до StyleCopCli. Сейчас он находится в папке с хуком.
    #Если будет смысл в дальнейшем перенести его отдельно - нужно будет сделать новую переменную окружения
    STYLECOP_PATH = HOOKS_PATH + "\\StyleCopCLI"

    #имя файла с выводом StyleCop'а.
    #Инициализируем только после того, как убедились, что HOOKS_PATH не None
    OUT_FILE = HOOKS_PATH + "\\out.xml"

    #Парсим репозитории в файле repositories
    reps = parseRepositories(HOOKS_PATH + "\\" + REPOSITORIES_FILE_NAME)

    #Если нашего репозитория нет в списке - не делаем ничего
    if (reps[repo.root] is None):
        return 0

    #Если репозиторий есть в списке, но проверка синтаксиса отключена -
    #Выводим предупреждение (чтобы не забыли когда-нибудь включить)
    if (reps[repo.root] == "0"):
        ui.warn(
            "StyleCop is disabled for this repository, syntax won't be checked\n"
        )
        return 0

    #Получаем repoContext для нашего коммита. В нём лежит, в частности, список файлов в коммите
    ctx = repo[node]
    #Инициализируем новый set, где будем хранить файлы, которые нужно передать в StyleCop
    fileSet = set()
    #Итерируемся по списку файлов в коммите
    for currentFile in ctx.files():
        #Если это не .cs-файл - пропускаем его (TODO: добавить ещё расширения?)
        if re.match('.+\.cs', currentFile) and currentFile in ctx:
            fileSet.add(currentFile)
    #Если ни одного C#-файла не было изменено - выходим
    if len(fileSet) == 0:
        return 0

    #Подгружаем файл настроек только если он существует
    settingsFile = repo.root + "\Settings.StyleCop"
    settingsString = " -set " + settingsFile if os.path.isfile(
        settingsFile) else ""

    #Инициализируем строку для запуска
    cmd = STYLECOP_PATH + "\\StyleCopCLI.exe -out " + OUT_FILE + settingsString + " -cs \"" + "\", \"".join(
        fileSet) + "\""
    ui.status("[StyleCop]:")
    process = subprocess.Popen(cmd)
    process.wait()
    if process.returncode == 2:
        ui.warn(parseXml(OUT_FILE))
    elif process.returncode == 1:
        ui.warn("Error while executing StyleCop syntax check\n")

    return process.returncode
Example #26
0
        except OSError, err:
            if err.errno not in walk_ignored_errors:
                raise
    for result in walkit(root, reporoot):
        yield result[1:]

def _explain_watch_limit(ui, repo, count):
    path = '/proc/sys/fs/inotify/max_user_watches'
    try:
        limit = int(file(path).read())
    except IOError, err:
        if err.errno != errno.ENOENT:
            raise
        raise util.Abort(_('this system does not seem to '
                           'support inotify'))
    ui.warn(_('*** the current per-user limit on the number '
              'of inotify watches is %s\n') % limit)
    ui.warn(_('*** this limit is too low to watch every '
              'directory in this repository\n'))
    ui.warn(_('*** counting directories: '))
    ndirs = len(list(walkrepodirs(repo)))
    ui.warn(_('found %d\n') % ndirs)
    newlimit = min(limit, 1024)
    while newlimit < ((limit + ndirs) * 1.1):
        newlimit *= 2
    ui.warn(_('*** to raise the limit from %d to %d (run as root):\n') %
            (limit, newlimit))
    ui.warn(_('***  echo %d > %s\n') % (newlimit, path))
    raise util.Abort(_('cannot watch %s until inotify watch limit is raised')
                     % repo.root)

class Watcher(object):
def check_desc_for_bugnum_and_reviews(ui, changeset, operation):
    # Check first line of log of tip changeset; if it appears questionable,
    # prompt the user to confirm that they want to continue the operation.
    desc = changeset.description()
    lines = desc.split('\n')
    first_line = lines[0]
    bug_num = bugzilla_reference(first_line)
    has_review = has_reviewer_notes(first_line)

    if not bug_num or not has_review:
        ui.warn('\nQuestionable log for changeset %s:\n  %s\n' %
                (changeset, first_line))

    if not bug_num:
        ui.warn('Missing bug number, e.g. "Bug NNNNNN: ..."\n')
        response = prompt_yesno(ui, operation)
        if response == 0:
            ui.warn('Aborting %s due to missing bug number.\n' % operation)
            return True
    else:
        bug_type = check_bug_type(bug_num)
        if bug_type == BugType.SECURITY:
            ui.warn('Bug %s is a security bug.' % bug_num)
            response = prompt_yesno(ui, operation)
            if response == 0:
                ui.warn('Aborting %s due to security bug.\n' % operation)
                return True
        elif bug_type == BugType.INVALID:
            ui.warn('Bug %s is a not defined in bugzilla.' % bug_num)
            response = prompt_yesno(ui, operation)
            if response == 0:
                ui.warn('Aborting %s due to invalid bug number.\n' % operation)
                return True

    if not has_review:
        ui.warn('Missing review notes, e.g. "... (r=<name>,sr=<name>)"\n')
        response = prompt_yesno(ui, operation)
        if response == 0:
            ui.warn('Aborting %s due to missing review notes.\n' % operation)
            return True

    return False
Example #28
0
def review(ui, repo, *dest, **opts):
    """create a code review for some changesets on kiln
    
    Review creates a brand new code review on kiln for a changeset on kiln.
    If no revision is specified, the code review defaults to the most recent
    changeset.
    
    Specify people to peek at your review by passing a comma-separated list
    of people to review your code, by passing multiple -p flags, or both.
      hg review -p tim,alex,ben -p joey
    
    You can specify revisions by passing a hash-range,
      hg review -r 13bs32abc:tip
    or by passing individual changesets
      hg review -r 75c471319a5b -r 41056495619c
    
    Using -e will open up your favorite editor and includes all the changeset
    descriptions for any revisions selected as the code review comment.
    """
    prefix = repo.ui.config("auth", "kiln.prefix")
    current_user = repo.ui.config("auth", "kiln.username") or repo.ui.config(
        "ui", "username")
    if prefix is None:
        ui.warn("In order to work, in your hgrc please set:\n\n")
        ui.warn("[auth]\n")
        ui.warn("kiln.prefix = https://kilnrepo.kilnhg.com\n")
        ui.warn("kiln.username = [email protected]\n")
        ui.warn("kiln.password = keymash\n")
        return 0

    review_params = {}

    changesets = ['tip']
    if opts.get('revs'):
        revs = opts.get('revs')
        changesets = [
            repo[rev].hex()[:12] for rev in scmutil.revrange(repo, revs)
        ]
    review_params['revs'] = changesets

    comment = opts.get('comment')
    if opts.get('editor'):
        if opts.get('comment'):
            default_comment = opts['comment']
        else:
            changeset_descs = [repo[rev].description() for rev in changesets]
            default_comment = "\n".join(changeset_descs)
        comment = ui.edit(default_comment, current_user)
    if comment:
        review_params['sDescription'] = comment

    if opts.get('title'):
        review_params['sTitle'] = opts.get('title')

    token = _token()
    review_params['token'] = token

    if dest:
        dest = dest[0]
    rev_repo = _get_user_repos(ui, repo, dest)
    if rev_repo:
        all_repos = _get_kiln_paths(ui, repo, token)
        kiln_repo = all_repos[rev_repo]
        review_params["ixRepo"] = kiln_repo["ixRepo"]

    reviewers = _get_reviewers(ui, repo, token, opts.get('people'))
    review_params['ixReviewers'] = [r['ixPerson'] for r in reviewers]

    review_status = _make_review(review_params)
    if review_status:
        ui.status("Review created!\n")
        ui.status("%s/Review/%s" % (prefix, review_status['ixReview']))
        return 1
    else:
        return 0
Example #29
0
def push_with_review(origfn, ui, repo, *args, **opts):
    """overrides 'hg push' to add creating a code review for the push on kiln.

    Review creates a brand new code review on kiln for a changeset on kiln.
    If no revision is specified, the code review defaults to the most recent
    changeset.

    Specify people to peek at your review by passing a comma-separated list
    of people to review your code, by passing multiple --rr flags, or both.
      hg push --rr tim,alex,ben --rr joey

    You can specify revisions by passing a hash-range,
      hg push --rrev 13bs32abc:tip
    or by passing individual changesets
      hg push --rrev 75c471319a5b --rrev 41056495619c

    Using --reditor will open up your favorite editor and includes all
    the changeset descriptions for any revisions selected as the code
    review comment.

    All the flags supported by 'hg push' are passed through to push.
    """
    # First order of business: If the user passed in --rr none, just
    # fall back onto the native push.
    if opts.get('rr') == ['none']:
        return origfn(ui, repo, *args, **opts)

    # TODO(csilvers): also bypass review if
    #  a) this push is a conflict-free merge push
    #  b) they have a review number in the commit notes (this means
    #     there's already a review for them in kilnhg).

    url_prefix = repo.ui.config('auth', 'kiln.prefix')
    if url_prefix is None:
        ui.warn("In order to work, in your hgrc please set:\n\n")
        ui.warn("[auth]\n")
        ui.warn("kiln.prefix = https://<kilnrepo.kilnhg.com>  # no trailing /\n")
        ui.warn("kiln.username = <username>@<domain.com>\n")
        ui.warn("kiln.password = <password>\n")
        return 0

    # dest is the commandline argument.  At most one should be specified.
    dest = None
    if args:
        if len(args) > 1:
            raise mercurial.util.Abort('At most one dest should be specified.')
        dest = args[0]

    review_params = {}

    auth_token = _get_authtoken(ui)
    review_params['token'] = auth_token

    # -rtitle: title
    title = opts.pop('rtitle', None)
    if title:
        review_params['sTitle'] = title

    # -rcomment: comment
    comment = opts.pop('rcomment', None)
    if comment:
        review_params['sDescription'] = comment

    # -rrev: revs
    revs = opts.pop('rrev', None)
    if revs:
        changesets = [repo[rev].hex()[:12]
                      for rev in mercurial.scmutil.revrange(repo, revs)]
    else:
        # TODO(csilvers): don't use an internal function from hg.
        changeset_nodes = mercurial.hg._outgoing(ui, repo, dest, {})
        if not changeset_nodes:
            raise mercurial.util.Abort('No changesets found to push/review. Use'
                                       ' --rrev to specify changesets manually.')
        changesets = [mercurial.node.hex(n)[:12] for n in changeset_nodes]
    review_params['revs'] = changesets

    # -rr: people
    people = opts.pop('rr', None)
    if not people:
        raise mercurial.util.Abort('Must specify at least one reviewer via --rr.'
                                   '  Pass "--rr none" to bypass review.')
    assert people != ['none']   # should have been checked above
    reviewers = _get_reviewers(ui, auth_token, people)
    review_params['ixReviewers'] = [r['ixPerson'] for r in reviewers]

    # -e: editor
    editor = opts.pop('editor', None)
    if editor:
         # If -rcomment was also specified, default the editor-text to that.
         # Otherwise, use the text from the changesets being reviewed.
         if 'sDescription' in review_params:
             default_comment = review_params['sDescription']
         else:
             changeset_descs = [repo[rev].description() for rev in changesets]
             default_comment = "\n".join(changeset_descs)
         current_user = (repo.ui.config('auth', 'kiln.username') or
                         repo.ui.config('ui', 'username'))
         review_params['sDescription'] = ui.edit(default_comment, current_user)

    repo_url_to_push_to = _get_repo_to_push_to(repo, dest)
    review_params['ixRepo'] = _get_repo_index_for_repo_url(repo, auth_token,
                                                           repo_url_to_push_to)

    # First do the push, then do the review.
    origfn(ui, repo, *args, **opts)

    ui.status('Creating review...')
    review_status = _make_review(review_params)
    assert review_status, 'Kiln API is returning None??'
    if 'ixReview' not in review_status:
        ui.status('FAILED: %s\n' % review_status)
        return 0
    ui.status('done!\n')
    ui.status('%s/Review/%s\n' % (url_prefix, review_status['ixReview']))
    return 1
Example #30
0
def check_desc_for_bugnum_and_reviews(ui, changeset, operation):
    # Check first line of log of tip changeset; if it appears questionable,
    # prompt the user to confirm that they want to continue the operation.
    desc = changeset.description()
    lines = desc.split('\n')
    first_line = lines[0]
    bug_num = bugzilla_reference(first_line)
    has_review = has_reviewer_notes(first_line)

    if not bug_num or not has_review:
        ui.warn('\nQuestionable log for changeset %s:\n  %s\n'
                % (changeset,first_line))

    if not bug_num:
        ui.warn('Missing bug number, e.g. "Bug NNNNNN: ..."\n')
        response = prompt_yesno(ui, operation)
        if response == 0:
            ui.warn('Aborting %s due to missing bug number.\n' % operation)
            return True
    else:
        bug_type = check_bug_type(bug_num)
        if bug_type == BugType.SECURITY:
            ui.warn('Bug %s is a security bug.' % bug_num)
            response = prompt_yesno(ui, operation)
            if response == 0:
                ui.warn('Aborting %s due to security bug.\n' % operation)
                return True
        elif bug_type == BugType.INVALID:
            ui.warn('Bug %s is a not defined in bugzilla.' % bug_num)
            response = prompt_yesno(ui, operation)
            if response == 0:
                ui.warn('Aborting %s due to invalid bug number.\n' % operation)
                return True

    if not has_review:
        ui.warn('Missing review notes, e.g. "... (r=<name>,sr=<name>)"\n')
        response = prompt_yesno(ui, operation)
        if response == 0:
            ui.warn('Aborting %s due to missing review notes.\n' % operation)
            return True

    return False;
def checkChangeCtxDiff(ui, repo, changecontexts, testFunc, testDesc,
                       fileEndings):
    '''Loop through each diff for each change and run the testFunc against each line'''
    ui.debug('Checking %s\n' % testDesc)
    for ctx in changecontexts:
        # Get the diff for each change and file
        for file in [f for f in ctx.files() if f.endswith(fileEndings)]:
            ui.debug('checking change: %s, file: %s\n' %
                     (short(ctx.node()), file))
            fmatch = matchfiles(repo, [file])
            # diff from this nodes parent to current node
            diff = ''.join(
                patch.diff(repo,
                           ctx.parents()[0].node(), ctx.node(),
                           fmatch)).split('\n')
            for i in range(3, len(diff)):  # start checking after diff header
                line = diff[i]
                if line.startswith('@@'):
                    diffLocation = line
                # only check new lines added/modified in the file
                if line.startswith('+'):
                    ui.debug('\nchecking line for %s: %s\n\n' %
                             (testDesc, line))
                    testResult, errorLocation = testFunc(line)
                    if testResult:
                        ui.warn(
                            '\n%s(s) found in %s for rev %s (change %s):\n' %
                            (testDesc, file, ctx.rev(), short(ctx.node())))
                        ui.warn('%s\n' % diffLocation)
                        ui.warn('%s\n' % line)
                        ui.warn(
                            '%s^\n' %
                            (' ' * errorLocation, ))  # show a pointer to error
                        try:
                            response = ui.promptchoice(
                                '(n)o, (y)es, (a)llow %ss for current file\n' %
                                testDesc +
                                'Are you sure you want to commit this change? [n]: ',
                                (('&No'), ('&Yes'), ('&Allow')), 0)
                        except AttributeError:
                            ui.warn(
                                'This commit hook requires that you have mercurial 1.4+ installed.  Please upgrade your hg installation.'
                            )
                            response = 0
                        if response == 1:
                            # next occurance in file
                            continue
                        elif response == 2:
                            # next file
                            break
                        else:
                            ui.warn('Aborting commit due to %s.\n' % testDesc)
                            # error = True
                            return True
    return False
def hook(ui, repo, **kwargs):
    # type: (ui, repo, **Text) -> None
    """
    Invoked by configuring a [hook] entry in .hg/hgrc.
    """
    hooktype = kwargs["hooktype"]
    node = kwargs["node"]

    ui.debug("Zulip: received {hooktype} event\n".format(hooktype=hooktype))

    if hooktype != "changegroup":
        ui.warn("Zulip: {hooktype} not supported\n".format(hooktype=hooktype))
        sys.exit(1)

    ctx = repo.changectx(node)
    branch = ctx.branch()

    # If `branches` isn't specified, notify on all branches.
    branch_whitelist = get_config(ui, "branches")
    branch_blacklist = get_config(ui, "ignore_branches")

    if branch_whitelist:
        # Only send notifications on branches we are watching.
        watched_branches = [
            b.lower().strip() for b in branch_whitelist.split(",")
        ]
        if branch.lower() not in watched_branches:
            ui.debug(
                "Zulip: ignoring event for {branch}\n".format(branch=branch))
            sys.exit(0)

    if branch_blacklist:
        # Don't send notifications for branches we've ignored.
        ignored_branches = [
            b.lower().strip() for b in branch_blacklist.split(",")
        ]
        if branch.lower() in ignored_branches:
            ui.debug(
                "Zulip: ignoring event for {branch}\n".format(branch=branch))
            sys.exit(0)

    # The first and final commits in the changeset.
    base = repo[node].rev()
    tip = len(repo)

    email = get_config(ui, "email")
    api_key = get_config(ui, "api_key")
    site = get_config(ui, "site")

    if not (email and api_key):
        ui.warn("Zulip: missing email or api_key configurations\n")
        ui.warn("in the [zulip] section of your .hg/hgrc.\n")
        sys.exit(1)

    stream = get_config(ui, "stream")
    # Give a default stream if one isn't provided.
    if not stream:
        stream = "commits"

    web_url = get_config(ui, "web_url")
    user = ctx.user()
    content = format_summary_line(web_url, user, base, tip, branch, node)
    content += format_commit_lines(web_url, repo, base, tip)

    subject = branch

    ui.debug("Sending to Zulip:\n")
    ui.debug(content + "\n")

    send_zulip(email, api_key, site, stream, subject, content)
Example #33
0
def checkChangeCtxDiff(ui, repo, changecontexts, testFunc, testDesc, fileEndings):
    '''Loop through each diff for each change and run the testFunc against each line'''
    ui.debug('Checking %s\n' % testDesc)
    for ctx in changecontexts:
        # Get the diff for each change and file
        for file in [f for f in ctx.files() if f.endswith(fileEndings)]:
            ui.debug('checking change: %s, file: %s\n' % (short(ctx.node()), file))
            fmatch = matchfiles(repo,[file])
            # diff from this nodes parent to current node
            diff = ''.join(patch.diff(repo, ctx.parents()[0].node(), ctx.node(), fmatch)).split('\n')
            for i in range(3, len(diff)):    # start checking after diff header
                line = diff[i]
                if line.startswith('@@'):
                    diffLocation = line
                # only check new lines added/modified in the file
                if line.startswith('+'):
                    ui.debug('\nchecking line for %s: %s\n\n' % (testDesc, line))
                    testResult, errorLocation = testFunc(line)
                    if testResult:
                        ui.warn('\n%s(s) found in %s for rev %s (change %s):\n' %
                                (testDesc, file, ctx.rev(), short(ctx.node())))
                        ui.warn('%s\n' % diffLocation)
                        ui.warn('%s\n' % line)
                        ui.warn('%s^\n' % (' '*errorLocation,)) # show a pointer to error
                        try:
                            response = ui.promptchoice('(n)o, (y)es, (a)llow %ss for current file\n' % testDesc +
                                                    'Are you sure you want to commit this change? [n]: ' ,
                                                   (('&No'), ('&Yes'), ('&Allow')), 0)
                        except AttributeError:
                            ui.warn('This commit hook requires that you have mercurial 1.4+ installed.  Please upgrade your hg installation.')
                            response = 0
                        if response == 1:
                            # next occurance in file
                            continue
                        elif response == 2:
                            # next file
                            break
                        else:
                            ui.warn('Aborting commit due to %s.\n' % testDesc)
                            # error = True
                            return True
    return False