在 bitbucket 多个存储库中搜索并替换为提交

问题描述

有没有办法使用 Bitbucket 管理工具/API/UI 在某个项目下的 Bitbucket git 存储库中搜索和替换某些字符串?修改应该通过 git commit 进行。

我想到的唯一方法是构建一些脚本来遍历所有存储库。

解决方法

我不得不做这样的手术。当我们从 svn 迁移到 git 时,我们不得不更改我们 pom.xml 中的 scm developerConnection:

<developerConnection>scm:git:git@github.com:codehaus-plexus/plexus-interpolation.git</developerConnection>

在我们从 svn 开发人员连接到 git 的所有 git 存储库中。这是我使用的脚本:

#!/usr/bin/python

import stashy
import os
import sys
import urllib2
import json
import base64
import getpass
from git import Repo
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element
from lxml import etree
import itertools
import logging

logging.basicConfig(level=logging.INFO,format='%(asctime)s %(levelname)s %(message)s')
bitbucketBaseUrl = "https://bitbucket.company.com"
bitbucketUserName = "admin"


class BitBucketRepo:
    def __init__(self,name,repoUrl):
        self.name = name
        self.repoUrl = repoUrl


class CommentedTreeBuilder(ET.TreeBuilder):
    def __init__(self,*args,**kwargs):
        super(CommentedTreeBuilder,self).__init__(*args,**kwargs)

    def comment(self,data):
        self.start(ET.Comment,{})
        self.data(data)
        self.end(ET.Comment)


def insert(originalfile,string):
    with open(originalfile,'r') as f:
        with open('pom.xml.bak','w') as f2:
            f2.write(string + "\n")
            f2.write(f.read())
    os.rename('pom.xml.bak',originalfile)


def validateScriptParameters():
    if len(sys.argv) != 3:
        sys.exit("Usage: {} [Bit Bucket Module Project key,e.g. mf for Modules - Framework] [Bit Bucket admin password]".format(
            os.path.basename(sys.argv[0])))


def cloneRepo(repository):
    logging.info("Cloning repo [{}]".format(repository.repoUrl))
    repo = Repo.clone_from(repository.repoUrl,repository.name)
    return repo


def updatePomFile(repository):
    resultCode = 1
    ET.register_namespace('xsi',"http://www.w3.org/2001/XMLSchema-instance")
    ET.register_namespace('',"http://maven.apache.org/POM/4.0.0")
    cparser = ET.XMLParser(target = CommentedTreeBuilder())
    if os.path.isfile(os.getcwd() + "/" + repository.name + "/pom.xml"):
        tree = ET.parse(repository.name + "/pom.xml",parser=cparser)
        root = tree.getroot()

        ns = {'nodes': 'http://maven.apache.org/POM/4.0.0'}

        for scm in root.findall('nodes:scm',ns):
            if scm is not None:
                developerConnection = scm.find('nodes:developerConnection',ns)
                scm.remove(developerConnection)
                newDeveloperConnectionElm = Element("developerConnection")
                newDeveloperConnectionElm.tail = "\n\t"
                newDeveloperConnectionElm.text = str("scm:git:" + repository.repoUrl)
                scm.append(newDeveloperConnectionElm)
                resultCode = 0
            else:
                resultCode = 1

        if resultCode == 0:
            logging.info("Updating repository: " + repository.name)
            tree.write(repository.name + "/pom.xml")

    return resultCode


def updateRepo(bitbucket,projectKey):
    xmlVersion = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    repoList = bitbucket.projects[projectKey].repos

    for repoItem in repoList:
        cloneUrl = repoItem['links']['clone'][1]['href']

        if cloneUrl.startswith("http"):
           cloneUrl = repoItem['links']['clone'][0]['href']
        if not cloneUrl.startswith("ssh"):
           logging.error("Unable to retrieve valid clone url [{}],exiting...".format(cloneUrl))
           sys.exit(1)

        repository = BitBucketRepo(repoItem['name'],cloneUrl)
        clonedRepo = cloneRepo(repository)
        resultCode = updatePomFile(repository)
        if resultCode == 0:
             insert(repository.name + "/pom.xml",xmlVersion)
             clonedRepo.index.add([os.getcwd() + "/" + repository.name + "/pom.xml"])
             clonedRepo.index.commit("CM-8991: Updating pom.xml to use git connection string instead of svn")
             clonedRepo.remotes.origin.push()


validateScriptParameters()
logging.info('Bit Bucket URL [' + bitbucketBaseUrl + ']')
logging.info('User name [' + bitbucketUserName + ']')

projectKey = sys.argv[1]
bitbucketPassword = sys.argv[2]

bitbucket = stashy.connect(bitbucketBaseUrl,bitbucketUserName,bitbucketPassword)
logging.info("Module project key: [{}]".format(projectKey))

updateRepo(bitbucket,projectKey)

请注意,它需要 'stashy' python 库,并且是为 python2 编写的。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...