Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
def PrintPackageInfo(args):
	packageList = ughubUtil.RemoveOptions(args)
	if len(packageList) != 1:
		print("Please specify exactly one package name. See 'ughub help packageinfo'")
		return

	packageName	= packageList[0]
	packages = LoadPackageDescs()

	firstPackage = True
	for pkg in packages:
		try:
			if pkg["name"] == packageName:
				if not firstPackage:
					print("")
				firstPackage = False

				print("package '{0}' from source '{1}':"
					  .format(packageName, pkg["__SOURCE"]))
				if ughubUtil.HasCommandlineOption(args, ("-s", "--short")):
					print(ShortPackageInfo(pkg))
				else:
					print(LongPackageInfo(pkg))

		except LookupError:
			raise InvalidSourceError("Failed to access package list in '{0}'"
									 .format(packagesFile))
Ejemplo n.º 3
0
def InitializeDirectory(args):
	force = ughubUtil.HasCommandlineOption(args, ("-f", "--force"))

	rootPath = os.getcwd()
	if len(args) > 0 and args[0][0] != '-':
		if os.path.isabs(args[0]):
			rootPath = args[0]
		else:
			rootPath = os.path.join(rootPath, args[0])

	ughubPath = os.path.normpath(os.path.join(rootPath, ".ughub"))
	if os.path.isdir(ughubPath):
		if os.path.isfile(os.path.join(ughubPath, "sources.json")):
			print("Directory '{0}' has been initialized already.".format(ughubPath))
			return
	else:
		try:
			existingRootDir = GetRootDirectory(ughubPath)
			if not force:
				print("Warning: Found ughub root directory at: {0}".format(existingRootDir))
				print("call 'ughub init -f' to force initialization in this path.")
				return

		except NoRootDirectoryError:
			pass

		# this is actually the expected case
		os.makedirs(ughubPath)

	GenerateDefaultSourceFile(ughubPath)
	UpdateSources([], ughubPath)
	GenerateCMakeLists(rootPath)
	print("initialized ughub directory at '{0}'".format(rootPath))
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
def ListPackages(args):
    categories = []
    matchAll = ughubUtil.HasCommandlineOption(args, ("-a", "--matchall"))

    for arg in args:
        if arg[0] != "-":
            categories.append(arg)

    try:
        packages = LoadPackageDescs()

        if len(packages) == 0:
            print("no packages found")
            return

        if matchAll:
            packages = FilterPackagesAll(packages, categories)
        elif len(categories) > 0:
            packages = FilterPackagesAny(packages, categories)

        if len(packages) == 0:
            print("no packages found for the given criteria")
            return

        # sort packages alphabetically
        packageDict = {}
        for pkg in packages:
            packageDict[pkg["name"]] = packageDict.get(pkg["name"], []) + [pkg]

        print("{0:24.4}  {1:10} {2:11} {3:}".format("NAME", "PREFIX", "SOURCE",
                                                    "URL"))

        for key in sorted(packageDict.keys()):
            pkgs = packageDict[key]
            for pkg in pkgs:
                print("{0:24}  {1:10} {2:11} {3:}".format(
                    pkg["name"], pkg["prefix"], pkg["__SOURCE"], pkg["url"]))

    except LookupError as e:
        raise InvalidPackageError(e)
Ejemplo n.º 6
0
def ListPackages(args):

    try:
        packages = LoadFilteredPackageDescs(args)

        if len(packages) == 0:
            print("no packages found")
            return

        # sort packages alphabetically
        packageDict = {}
        for pkg in packages:
            packageDict[pkg["name"]] = packageDict.get(pkg["name"], []) + [pkg]

        namesonly = ughubUtil.HasCommandlineOption(args, ("--namesonly", ))

        if namesonly:
            result = ""
            for key in sorted(packageDict.keys()):
                pkgs = packageDict[key]
                for pkg in pkgs:
                    result += pkg["name"] + " "

            ughubUtil.Write(result)
        else:
            print("{0:24.4}  {1:10} {2:11} {3:}".format(
                "NAME", "PREFIX", "SOURCE", "URL"))

            for key in sorted(packageDict.keys()):
                pkgs = packageDict[key]
                for pkg in pkgs:
                    print("{0:24}  {1:10} {2:11} {3:}".format(
                        pkg["name"], pkg["prefix"], pkg["__SOURCE"],
                        pkg["url"]))

    except LookupError as e:
        raise InvalidPackageError(e)
Ejemplo n.º 7
0
def PrintCommandHelp(cmdName, args=[]):

    shortdesc = ughubUtil.HasCommandlineOption(args, ("--short", ))

    try:
        cmdDict = GetHelpEntry("commands.{0}".format(cmdName))

    except ughubUtil.NestedTableEntryNotFoundError:
        raise MalformedHelpContentsError(
            "Requested command '{0}' not found in help database".format(
                cmdName))

    if shortdesc:
        if "shortdescription" in cmdDict:
            ughubUtil.Write(cmdDict["shortdescription"])
        return

    print("Usage: ughub {0}".format(cmdDict["usage"]))
    print("")
    for line in cmdDict["description"].splitlines():
        print("  {0}".format(line))

    try:
        options = ughubUtil.GetFromNestedTable(cmdDict, "options")
    except ughubUtil.NestedTableEntryNotFoundError:
        return

    print("")
    print("Valid options:")
    for opt in options:
        name = opt["name"]
        sep = ":"
        for line in opt["description"].splitlines():
            print("  {0:20}{1} {2}".format(name, sep, line))
            name = ""
            sep = " "
Ejemplo n.º 8
0
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