def query_user_input(section): def read_keyboard(): return raw_input(color.success_blue('==> ') + "Enter 'e' to assign effort order, 'p' to assign rough point estimates, 'f' to finish session, or 'q' to quit (session is resumed on next run): ") has_applied_effort_order = False keyboard_in = read_keyboard() while keyboard_in not in ['q', 'f']: if keyboard_in == 'e': print color.success_blue('# ') + 'Assigning effort order...' apply_effort_order(section.estimator) has_applied_effort_order = True elif keyboard_in == 'p': print color.success_blue('# ') + 'Assigning point estimates...' apply_point_estimates(section.estimator) else: print color.warn('Warning: ') + 'Please enter p, q, or f' keyboard_in = read_keyboard() if keyboard_in == 'q': quit() elif keyboard_in == 'f': if not has_applied_effort_order: response = raw_input(color.warn('Warning: ') + 'You have not assigned effort order before finishing. Would you like to assign effort order? (y/n): ') while response not in ['y', 'n']: response = raw_input(color.warn('Warning: ') + 'Please enter y/n for assigning effort order: ') if response == 'y': print color.success_blue('# ') + 'Assigning effort order...' apply_effort_order(section.estimator)
def uninstallPackage(flags, paths, args): color.isDebug = flags.debug args[0] = args[0].lower() if not os.path.exists(f"{paths[2]}/R2Boyo25"): downloadMainRepo(paths[2]) if isInMainRepo(args[0], paths) and not isAvalonPackage(args[0], paths[0], args[0]): color.note("Package is not an Avalon package, but it is in the main repository... uninstalling from there.....") moveMainRepoToAvalonFolder(paths[2], args[0], paths[0], paths) checkReqs(paths, args[0]) pkg = getPackageInfo(paths, args[0]) color.note("Uninstalling.....") if not pkg['uninstallScript']: color.warn("Uninstall script not found... Assuming uninstall not required and deleting files.....") deletePackage(paths[0], paths[1], args[0], paths) else: color.note("Uninstall script found, running.....") os.chdir(paths[1]) if runScript(paths[0] + "/" + args[0] + '/' + pkg['uninstallScript'], paths[0], paths[1], args[0], pkg['binname'], paths[4]+args[0]): color.error("Uninstall script failed! Deleting files anyways.....") deletePackage(paths[0], paths[1], args[0], paths) color.success("Successfully uninstalled package!")
def init(section): print color.success_blue('# ') + 'Fetching stories from Backlog and Queue...' progress.update(0, 2) backlog_stories = filter_not_accepted(section.backlog.fetch_stories()) backlog_stories_sorted = effort_sorted(backlog_stories) progress.update(1, 2) queue_backlog = filter_backlog(section.queue.fetch_stories()) progress.finish() print color.success_blue('# ') + 'Writing original story order to config file...' section.order = map(lambda story: (story.id, story.current_state), backlog_stories) section.write_order() progress.finish() def move_to_estimator(story, origin): story.description = getattr(story, 'description', '') + '\n' + origin_key + origin story.sync_to_project(section.estimator, safe=True) for story in backlog_stories_sorted: if story.story_type == 'release' and story.current_state == 'unscheduled': story.current_state = 'unstarted' continue if story.story_type != 'release' and story.current_state in ['unscheduled', 'unstarted']: story.current_state = 'started' if not hasattr(story, 'estimate') and story.is_estimatable(): print color.warn('Warning: ') + 'Story %s has no estimate. Adding an estimate of one; this is needed to start the story in Estimator.' % story.name story.estimate = 1 print color.success_blue('# ') + 'Moving stories from Backlog to Estimator...' progress.iter(backlog_stories_sorted, move_to_estimator, 'backlog') for story in queue_backlog: story.current_state = 'unscheduled' print color.success_blue('# ') + 'Moving stories from Queue to Estimator...' progress.iter(queue_backlog[::-1], move_to_estimator, 'queue')
def distroIsSupported(pkg): color.debug(getDistro()) if pkg['distros']: return (getDistro() in pkg['distros']) or (pkg['distros'] == ["all"]) else: color.warn("Supported distros not specified, assuming this distro is supported.....") return True
def __load_projects(self): for option in set(_read().options(self.section)).intersection([backlog_key, queue_key, estimator_key]): try: self.__dict__[option] = piv.Project.load(_read().getint(self.section, option)) except RuntimeError: # more specific? print color.warn('Warning: ') + 'invalid project id in config file at %s, %s. Could not load id: %d' % (self.section, option, _read().getint(self.section, option))
def installPackage(flags, paths, args): if os.path.exists(args[0]): installLocalPackage(flags, paths, args) quit() if os.path.exists(f"{paths[0]}/{args[0].lower()}") and not flags.fresh: updatePackage(flags, paths, *args) quit() color.isDebug = flags.debug args[0] = args[0].lower() if not os.path.exists(f"{paths[2]}/R2Boyo25"): downloadMainRepo(paths[2]) packagename = args[0] if ":" in packagename: branch = None commit = packagename.split(":")[-1] packagename = packagename.split(":")[0] elif packagename.count("/") > 1: branch = packagename.split("/")[-1] packagename = "/".join(packagename.split(":")[:-1]) commit = None elif ( ":" in packagename ) and ( packagename.count("/") > 1 ): commit = packagename.split(":")[-1] packagename = packagename.split(":")[0] branch = packagename.split("/")[-1] packagename = "/".join(packagename.split(":")[:-1]) else: branch = None commit = None args[0] = packagename color.note("Deleting old binaries and source files.....") deletePackage(paths[0], paths[1], args[0], paths, branch = branch, commit = commit) color.note("Downloading from github.....") color.debug(paths[0], "https://github.com/" + args[0], args[0]) downloadPackage(paths[0], "https://github.com/" + args[0], args[0], branch = branch, commit = commit) if isInMainRepo(args[0], paths) and not isAvalonPackage(args[0], paths[0], args[0]): color.note("Package is not an Avalon package, but it is in the main repository... installing from there.....") moveMainRepoToAvalonFolder(paths[2], args[0], paths[0], paths) else: color.debug("Not in the main repo") checkReqs(paths, args[0]) installDeps(flags, paths, args) if not flags.noinstall: color.note("Beginning compilation/installation.....") compilePackage(paths[0], paths[1], args[0], paths, flags) color.success("Done!") else: color.warn("-ni specified, skipping installation/compilation")
def archIsSupported(pkg): color.debug(str(pkg)) color.debug(getArch()) if pkg['arches']: return (getArch() in pkg['arches']) or (pkg['arches'] == ["all"]) else: color.warn("Supported arches not specified, assuming this arch is supported.....") return True
def updatePackage(flags, paths, *args): "Update to newest version of a repo, then recompile + reinstall program" args = list(args) if len(args) == 0: args.append("r2boyo25/avalonpackagemanager") #if not os.path.exists(f"{paths[0]}/{args[0].lower()}"): # installPackage(flags, paths, args) # quit() if not os.path.exists(f"{paths[2]}/R2Boyo25"): downloadMainRepo(paths[2]) color.isDebug = flags.debug args[0] = args[0].lower() #color.note("Deleting old binaries and source files.....") #deletePackage(paths[0], paths[1], args[0], paths, branch = branch, commit = commit) #rmFromBin(paths[1], packagename, paths) color.note("Pulling from github.....") #color.debug(paths[0], "https://github.com/" + args[0], args[0]) if os.system(f"cd {paths[0]}/{args[0]}; git pull"): if os.system(f"cd {paths[0]}/{args[0]}; git reset --hard; git pull"): error("Git error") #downloadPackage(paths[0], "https://github.com/" + args[0], args[0], branch = branch, commit = commit) if isInMainRepo(args[0], paths): color.note("Package is not an Avalon package, but it is in the main repository... installing from there.....") moveMainRepoToAvalonFolder(paths[2], args[0], paths[0], paths) else: color.debug("Not in the main repo") checkReqs(paths, args[0]) installDeps(flags, paths, args) if not flags.noinstall: color.note("Beginning compilation/installation.....") compilePackage(paths[0], paths[1], args[0], paths, flags) color.success("Done!") else: color.warn("-ni specified, skipping installation/compilation")
def finalize(section): print color.success_blue('# ') + 'Fetching stories from Estimator...' estimator_stories = section.estimator.fetch_stories() estimator_backlog = filter_backlog(estimator_stories) estimator_icebox = filter_icebox(estimator_stories) # stories that originally came from the backlog from_backlog = filter(lambda story: parse_tag(story, origin_key) == 'backlog', estimator_backlog) # stories that originally came from the queue from_queue = filter(lambda story: parse_tag(story, origin_key) == 'queue', estimator_backlog) # newly created stories no_from = filter(lambda story: story not in (from_backlog+from_queue), estimator_backlog) progress.finish() for story in estimator_icebox: if parse_tag(story, effort_key) == 'backlog': print color.warn('Warning: ') + 'Story \"%s\" is from the backlog, but was placed in Estimator icebox. It will be moved to backlog of Queue.' % story.name print color.success_blue('# ') + 'Filtering out nonexistant stories...' existing_backlog = get_existing(from_backlog, section.estimator) print color.success_blue('# ') + 'Restoring states and moving stories from Backlog...' restore_states(existing_backlog, section.order) progress.iter(existing_backlog, lambda story: story.sync_to_project(section.backlog,safe=True)) print color.success_blue('# ') + 'Ordering stories originally from Backlog...' order_backlog(existing_backlog, section.order) print color.success_blue('# ') + 'Moving new stories from Queue into icebox of Backlog...' progress.iter(list(reversed(from_queue)), move_to_icebox, section.backlog) print color.success_blue('# ') + 'Moving stories created in Estimator to icebox of Backlog...' progress.iter(no_from, move_to_icebox, section.backlog) print color.success_blue('# ') + 'Moving stories from icebox of Estimator to backlog of Queue...' progress.iter(estimator_icebox, move_to_backlog, section.queue) print color.success_blue('# ') + 'Formatting tags...' progress.iter(estimator_stories, finalize_tags) print color.success_blue('# ') + 'Deleting Estimator...' section.estimator.delete() progress.finish() abandon_session_config(section)
def installLocalPackage(flags, paths, args): tmppath = paths[5] color.isDebug = flags.debug color.note("Unpacking package.....") if not os.path.exists(args[0]): error(f"{args[0]} does not exist") elif os.path.isdir(args[0]): color.debug(f"cp -r {args[0]}/./ {tmppath}") if os.system(f"cp -r {args[0]}/./ {tmppath}"): error("Failed to copy files") else: color.debug(f"tar -xf {args[0]} -C {tmppath}") if os.system(f"tar -xf {args[0]} -C {tmppath}"): error("Error unpacking package, not a tar.gz file") cfgfile = json.load(open(f"{tmppath}/.avalon/package", "r")) try: args[0] = (cfgfile["author"] + "/" + cfgfile["repo"]).lower() except: error("Package's package file need 'author' and 'repo'") color.note("Deleting old binaries and source files.....") deletePackage(paths[0], paths[1], args[0], paths, cfgfile) color.note("Copying package files....") color.debug(f"mkdir -p {paths[0]}/{args[0]}") if os.system(f"mkdir -p {paths[0]}/{args[0]}"): error("Failed to make src folder") color.debug(f"cp -a {tmppath}/. {paths[0]}/{args[0]}") if os.system(f"cp -a {tmppath}/. {paths[0]}/{args[0]}"): error("Failed to copy files from temp folder to src folder") shutil.rmtree(tmppath) checkReqs(paths, args[0]) installDeps(flags, paths, args) if not flags.noinstall: color.note("Beginning compilation/installation.....") compilePackage(paths[0], paths[1], args[0], paths, flags) color.success("Done!") else: color.warn("-ni specified, skipping installation/compilation")
def stringDiffByLines(str1, str2): # color.warn('actual') # beatyPrint(str1) # color.warn('expected') # beatyPrint(str2) if isinstance(str1, str): color.red('actual') color.green(str1) color.red('expected') color.warn(str2) colorDiff.do(str1, str2) assert str1.strip() == str2.strip(), "not equal" else: color.red('actual') print(str1) color.red('expected') print(str2) assert str1 == str2, "not equal"
def share_estimator_with_account(section): estimator = section.estimator if not section.has_account_id(): account_id = raw_input(color.success_blue('==> ') + "No account id found in config file. This is used to automatically share the Estimator with everyone in the account. Please enter account id, or leave blank to skip this step: ") if account_id != '': section.account_id = account_id section.write_account_id() if section.has_account_id(): account = piv.Account.load(section.account_id) account_mems = account.fetch_memberships() estimator_mems = estimator.fetch_memberships() if len(account_mems) == 1: print color.warn('Warning: ') + 'No users to invite in account.' return; for amem in account_mems: intersection_mems = filter(lambda pmem: pmem.person['id'] == amem.person['id'], estimator_mems) if len(intersection_mems) > 1: print color.warn('Warning: ') + 'More than one project membership with id: %d. This should never happen. If this ever happens please let me know how I can reproduce this.' % amem.person['id'] if len(intersection_mems) == 0: estimator.add_membership({'person_id' : amem.person['id'], 'role' : 'member'}) print color.success_blue('# ') + 'Invited user %s to Estimator.' % amem.person['name']
def compilePackage(srcFolder, binFolder, packagename, paths, flags): pkg = getPackageInfo(paths, packagename) os.chdir(f"{srcFolder}/{packagename}") os.makedirs(f"{paths[4]}/{packagename}", exist_ok = True) if pkg['needsCompiled']: if not pkg['binname']: color.warn("Package needs compiled but there is no binname for Avalon to install, assuming installed by compile script.....") if pkg['compileScript']: color.note("Compile script found, compiling.....") if runScript(pkg['compileScript'], f"\"{srcFolder+f'/{packagename}'}\" \"{pkg['binname']}\" \"{paths[4]+packagename}\""): error("Compile script failed!") else: error("Program needs compiling but no compilation script found... exiting.....") else: color.warn("Program does not need to be compiled, moving to installation.....") if pkg['binname'] and not pkg['mvBinAfterInstallScript']: rmFromBin(binFolder, packagename, paths) if pkg['binfile']: mvBinToBin(binFolder, paths[4]+packagename, srcFolder + "/" + packagename + "/", pkg['binfile'], pkg['binname']) else: mvBinToBin(binFolder, paths[4]+packagename, srcFolder + "/" + packagename + "/", pkg['binname'], pkg['binname']) if pkg['installScript']: color.note("Installing.....") if pkg['needsCompiled'] or pkg['compileScript'] or pkg['binname']: if runScript(pkg['installScript'], f"\"{paths[4]+ '/' + packagename + '/' + pkg['binname']}\" \"{paths[4]+packagename}\" \"{binFolder}\" \"{srcFolder}\""): error("Install script failed!") else: if runScript(pkg['installScript'], f"\"{paths[4] + '/' + packagename}\" \"{srcFolder}\" \"{packagename}\""): error("Install script failed!") if pkg['toCopy']: color.note("Copying files needed by program.....") copyFilesToFiles(paths, packagename, pkg['toCopy']) if pkg['mvBinAfterInstallScript'] and pkg['binname']: rmFromBin(binFolder, packagename, paths) if pkg['binfile']: mvBinToBin(binFolder, paths[4]+packagename, srcFolder + "/" + packagename + "/", pkg['binfile'], pkg['binname']) else: mvBinToBin(binFolder, paths[4]+packagename, srcFolder + "/" + packagename + "/", pkg['binname'], pkg['binname']) else: color.warn('No installation script found... Assuming installation beyond APM\'s autoinstaller isn\'t neccessary')