def test_fuerte_package_repository(directory=None): """ Release a single catkin stack (fuerte) repository. """ directory = directory if directory is not None else os.getcwd() # Setup upstream_url = create_upstream_catkin_fuerte_repository('foo', directory) release_url = create_release_repo(upstream_url, 'git', 'fuerte_devel') release_dir = os.path.join(directory, 'foo_release_clone') release_client = VcsClient('git', release_dir) release_client.checkout(release_url) with change_directory(release_dir): ### ### Import upstream ### user('git-bloom-import-upstream --quiet') # does the upstream branch exist? assert branch_exists('upstream', local_only=True), "no upstream branch" # does the upstrea/0.1.0 tag exist? ret, out, err = user('git tag', return_io=True) assert out.count('upstream/0.1.0') == 1, "no upstream tag created" # Is the package.xml from upstream in the upstream branch now? with inbranch('upstream'): assert os.path.exists('stack.xml'), \ "upstream did not import: '" + os.getcwd() + "': " + \ str(os.listdir(os.getcwd())) assert open('stack.xml').read().count('0.1.0'), "not right file" ### ### Release generator ### with bloom_answer(bloom_answer.ASSERT_NO_QUESTION): ret = user('git-bloom-generate -y release -s upstream --quiet') # patch import should have reported OK assert ret == code.OK, "actually returned ({0})".format(ret) # do the proper branches exist? assert branch_exists('release/foo'), "no release/foo branch: " + \ str(get_branches()) assert branch_exists('patches/release/foo'), \ "no patches/release/foo branch" # was the release tag created? ret, out, err = user('git tag', return_io=True) assert out.count('release/foo/0.1.0') == 1, "no release tag created" ### ### Release generator, again ### with bloom_answer(bloom_answer.ASSERT_NO_QUESTION): ret = user('git-bloom-generate -y release -s upstream --quiet') # patch import should have reported OK assert ret == code.OK, "actually returned ({0})".format(ret) # do the proper branches exist? assert branch_exists('release/foo'), "no release/foo branch: " + \ str(get_branches()) assert branch_exists('patches/release/foo'), \ "no patches/release/foo branch" # was the release tag created? ret, out, err = user('git tag', return_io=True) assert out.count('release/foo/0.1.0') == 1, "no release tag created"
def match_branches_with_prefix(prefix, get_branches): debug("match_branches_with_prefix(" + str(prefix) + ", " + str(get_branches()) + ")") branches = [] # Match branches existing_branches = get_branches() for branch in existing_branches: if branch.startswith('remotes/origin/'): branch = branch.split('/', 2)[-1] if branch.startswith(prefix): branches.append(branch) return list(set(branches))
def match_branches_with_prefix(prefix, get_branches, prune=False): debug("match_branches_with_prefix(" + str(prefix) + ", " + str(get_branches()) + ")") branches = [] # Match branches existing_branches = get_branches() for branch in existing_branches: if branch.startswith('remotes/origin/'): branch = branch.split('/', 2)[-1] if branch.startswith(prefix): branches.append(branch) branches = list(set(branches)) if prune: # Prune listed branches by packages in latest upstream with inbranch('upstream'): pkg_names, version, pkgs_dict = get_package_data('upstream') for branch in branches: if branch.split(prefix)[-1].strip('/') not in pkg_names: branches.remove(branch) return branches
def open_pull_request(track, repository, distro): # Get the diff release_file = get_release_file(distro) if repository in release_file.repositories: orig_version = release_file.repositories[repository].version else: orig_version = None updated_release_file = generate_ros_distro_diff(track, repository, distro) if updated_release_file is None: # There were no changes, no pull request required return None version = updated_release_file.repositories[repository].version updated_distro_file = yaml_from_release_file(updated_release_file) # Determine if the distro file is hosted on github... gh_org, gh_repo, gh_branch, gh_path = get_gh_info(get_release_file_url(distro)) if None in [gh_org, gh_repo, gh_branch, gh_path]: warning("Automated pull request only available via github.com") return # Get the github user name gh_username = None bloom_user_path = os.path.join(os.path.expanduser("~"), ".bloom_user") if os.path.exists(bloom_user_path): with open(bloom_user_path, "r") as f: gh_username = f.read().strip() gh_username = gh_username or getpass.getuser() response = raw_input("github user name [{0}]: ".format(gh_username)) if response: gh_username = response info("Would you like bloom to store your github user name (~/.bloom_user)?") if maybe_continue(): with open(bloom_user_path, "w") as f: f.write(gh_username) else: with open(bloom_user_path, "w") as f: f.write(" ") warning("If you want to have bloom store it in the future remove the ~/.bloom_user file.") # Get the github password gh_password = getpass.getpass("github password (This is not stored):") if not gh_password or not gh_username: error("Either the github username or github password is not set.") warning("Skipping the pull request...") return # Check for fork info(fmt("@{bf}@!==> @|@!Checking for rosdistro fork on github...")) gh_user_repos = fetch_github_api("https://api.github.com/users/{0}/repos".format(gh_username), use_pagination=True) if gh_user_repos is None: error("Failed to get a list of repositories for user: '******'".format(gh_username)) warning("Skipping the pull request...") return if "rosdistro" not in [x["name"] for x in gh_user_repos if "name" in x]: warning( "Github user '{0}' does not have a fork ".format(gh_username) + "of the {0}:{1} repository, create one?".format(gh_org, gh_repo) ) if not maybe_continue(): warning("Skipping the pull request...") return # Create a fork create_fork(gh_org, gh_repo, gh_username, gh_password) # Clone the fork info(fmt("@{bf}@!==> @|@!" + "Cloning {0}/{1}...".format(gh_username, gh_repo))) temp_dir = tempfile.mkdtemp() new_branch = None title = "{0}: {1} in '{2}' [bloom]".format(repository, version, gh_path) body = """\ Increasing version of package(s) in repository `{0}`: - previous version: `{1}` - new version: `{2}` - distro file: `{3}` - bloom version: `{4}` """.format( repository, orig_version or "null", version, gh_path, bloom.__version__ ) with change_directory(temp_dir): def _my_run(cmd): info(fmt("@{bf}@!==> @|@!" + str(cmd))) # out = check_output(cmd, stderr=subprocess.STDOUT, shell=True) out = None from subprocess import call call(cmd, shell=True) if out: info(out, use_prefix=False) _my_run("git clone https://github.com/{0}/{1}.git".format(gh_username, gh_repo)) with change_directory(gh_repo): _my_run("git remote add bloom https://github.com/{0}/{1}.git".format(gh_org, gh_repo)) _my_run("git remote update") _my_run("git fetch") track_branches() branches = get_branches() new_branch = "bloom-{repository}-{count}" count = 0 while new_branch.format(repository=repository, count=count) in branches: count += 1 new_branch = new_branch.format(repository=repository, count=count) # Final check info(fmt("@{cf}Pull Request Title: @{yf}" + title)) info(fmt("@{cf}Pull Request Body : \n@{yf}" + body)) msg = fmt( "@!Open a @|@{cf}pull request@| @!@{kf}from@| @!'@|@!@{bf}" + "{gh_username}/{gh_repo}:{new_branch}".format(**locals()) + "@|@!' @!@{kf}into@| @!'@|@!@{bf}" + "{gh_org}/{gh_repo}:{gh_branch}".format(**locals()) + "@|@!'?" ) info(msg) if not maybe_continue(): warning("Skipping the pull request...") return _my_run("git checkout -b {0} bloom/{1}".format(new_branch, gh_branch)) with open("{0}".format(gh_path), "w") as f: info(fmt("@{bf}@!==> @|@!Writing new distribution file: ") + str(gh_path)) f.write(updated_distro_file) _my_run("git add {0}".format(gh_path)) _my_run('git commit -m "{0}"'.format(title)) _my_run("git push origin {0}".format(new_branch)) # Open the pull request return create_pull_request(gh_org, gh_repo, gh_username, gh_password, gh_branch, new_branch, title, body)
def open_pull_request(track, repository, distro, distro_file_url=ROS_DISTRO_FILE): # Get the diff distro_file_url = distro_file_url.format(distro) distro_file_raw = fetch_distro_file(distro_file_url) distro_file = yaml.load(distro_file_raw) if repository in distro_file['repositories']: orig_version = distro_file['repositories'][repository].get('version', None) else: orig_version = None udiff_patch_file, updated_distro_file = generate_ros_distro_diff(track, repository, distro, distro_file_url, distro_file, distro_file_raw) if None in [udiff_patch_file, updated_distro_file]: # There were no changes, no pull request required return None version = distro_file['repositories'][repository]['version'] # Determine if the distro file is hosted on github... distro_file_url = distro_file_url.format(distro) gh_org, gh_repo, gh_branch, gh_path = get_gh_info(distro_file_url) if None in [gh_org, gh_repo, gh_branch, gh_path]: warning("Automated pull request only available via github.com") return # Determine if we have a .netrc file gh_username = None try: netrc_hosts = netrc.netrc().hosts except Exception as e: error("Failed to parse ~/.netrc file: {0}".format(e)) warning("Skipping the pull request...") return for host in netrc_hosts.keys(): if 'github.com' in host: gh_username = netrc_hosts[host][0] gh_password = netrc_hosts[host][2] if None in [gh_username, gh_password]: error("Either the github username or github password is not set in the ~/.netrc file.") warning("Skipping the pull request...") return # Check for fork info(fmt("@{bf}@!==> @|@!Checking for rosdistro fork on github...")) gh_user_repos = fetch_github_api('https://api.github.com/users/{0}/repos'.format(gh_username)) if gh_user_repos is None: error("Failed to get a list of repositories for user: '******'".format(gh_username)) warning("Skipping the pull request...") return if 'rosdistro' not in [x['name'] for x in gh_user_repos if 'name' in x]: warning("Github user '{0}' does not have a fork ".format(gh_username) + "of the {0}:{1} repository, create one?".format(gh_org, gh_repo)) if not maybe_continue(): warning("Skipping the pull request...") return # Create a fork create_fork(gh_org, gh_repo, gh_username, gh_password) # Clone the fork info(fmt("@{bf}@!==> @|@!" + "Cloning {0}/{1}...".format(gh_username, gh_repo))) temp_dir = tempfile.mkdtemp() new_branch = None title = "{0}: {1} in '{2}' [bloom]".format(repository, version, os.path.basename(gh_path)) body = """\ Increasing version of package(s) in repository `{0}`: - previous version: `{1}` - new version: `{2}` - distro file: `{3}` - bloom version: `{4}` """.format(repository, orig_version or 'null', version, gh_path, bloom.__version__) with change_directory(temp_dir): def _my_run(cmd): info(fmt("@{bf}@!==> @|@!" + str(cmd))) out = check_output(cmd, stderr=subprocess.STDOUT, shell=True) if out: info(out, use_prefix=False) _my_run('git clone https://github.com/{0}/{1}.git'.format(gh_username, gh_repo)) with change_directory(gh_repo): _my_run('git remote add bloom https://github.com/{0}/{1}.git'.format(gh_org, gh_repo)) _my_run('git remote update') _my_run('git fetch') track_branches() branches = get_branches() new_branch = 'bloom-patch-{0}' count = 0 while new_branch.format(count) in branches: count += 1 new_branch = new_branch.format(count) # Final check info(fmt("@{cf}Pull Request Title: @{yf}" + title)) info(fmt("@{cf}Pull Request Body : \n@{yf}" + body)) msg = fmt("@!Open a @|@{cf}pull request@| @!@{kf}from@| @!'@|@!@{bf}" + "{gh_username}/{gh_repo}:{new_branch}".format(**locals()) + "@|@!' @!@{kf}into@| @!'@|@!@{bf}" + "{gh_org}/{gh_repo}:{gh_branch}".format(**locals()) + "@|@!'?") info(msg) if not maybe_continue(): warning("Skipping the pull request...") return _my_run('git checkout -b {0} bloom/{1}'.format(new_branch, gh_branch)) with open('{0}'.format(gh_path), 'w') as f: info(fmt("@{bf}@!==> @|@!Writing new distribution file: ") + str(gh_path)) f.write(updated_distro_file) _my_run('git add {0}'.format(gh_path)) _my_run('git commit -m "{0}"'.format(title)) _my_run('git push origin {0}'.format(new_branch)) # Open the pull request return create_pull_request(gh_org, gh_repo, gh_username, gh_password, gh_branch, new_branch, title, body)
def open_pull_request(track, repository, distro): # Get the diff release_file = get_release_file(distro) if repository in release_file.repositories: orig_version = release_file.repositories[repository].version else: orig_version = None updated_release_file = generate_ros_distro_diff(track, repository, distro) if updated_release_file is None: # There were no changes, no pull request required return None version = updated_release_file.repositories[repository].version updated_distro_file = yaml_from_release_file(updated_release_file) # Determine if the distro file is hosted on github... gh_org, gh_repo, gh_branch, gh_path = get_gh_info( get_release_file_url(distro)) if None in [gh_org, gh_repo, gh_branch, gh_path]: warning("Automated pull request only available via github.com") return # Get the github user name gh_username = None bloom_user_path = os.path.join(os.path.expanduser('~'), '.bloom_user') if os.path.exists(bloom_user_path): with open(bloom_user_path, 'r') as f: gh_username = f.read().strip() gh_username = gh_username or getpass.getuser() response = raw_input("github user name [{0}]: ".format(gh_username)) if response: gh_username = response info( "Would you like bloom to store your github user name (~/.bloom_user)?" ) if maybe_continue(): with open(bloom_user_path, 'w') as f: f.write(gh_username) else: with open(bloom_user_path, 'w') as f: f.write(' ') warning( "If you want to have bloom store it in the future remove the ~/.bloom_user file." ) # Get the github password gh_password = getpass.getpass("github password (This is not stored):") if not gh_password or not gh_username: error("Either the github username or github password is not set.") warning("Skipping the pull request...") return # Check for fork info(fmt("@{bf}@!==> @|@!Checking for rosdistro fork on github...")) gh_user_repos = fetch_github_api( 'https://api.github.com/users/{0}/repos'.format(gh_username), use_pagination=True) if gh_user_repos is None: error("Failed to get a list of repositories for user: '******'".format( gh_username)) warning("Skipping the pull request...") return if 'rosdistro' not in [x['name'] for x in gh_user_repos if 'name' in x]: warning( "Github user '{0}' does not have a fork ".format(gh_username) + "of the {0}:{1} repository, create one?".format(gh_org, gh_repo)) if not maybe_continue(): warning("Skipping the pull request...") return # Create a fork create_fork(gh_org, gh_repo, gh_username, gh_password) # Clone the fork info( fmt("@{bf}@!==> @|@!" + "Cloning {0}/{1}...".format(gh_username, gh_repo))) temp_dir = tempfile.mkdtemp() new_branch = None title = "{0}: {1} in '{2}' [bloom]".format(repository, version, gh_path) body = """\ Increasing version of package(s) in repository `{0}`: - previous version: `{1}` - new version: `{2}` - distro file: `{3}` - bloom version: `{4}` """.format(repository, orig_version or 'null', version, gh_path, bloom.__version__) with change_directory(temp_dir): def _my_run(cmd): info(fmt("@{bf}@!==> @|@!" + str(cmd))) # out = check_output(cmd, stderr=subprocess.STDOUT, shell=True) out = None from subprocess import call call(cmd, shell=True) if out: info(out, use_prefix=False) _my_run('git clone https://github.com/{0}/{1}.git'.format( gh_username, gh_repo)) with change_directory(gh_repo): _my_run( 'git remote add bloom https://github.com/{0}/{1}.git'.format( gh_org, gh_repo)) _my_run('git remote update') _my_run('git fetch') track_branches() branches = get_branches() new_branch = 'bloom-{repository}-{count}' count = 0 while new_branch.format(repository=repository, count=count) in branches: count += 1 new_branch = new_branch.format(repository=repository, count=count) # Final check info(fmt("@{cf}Pull Request Title: @{yf}" + title)) info(fmt("@{cf}Pull Request Body : \n@{yf}" + body)) msg = fmt( "@!Open a @|@{cf}pull request@| @!@{kf}from@| @!'@|@!@{bf}" + "{gh_username}/{gh_repo}:{new_branch}".format(**locals()) + "@|@!' @!@{kf}into@| @!'@|@!@{bf}" + "{gh_org}/{gh_repo}:{gh_branch}".format(**locals()) + "@|@!'?") info(msg) if not maybe_continue(): warning("Skipping the pull request...") return _my_run('git checkout -b {0} bloom/{1}'.format( new_branch, gh_branch)) with open('{0}'.format(gh_path), 'w') as f: info( fmt("@{bf}@!==> @|@!Writing new distribution file: ") + str(gh_path)) f.write(updated_distro_file) _my_run('git add {0}'.format(gh_path)) _my_run('git commit -m "{0}"'.format(title)) _my_run('git push origin {0}'.format(new_branch)) # Open the pull request return create_pull_request(gh_org, gh_repo, gh_username, gh_password, gh_branch, new_branch, title, body)