def AddSource(args): if len(args) < 2 or args[0][0] == "-" or args[1][0] == "-": print("ERROR in addsource: Invalid arguments specified. See 'ughub help addsource'.") return name = args[0] url = args[1] sources = LoadSources() branch = ughubUtil.GetCommandlineOptionValue(args, ("-b", "--branch")) or "master" newSource = { "name": name, "url": url, "branch": branch} for s in sources: if s["name"] == name: print("ERROR in addsource: A source with name '{0}' exists already".format(name)) return try: UpdateSource(newSource) except InvalidSourceError as e: print("WARNING: Requested source was not added due to errors:") PrintSource(newSource) raise e sources.append(newSource) WriteSources(sources) print("The following source was added at rank {0}:".format(len(sources))) PrintSource(newSource)
def LoadFilteredPackageDescs(args): categories = [] matchAll = ughubUtil.HasCommandlineOption(args, ("-a", "--matchall")) installed = ughubUtil.HasCommandlineOption(args, ("-i", "--installed")) notinstalled = ughubUtil.HasCommandlineOption(args, ("-n", "--notinstalled")) sourceName = ughubUtil.GetCommandlineOptionValue(args, ("-s", "--source")) for arg in args: if arg[0] != "-": categories.append(arg) else: break try: allPackages = LoadPackageDescs(sourceName) if len(allPackages) == 0: return allPackages packages = [] # select according to installed/notinstalled if installed and notinstalled: print("Cannot use --installed and --notinstalled simultaneously.") raise Exception() if installed: for pkg in allPackages: if PackageIsInstalled(pkg): packages.append(pkg) if notinstalled: for pkg in allPackages: if not PackageIsInstalled(pkg): packages.append(pkg) if not installed and not notinstalled: for pkg in allPackages: packages.append(pkg) # select according to category if matchAll: packages = FilterPackagesAll(packages, categories) elif len(categories) > 0: packages = FilterPackagesAny(packages, categories) return packages except LookupError as e: raise InvalidPackageError(e)
def InstallAllPackages(args): source = ughubUtil.GetCommandlineOptionValue(args, ("-s", "--source")) packages = LoadFilteredPackageDescs(args) names = [] for pkg in packages: names.append(pkg["name"]) isOption = False for arg in args: if isOption or arg[0] == "-": isOption = True names.append(arg) InstallPackage(names)
def GenerateProjectFiles(args): options = [] for i in range(len(args)): if args[i][0] == "-": options = args[i:] args = args[0:i] break if len(args) < 1: raise ArgumentError("Please specify a TARGET.") name = ughubUtil.GetCommandlineOptionValue(args, ("-n", "--name")) overwriteFiles = ughubUtil.HasCommandlineOption(options, ("-o", "--overwrite")) deleteFiles = ughubUtil.HasCommandlineOption(options, ("-d", "--delete")) if deleteFiles: ughubProjectFileGenerator.RemoveFiles(GetRootDirectory(), args[0]) else: ughubProjectFileGenerator.Run(GetRootDirectory(), args[0], name, overwriteFiles)
def InstallPackage(args): packageNames = args options = [] for i in range(len(args)): if args[i][0] == "-": packageNames = args[0:i] options = args[i:] break if len(packageNames) == 0: print("Please specify a package name. See 'ughub help install'.") return dryRun = ughubUtil.HasCommandlineOption(options, ("-d", "--dry")) force = ughubUtil.HasCommandlineOption(options, ("-f", "--force")) resolve = ughubUtil.HasCommandlineOption(options, ("-r", "--resolve")) branch = ughubUtil.GetCommandlineOptionValue(options, ("-b", "--branch")) source = ughubUtil.GetCommandlineOptionValue(options, ("-s", "--source")) packages = LoadPackageDescs() rootDir = GetRootDirectory() requiredPackages = [] processedPackageBranchPairs = [] for packageName in packageNames: requiredPackages = requiredPackages + BuildPackageDependencyList(packageName, packages, source, branch, processedPackageBranchPairs) print("List of required packages:") #0: Message, 1: Package name, 2: current remote, 3: required remote textRemoteConflictUF = ("" "{0}: Url of remote 'origin' of package '{1}' does not correspond\n" " to the current source-definition:\n" " currentt URL: '{2}'\n" " expected URL: '{3}'\n" " This is most likely a result of an updated source-definition (e.g. through 'ughub updatesources').") #0: required remote, 2: package-path textRemoteConflictOptionsUF = ("" " You may\n" " - call 'ughub install ...' with the '--resolve' option to resolve conflicts on the fly.\n" " - manually adjust the url by executing\n" " 'git remote set-url origin {0}'\n" " at '{1}'\n" " - call 'ughub install ...' with the '--force' option to force installation despite this\n" " error. This may result in an outdated package and build conflicts!") #0: Message, 1: Package name, 2: current branch, 3: required branch textBranchConflictUF = ("" "{0}: Current branch '{2}' of installed package '{1}'\n" " does not correspond to the required branch '{3}'.") #0: required branch, 2: package-path textBranchConflictOptionsUF = ("" " You may\n" " - call 'ughub install' with the '--resolve' option to automatically resolve the conflict\n" " (a checkout of the required branch will be performed).\n" " - manually check out the required branch by executing\n" " git checkout {0}\n" " at '{1}'\n" " - call 'ughub install' with the '--force' option to ignore the error. This may lead to build problems!\n") # iterate over all required packages. Check for each whether it already # exists and whether the branch matches. # If it doesn't exist, perform a fresh clone. # If it does exist and branches match, perform a pull. # If it does exist but branches mismatch, perform a pull if --force was specified # and abort with a warning if it wasn't specified. firstPkg = True problemsOccurred = False for pkg in requiredPackages: if not firstPkg: print("") firstPkg = False print(ShortPackageInfo(pkg)) # check whether the package is already installed if pkg["repoType"] == "git": prefixPath = os.path.join(rootDir, pkg["prefix"]) pkgPath = os.path.join(prefixPath, pkg["name"]) if os.path.isdir(os.path.join(pkgPath, ".git")): # The package exists. validate its origin. fetchURL, pushURL = GetCurrentRemoteGitURLs(pkg) if fetchURL != pkg["url"] or pushURL != pkg["url"]: if fetchURL != pkg["url"]: wrongURL = fetchURL if pushURL != pkg["url"]: wrongURL = pushURL problemsOccurred = True if resolve: print(textRemoteConflictUF.format("NOTE", pkg["name"], wrongURL, pkg["url"])) print("The remote will be automatically adjusted (--resolve)") if not dryRun: proc = subprocess.Popen(["git","remote","set-url","origin", pkg["url"]], cwd = pkgPath) if proc.wait() != 0: raise TransactionError("Couldn't set url '{0}' of remote 'origin' for package '{1}' at '{2}'" .format(pkg["url"], pkg["name"], pkgPath)) elif force: print(textRemoteConflictUF.format("WARNING", pkg["name"], wrongURL, pkg["url"])) print("The warning will be ignored (--force). This may result in an outdated package and build conflicts!") else: text = textRemoteConflictUF.format("ERROR", pkg["name"], wrongURL, pkg["url"]) + "\n" + textRemoteConflictOptionsUF.format(pkg["url"], pkgPath) if dryRun: print(text) else: raise DependencyError(text) # Validate branch p = subprocess.Popen("git branch".split(), cwd = pkgPath, stdout=subprocess.PIPE) gitLog = p.communicate()[0].decode("utf-8") if p.returncode != 0: raise TransactionError("Couldn't access branch information of package '{0}' at '{1}'" .format(pkg["name"], pkgPath)) curBranch = None for line in gitLog.splitlines(): if line[0] == "*": curBranch = line.split()[1] break if curBranch != pkg["__BRANCH"]: problemsOccurred = True if resolve: print(textBranchConflictUF.format("NOTE", pkg["name"], curBranch, pkg["__BRANCH"])) print("The required branch will be automatically checked out (--resolve)") if not dryRun: proc = subprocess.Popen(["git", "checkout", pkg["__BRANCH"]], cwd = pkgPath) if proc.wait() != 0: raise TransactionError("Trying to resolve branch conflict but couldn't check " "out branch '{0}' of package '{1}' at '{2}'" .format(pkg["__BRANCH"], pkg["name"], pkgPath)) elif force: print(textBranchConflictUF.format("WARNING", pkg["name"], curBranch, pkg["__BRANCH"])) print("The warning will be ignored (--force). This may result in build problems!") else: text = textBranchConflictUF.format("ERROR", pkg["name"], curBranch, pkg["__BRANCH"]) + "\n" + textBranchConflictOptionsUF.format(pkg["__BRANCH"], pkgPath) if dryRun: print(text) else: raise DependencyError(text) # if dryRun: # if resolve: # print("NOTE: Branch '{0}' of package '{2}' at '{3}'\n" # " will be replaced by branch '{1}' (--resove)" # .format(curBranch, pkg["__BRANCH"], pkg["name"], pkgPath)) # elif force: # print("WARNING: Branch conflict between current branch '{0}' and required\n" # "branch '{1}' of package '{2}' at '{3}' will be ignored (--force)." # .format(curBranch, pkg["__BRANCH"], pkg["name"], pkgPath)) # else: # problemsOccurred = True # print("ERROR: Current branch '{0}' and required branch '{1}'\n" # " do not match for package '{2}' at '{3}'.\n" # " - Call 'ughub install' with the '--resolve' option to force a checkout of the required branch.\n" # " - Call 'ughub install' with the '--force' option to ignore the error. This may lead to build problems!\n" # .format(curBranch, pkg["__BRANCH"], pkg["name"], pkgPath))) # else: # if resolve: # proc = subprocess.Popen(["git", "checkout", pkg["__BRANCH"]], cwd = pkgPath) # if proc.wait() != 0: # raise TransactionError("Trying to resolve branch conflict but couldn't check " # "out branch '{0}' of package '{1}' at '{2}'" # .format(pkg["__BRANCH"], pkg["name"], pkgPath)) # print("Resolved branch conflict by switching from branch '{0}'\n" # "to branch '{1}' of package '{2}' at '{3}' (--resolve)" # .format(curBranch, pkg["__BRANCH"], pkg["name"], pkgPath)) # elif force: # print("WARNING: Ignoring branch conflict between current branch '{0}'\n" # "and required branch '{1}' of package '{2}' at '{3}' (--force)" # .format(curBranch, pkg["__BRANCH"], pkg["name"], pkgPath)) # else: # raise DependencyError( # "Current branch '{0}' and required branch '{1}'\n" # " do not match for package '{2}' at '{3}'.\n" # " - Call 'ughub install' with the '--resolve' option to force a checkout of the required branch.\n" # " - Call 'ughub install' with the '--force' option to ignore the error. This may lead to build problems!\n" # .format(curBranch, pkg["__BRANCH"], pkg["name"], pkgPath)) if not dryRun: proc = subprocess.Popen(["git", "pull"], cwd = pkgPath) if proc.wait() != 0: raise TransactionError("Couldn't pull for package '{0}' at '{1}'" .format(pkg["name"], pkgPath)) else: # the package doesn't exist yet. Make sure that all paths are set up correctly # and perform a clone if os.path.exists(pkgPath): try: if not os.path.isdir(pkgPath): raise TargetError("Target path '{0}' for package '{1}' exists but is not a directory" .format(pkgPath, pkg["name"])) if os.listdir(pkgPath): raise TargetError("Target path '{0}' for package '{1}' has to be empty or a valid git working copy." .format(pkgPath, pkg["name"])) except TargetError as e: if dryRun: print("WARNING: {0}".format(e)) problemsOccurred = True else: raise e if not dryRun: if not os.path.exists(pkgPath): os.makedirs(pkgPath) proc = subprocess.Popen(["git", "clone", "--branch", pkg["__BRANCH"], pkg["url"], pkg["name"]], cwd = prefixPath) if proc.wait() != 0: raise TransactionError("Couldn't clone package '{0}' with branch '{1}' from '{2}'" .format(pkg["name"], pkg["__BRANCH"], pkg["url"])) else: raise InvalidPackageError("Unsupported repository type of package '{0}': '{1}'" .format(pkg["name"], pkg["repoType"])) if dryRun: print("Dry run. Nothing was installed/updated.") if problemsOccurred: print("WARNING: problems were detected during dry installation run. See above.") return