def run_extract(self): # if the environment has no extract_plan variable, doesn't run extract function if not hasattr(self.environment, "extract_nevertheless" ) or not self.environment.extract_nevertheless: if not hasattr(self.environment, "extract_plan"): return target = os.path.dirname(self.environment.build_dir) extracted_file = os.path.join(os.path.dirname(target), ".extracted") if os.path.isfile(extracted_file): if self.environment.force_extract: shelltools.remove_file(extracted_file) else: out.write("%s %s/%s-%s had been already extracted.\n" % (out.color(">>", "brightyellow"), \ self.environment.category, self.environment.name, self.environment.version)) return True utils.xterm_title("lpms: extracting %s/%s/%s-%s" % (self.environment.repo, self.environment.category, \ self.environment.name, self.environment.version)) out.notify("extracting archive(s) to %s" % os.path.dirname(self.environment.build_dir)) # now, extract the archives self.run_stage("extract") out.notify("%s has been extracted." % self.environment.fullname) shelltools.touch(extracted_file) if self.environment.stage == "extract": lpms.terminate()
def perform_operation(self): utils.xterm_title("(%s/%s) lpms: merging %s/%s-%s from %s" % (self.environment.index, self.environment.count, self.environment.category, self.environment.name, self.environment.version, self.environment.repo)) # create $info_file_name.gz archive and remove info file self.create_info_archive() # merge the package self.merge_package() # clean the previous version if it is exists self.clean_obsolete_content() # write to database self.write_db() # create or update /usr/share/info/dir self.update_info_index() if self.backup: out.write("%s%s configuration file changed. Use %s to fix these files.\n" % (out.color(" > ", "green"), len(self.backup), \ out.color("merge-conf", "red"))) if shelltools.is_exists(cst.lock_file): shelltools.remove_file(cst.lock_file) return True, self.environment
def run_configure(self): utils.xterm_title("(%s/%s) lpms: configuring %s/%s-%s from %s" % (self.environment.index, self.environment.count, self.environment.category, self.environment.name, self.environment.version, self.environment.repo)) out.normal("configuring source in %s" % self.environment.build_dir) configured_file = os.path.join( os.path.dirname(os.path.dirname(self.environment.build_dir)), ".configured") if os.path.isfile(configured_file) and self.environment.resume_build: out.warn_notify("%s had been already configured." % self.environment.fullname) return True lpms.logger.info("configuring in %s" % self.environment.build_dir) self.run_stage("configure") out.notify("%s has been configured." % self.environment.fullname) if not os.path.isfile(configured_file): touch(configured_file) if self.environment.stage == "configure": lpms.terminate()
def run_install(self): utils.xterm_title("(%s/%s) lpms: installing %s/%s-%s from %s" % (self.environment.index, self.environment.count, self.environment.category, self.environment.name, self.environment.version, self.environment.repo)) out.normal("installing %s to %s" % (self.environment.fullname, self.environment.install_dir)) installed_file = os.path.join(os.path.dirname(os.path.dirname( self.environment.build_dir)), ".installed") if os.path.isfile(installed_file) and self.environment.resume_build: out.warn_notify("%s had been already installed." % self.environment.fullname) return True lpms.logger.info("installing to %s" % self.environment.build_dir) self.run_stage("install") if self.environment.docs is not None: for doc in self.environment.docs: if isinstance(doc, list) or isinstance(doc, tuple): source_file, target_file = doc namestr = self.environment.fullname if self.environment.slot != "0" else self.environment.name target = self.environment.fix_target_path("/usr/share/doc/%s/%s" % (namestr, target_file)) source = os.path.join(self.environment.build_dir, source_file) # self.environment.index, insfile(source, target) #else: # self.environment.index, insdoc(doc) out.notify("%s has been installed." % self.environment.fullname) if not os.path.isfile(installed_file): touch(installed_file) if self.environment.stage == "install": lpms.terminate()
def run_remove(self): utils.xterm_title("(%s/%s) lpms: removing %s/%s-%s from %s" % (self.environment.index, self.environment.count, self.environment.category, self.environment.name, self.environment.version, self.environment.repo)) remove.main((self.environment.repo, self.environment.category, self.environment.name, self.environment.version), self.environment.real_root)
def run_build(self): utils.xterm_title("(%s/%s) lpms: building %s/%s-%s from %s" % (self.environment.index, self.environment.count, self.environment.category, self.environment.name, self.environment.version, self.environment.repo)) out.normal("compiling source in %s" % self.environment.build_dir) built_file = os.path.join(os.path.dirname(os.path.dirname( self.environment.build_dir)), ".built") if os.path.isfile(built_file) and self.environment.resume_build: out.warn_notify("%s had been already built." % self.environment.fullname) return True lpms.logger.info("building in %s" % self.environment.build_dir) self.run_stage("build") out.notify("%s has been built." % self.environment.fullname) if not os.path.isfile(built_file): touch(built_file) if self.environment.stage == "build": lpms.terminate()
def run_install(self): utils.xterm_title("(%s/%s) lpms: installing %s/%s-%s from %s" % (self.environment.index, self.environment.count, self.environment.category, self.environment.name, self.environment.version, self.environment.repo)) out.normal("installing %s to %s" % (self.environment.fullname, self.environment.install_dir)) installed_file = os.path.join( os.path.dirname(os.path.dirname(self.environment.build_dir)), ".installed") if os.path.isfile(installed_file) and self.environment.resume_build: out.warn_notify("%s had been already installed." % self.environment.fullname) return True lpms.logger.info("installing to %s" % self.environment.build_dir) self.run_stage("install") if self.environment.docs is not None: for doc in self.environment.docs: if isinstance(doc, list) or isinstance(doc, tuple): source_file, target_file = doc namestr = self.environment.fullname if self.environment.slot != "0" else self.environment.name target = self.environment.fix_target_path( "/usr/share/doc/%s/%s" % (namestr, target_file)) source = os.path.join(self.environment.build_dir, source_file) # self.environment.index, insfile(source, target) #else: # self.environment.index, insdoc(doc) out.notify("%s has been installed." % self.environment.fullname) if not os.path.isfile(installed_file): touch(installed_file) if self.environment.stage == "install": lpms.terminate()
def run_extract(self): # if the environment has no extract_plan variable, doesn't run extract function if not hasattr(self.environment, "extract_nevertheless") or not self.environment.extract_nevertheless: if not hasattr(self.environment, "extract_plan"): return target = os.path.dirname(self.environment.build_dir) extracted_file = os.path.join(os.path.dirname(target), ".extracted") if os.path.isfile(extracted_file): if self.environment.force_extract: shelltools.remove_file(extracted_file) else: out.write("%s %s/%s-%s had been already extracted.\n" % (out.color(">>", "brightyellow"), \ self.environment.category, self.environment.name, self.environment.version)) return True utils.xterm_title("lpms: extracting %s/%s/%s-%s" % (self.environment.repo, self.environment.category, \ self.environment.name, self.environment.version)) out.notify("extracting archive(s) to %s" % os.path.dirname(self.environment.build_dir)) # now, extract the archives self.run_stage("extract") out.notify("%s has been extracted." % self.environment.fullname) shelltools.touch(extracted_file) if self.environment.stage == "extract": lpms.terminate()
def perform_operation(self): '''Handles command line arguments and drive building operation''' self.set_environment_variables() # Check /proc and /dev. These filesystems must be mounted # to perform operations properly. for item in ('/proc', '/dev'): if not os.path.ismount(item): out.warn("%s is not mounted. You have been warned." % item) # clean source code extraction directory if it is wanted # TODO: check the following condition when resume functionality is back if self.instruction.clean_tmp: if self.instruction.resume_build is not None: out.warn("clean-tmp is disabled because of resume-build is enabled.") else: self.clean_temporary_directory() # we want to save starting time of the build operation to calculate building time # The starting point of logging lpms.logger.info("starting build (%s/%s) %s/%s/%s-%s" % ( self.instruction.index, self.instruction.count, self.internals.env.repo, self.internals.env.category, self.internals.env.name, self.internals.env.version ) ) out.normal("(%s/%s) building %s/%s from %s" % ( self.instruction.index, self.instruction.count, out.color(self.internals.env.category, "green"), out.color(self.internals.env.name+"-"+self.internals.env.version, "green"), self.internals.env.repo ) ) if self.internals.env.sandbox: lpms.logger.info("sandbox enabled build") out.notify("sandbox is enabled") else: lpms.logger.warning("sandbox disabled build") out.warn_notify("sandbox is disabled") # fetch packages which are in download_plan list if self.internals.env.src_url is not None: # preprocess url shortcuts such as $name, $version and etc self.parse_src_url_field() # if the package is revisioned, override build_dir and install_dir. # remove revision number from these variables. if self.revisioned: for variable in ("build_dir", "install_dir"): new_variable = "".join(os.path.basename(getattr(self.internals.env, \ variable)).split(self.revision)) setattr(self.internals.env, variable, \ os.path.join(os.path.dirname(getattr(self.internals.env, \ variable)), new_variable)) utils.xterm_title("lpms: downloading %s/%s/%s-%s" % ( self.internals.env.repo, self.internals.env.category, self.internals.env.name, self.internals.env.version ) ) self.prepare_download_plan(self.internals.env.applied_options) if not fetcher.URLFetcher().run(self.download_plan): lpms.terminate("\nplease check the spec") if self.internals.env.applied_options is not None and self.internals.env.applied_options: out.notify("applied options: %s" % " ".join(self.internals.env.applied_options)) if self.internals.env.src_url is None and not self.extract_plan \ and hasattr(self.internals.env, "extract"): # Workaround for #208 self.internals.env.extract_nevertheless = True # Remove previous sandbox log if it is exist. if os.path.exists(cst.sandbox_log): shelltools.remove_file(cst.sandbox_log) # Enter the building directory os.chdir(self.internals.env.build_dir) # Manage ccache if hasattr(self.config, "ccache") and self.config.ccache: if utils.drive_ccache(config=self.config): out.notify("ccache is enabled.") else: out.warn("ccache could not be enabled. so you should check dev-util/ccache") self.internals.env.start_time = time.time() return True, self.internals.env
def perform_operation(self): '''Handles command line arguments and drive building operation''' self.set_environment_variables() # Check /proc and /dev. These filesystems must be mounted # to perform operations properly. for item in ('/proc', '/dev'): if not os.path.ismount(item): out.warn("%s is not mounted. You have been warned." % item) # clean source code extraction directory if it is wanted # TODO: check the following condition when resume functionality is back if self.instruction.clean_tmp: if self.instruction.resume_build is not None: out.warn( "clean-tmp is disabled because of resume-build is enabled." ) else: self.clean_temporary_directory() # we want to save starting time of the build operation to calculate building time # The starting point of logging lpms.logger.info("starting build (%s/%s) %s/%s/%s-%s" % (self.instruction.index, self.instruction.count, self.internals.env.repo, self.internals.env.category, self.internals.env.name, self.internals.env.version)) out.normal( "(%s/%s) building %s/%s from %s" % (self.instruction.index, self.instruction.count, out.color(self.internals.env.category, "green"), out.color( self.internals.env.name + "-" + self.internals.env.version, "green"), self.internals.env.repo)) if self.internals.env.sandbox: lpms.logger.info("sandbox enabled build") out.notify("sandbox is enabled") else: lpms.logger.warning("sandbox disabled build") out.warn_notify("sandbox is disabled") # fetch packages which are in download_plan list if self.internals.env.src_url is not None: # preprocess url shortcuts such as $name, $version and etc self.parse_src_url_field() # if the package is revisioned, override build_dir and install_dir. # remove revision number from these variables. if self.revisioned: for variable in ("build_dir", "install_dir"): new_variable = "".join(os.path.basename(getattr(self.internals.env, \ variable)).split(self.revision)) setattr(self.internals.env, variable, \ os.path.join(os.path.dirname(getattr(self.internals.env, \ variable)), new_variable)) utils.xterm_title( "lpms: downloading %s/%s/%s-%s" % (self.internals.env.repo, self.internals.env.category, self.internals.env.name, self.internals.env.version)) self.prepare_download_plan(self.internals.env.applied_options) if not fetcher.URLFetcher().run(self.download_plan): lpms.terminate("\nplease check the spec") if self.internals.env.applied_options is not None and self.internals.env.applied_options: out.notify("applied options: %s" % " ".join(self.internals.env.applied_options)) if self.internals.env.src_url is None and not self.extract_plan \ and hasattr(self.internals.env, "extract"): # Workaround for #208 self.internals.env.extract_nevertheless = True # Remove previous sandbox log if it is exist. if os.path.exists(cst.sandbox_log): shelltools.remove_file(cst.sandbox_log) # Enter the building directory os.chdir(self.internals.env.build_dir) # Manage ccache if hasattr(self.config, "ccache") and self.config.ccache: if utils.drive_ccache(config=self.config): out.notify("ccache is enabled.") else: out.warn( "ccache could not be enabled. so you should check dev-util/ccache" ) self.internals.env.start_time = time.time() return True, self.internals.env
def remove_package(pkgnames, instruction): '''Triggers remove operation for given packages''' if instruction.like: # handle shortened package names database = dbapi.InstallDB() for item in instruction.like: query = database.db.cursor.execute( "SELECT name FROM package where name LIKE ?", (item, )) results = query.fetchall() if results: for result in results: pkgnames.append(result[0]) del database file_relationsdb = dbapi.FileRelationsDB() #try: packages = [ GetPackage(pkgname, installdb=True).select() for pkgname in pkgnames ] #except PackageNotFound as package_name: # out.error("%s seems not installed." % package_name) # lpms.terminate() instruction.count = len(packages) index = 0 # FIXME: I must create a new reverse dependency handler implementation #if instruct["show-reverse-depends"]: # instruct["ask"] = True # # WARNING: the mechanism only shows directly reverse dependencies # # supposing that if A is a reverse dependency of B and C is depends on A. # # when the user removes B, A and C will be broken. But lpms will warn the user about A. # broken_packages = [] # reversedb = dbapi.ReverseDependsDB() # out.normal("resolving primary reverse dependencies...\n") # for package in packages: # category, name, version = package[1:] # if lpms.getopt("--use-file-relations"): # broken_packages.extend(file_relations.get_packages(category, name, version)) # else: # broken_packages.extend(reversedb.get_reverse_depends(category, name)) # if broken_packages: # out.warn("the following packages will be broken:\n") # for broken_package in broken_packages: # broken_repo, broken_category, broken_name, broken_version = broken_package # out.write(" %s %s/%s/%s-%s\n" % (out.color(">", "brightred"), broken_repo, broken_category, \ # broken_name, broken_version)) # else: # out.warn("no reverse dependency found.") if instruction.ask: out.write("\n") for package in packages: out.write( " %s %s/%s/%s-%s\n" % (out.color( ">", "brightgreen"), out.color(package.repo, "green"), out.color(package.category, "green"), out.color(package.name, "green"), out.color(package.version, "green"))) utils.xterm_title("lpms: confirmation request") out.write("\nTotal %s package will be removed.\n\n" % out.color(str(instruction.count), "green")) if not utils.confirm("Would you like to continue?"): out.write("quitting...\n") utils.xterm_title_reset() lpms.terminate() realroot = instruction.new_root if instruction.new_root else cst.root config = conf.LPMSConfig() for package in packages: fdb = file_collisions.CollisionProtect(package.category, package.name, \ package.slot, version=package.version, real_root=realroot) fdb.handle_collisions() if fdb.collisions: out.write(out.color(" > ", "brightyellow")+"file collisions detected while removing %s/%s/%s-%s\n\n" \ % (package.repo, package.category, package.name, package.version)) for (c_package, c_path) in fdb.collisions: c_category, c_name, c_slot, c_version = c_package out.write(out.color(" -- ", "red")+c_category+"/"+c_name+"-"\ +c_version+":"+c_slot+" -> "+c_path+"\n") if fdb.collisions and config.collision_protect and not \ lpms.getopt('--force-file-collision'): out.write( "\nquitting... use '--force-file-collision' to continue.\n" ) lpms.terminate() index += 1 instruction.index = index if not initpreter.InitializeInterpreter( package, instruction, ['remove'], remove=True).initialize(): out.warn("an error occured during remove operation: %s/%s/%s-%s" % (package.repo, package.category, \ package.name, package.version)) else: file_relationsdb.delete_item_by_pkgdata(package.category, package.name, package.version, commit=True)
def package_mangler(self, **kwargs): def collision_check(): # TODO: This is a temporary solution. collision_check function # must be a reusable part for using in remove operation out.normal("checking file collisions...") lpms.logger.info("checking file collisions") collision_object = file_collisions.CollisionProtect( environment.category, environment.name, environment.slot, real_root=environment.real_root, source_dir=environment.install_dir) collision_object.handle_collisions() if collision_object.orphans: out.write( out.color(" > ", "brightyellow") + "these files are orphan. the package will adopt the files:\n" ) index = 0 for orphan in collision_object.orphans: out.notify(orphan) index += 1 if index > 100: # FIXME: the files must be logged out.write( out.color(" > ", "brightyellow") + "...and many others.") break if collision_object.collisions: out.write( out.color(" > ", "brightyellow") + "file collisions detected:\n") for item in collision_object.collisions: (category, name, slot, version), path = item out.write(out.color(" -- ", "red")+category+"/"+name+"-"\ +version+":"+slot+" -> "+path+"\n") if collision_object.collisions and self.config.collision_protect: if environment.force_file_collision: out.warn( "Disregarding these collisions, you have been warned!") else: return False return True names = kwargs.get("names", self.request.names) # Prepare build environment out.normal("resolving dependencies") targets = api.resolve_dependencies(names, self.request.instruction) if self.request.instruction.pretend: out.write("\n") out.normal("these packages will be merged, respectively:\n") showplan.show(targets.packages, targets.conflicts, targets.options, installdb=dbapi.InstallDB()) out.write("\ntotal %s package(s) listed.\n\n" \ % out.color(str(len(targets.packages)), "green")) raise LpmsTerminate if self.request.instruction.ask: out.write("\n") out.normal("these packages will be merged, respectively:\n") showplan.show(targets.packages, targets.conflicts, targets.options, installdb=dbapi.InstallDB()) utils.xterm_title("lpms: confirmation request") out.write("\ntotal %s package(s) will be merged.\n\n" \ % out.color(str(len(targets.packages)), "green")) if not utils.confirm("Would you like to continue?"): # Reset terminal title and terminate lpms. utils.xterm_title_reset() raise LpmsTerminate self.request.instruction.count = len(targets.packages) for index, package in enumerate(targets.packages, 1): self.request.instruction.index = index retval, environment = api.prepare_environment( package, self.request.instruction, dependencies=targets.dependencies[package.id] if package.id in \ targets.dependencies else None, options=targets.options[package.id] if package.id in \ targets.options else None, conditional_versions=targets.conditional_versions[package.id] \ if package.id in targets.conditional_versions else None, conflicts=targets.conflicts[package.id] if package.id \ in targets.conflicts else None, inline_option_targets=targets.inline_option_targets[package.id] \ if package.id in targets.inline_option_targets else None ) if not retval: out.error( "There are some errors while preparing environment to build FOO." ) out.error( "So you should submit a bug report to fix the issue.") raise LpmsTerminate("thanks to flying with lpms.") # Now, run package script(spec) for configuring, building and install retval, environment = self.interpreter.initialize(environment) if retval is False: out.error( "There are some errors while building FOO from source.") out.error("Error messages should be seen above.") out.error( "If you want to submit a bug report, please attatch BAR or send above messages in a proper way." ) raise LpmsTerminate("thanks to flying with lpms.") elif retval is None: raise LpmsTerminate if not collision_check(): out.error( "File collisions detected. If you want to overwrite these files," ) out.error( "You have to use --force-file-collisions parameter or disable collision_protect in configuration file." ) raise LpmsTerminate("thanks to flying with lpms.") # Merge package to livefs if environment.not_merge: raise LpmsTerminate("not merging...") retval, environment = merge.Merge(environment).perform_operation() if not retval: raise LpmsTerminate("Some errors occured while merging %s" % environment.fullname) lpms.logger.info("finished %s/%s/%s-%s" % (package.repo, package.category, package.name, package.version)) utils.xterm_title("lpms: %s/%s finished" % (package.category, package.name)) out.normal("Cleaning build directory") shelltools.remove_dir(os.path.dirname(environment.install_dir)) catdir = os.path.dirname(os.path.dirname(environment.install_dir)) if not os.listdir(catdir): shelltools.remove_dir(catdir) # There is no error, exitting... out.normal("Completed.")
def remove_package(pkgnames, instruction): '''Triggers remove operation for given packages''' if instruction.like: # handle shortened package names database = dbapi.InstallDB() for item in instruction.like: query = database.db.cursor.execute("SELECT name FROM package where name LIKE ?", (item,)) results = query.fetchall() if results: for result in results: pkgnames.append(result[0]) del database file_relationsdb = dbapi.FileRelationsDB() #try: packages = [GetPackage(pkgname, installdb=True).select() for pkgname in pkgnames] #except PackageNotFound as package_name: # out.error("%s seems not installed." % package_name) # lpms.terminate() instruction.count = len(packages); index = 0; # FIXME: I must create a new reverse dependency handler implementation #if instruct["show-reverse-depends"]: # instruct["ask"] = True # # WARNING: the mechanism only shows directly reverse dependencies # # supposing that if A is a reverse dependency of B and C is depends on A. # # when the user removes B, A and C will be broken. But lpms will warn the user about A. # broken_packages = [] # reversedb = dbapi.ReverseDependsDB() # out.normal("resolving primary reverse dependencies...\n") # for package in packages: # category, name, version = package[1:] # if lpms.getopt("--use-file-relations"): # broken_packages.extend(file_relations.get_packages(category, name, version)) # else: # broken_packages.extend(reversedb.get_reverse_depends(category, name)) # if broken_packages: # out.warn("the following packages will be broken:\n") # for broken_package in broken_packages: # broken_repo, broken_category, broken_name, broken_version = broken_package # out.write(" %s %s/%s/%s-%s\n" % (out.color(">", "brightred"), broken_repo, broken_category, \ # broken_name, broken_version)) # else: # out.warn("no reverse dependency found.") if instruction.ask: out.write("\n") for package in packages: out.write(" %s %s/%s/%s-%s\n" % (out.color(">", "brightgreen"), out.color(package.repo, "green"), out.color(package.category, "green"), out.color(package.name, "green"), out.color(package.version, "green"))) utils.xterm_title("lpms: confirmation request") out.write("\nTotal %s package will be removed.\n\n" % out.color(str(instruction.count), "green")) if not utils.confirm("Would you like to continue?"): out.write("quitting...\n") utils.xterm_title_reset() lpms.terminate() realroot = instruction.new_root if instruction.new_root else cst.root config = conf.LPMSConfig() for package in packages: fdb = file_collisions.CollisionProtect(package.category, package.name, \ package.slot, version=package.version, real_root=realroot) fdb.handle_collisions() if fdb.collisions: out.write(out.color(" > ", "brightyellow")+"file collisions detected while removing %s/%s/%s-%s\n\n" \ % (package.repo, package.category, package.name, package.version)) for (c_package, c_path) in fdb.collisions: c_category, c_name, c_slot, c_version = c_package out.write(out.color(" -- ", "red")+c_category+"/"+c_name+"-"\ +c_version+":"+c_slot+" -> "+c_path+"\n") if fdb.collisions and config.collision_protect and not \ lpms.getopt('--force-file-collision'): out.write("\nquitting... use '--force-file-collision' to continue.\n") lpms.terminate() index += 1; instruction.index = index if not initpreter.InitializeInterpreter(package, instruction, ['remove'], remove=True).initialize(): out.warn("an error occured during remove operation: %s/%s/%s-%s" % (package.repo, package.category, \ package.name, package.version)) else: file_relationsdb.delete_item_by_pkgdata(package.category, package.name, package.version, commit=True)