def _create_env_script(self): virtual_path = self.virtual_path path_updates = '\n'.join('export %s="$VIRTUAL_PATH/%s${%s:+:$%s}"' % (v, d, v, v) for v, d in STANDARD_PATH_VARS) # Collect package env scripts pkg_env_scripts = [] for pkg in self.packages(only_enabled=True): local_env_script = os.path.join(pkg.path, 'bpt_meta', 'env_script') if os.path.exists(local_env_script): f = open(local_env_script) try: pkg_env_scripts.append(f.read()) finally: f.close() pkg_env_scripts = '\n'.join(pkg_env_scripts) env_script = open( ENV_SCRIPT_TMPL).read() % locals() # XXX(ot) close file? env_script_file = open(self.env_script, 'w') try: env_script_file.write(env_script) finally: env_script_file.close() os.chmod(self.env_script, 0755) log.info('Created env script')
def _unlink_package(self, package): log.info('Unlinking package %s' % package.name) for d in DYN_DIRS: src_path = os.path.abspath(os.path.join(package.path, d)) dest_path = os.path.abspath(os.path.join(self.virtual_path, d)) unlinkdir(src_path, dest_path)
def _run(self, config, cmd_options, cmd_args): require_box(config) box = config.box regexps = [re.compile(pattern + '$', re.IGNORECASE) for pattern in cmd_options.exclude] to_remove = [] for pkg in box.packages(): if pkg.enabled: continue for regexp in regexps: if regexp.match(pkg.name): break else: # no exclude regexp matched to_remove.append(pkg) if not to_remove: log.info('No packages to remove') return 0 print 'The following packages will be removed:' for pkg in to_remove: print '\t%s' % pkg.name answer = raw_input('Are you sure [y/N]? ') if answer.lower() != 'y': return 0 for pkg in to_remove: box.disable_package(pkg, remove=True)
def autobuild(box, filename, configure_options='', keep_temp=False, stdout=None): if not os.path.exists(filename): raise UserError('File %s does not exist' % filename) if os.path.isdir(filename): source_dir = os.path.abspath(filename) autobuild_dir(box, source_dir, os.path.basename(source_dir), configure_options) else: build_dir = mkdtemp() try: basename, unpack_cmd = guess_unpack_cmd(filename) log.info('Unpacking the file...') check_call(unpack_cmd, cwd=build_dir) unpacked_files = [ os.path.join(build_dir, f) for f in os.listdir(build_dir) ] unpacked_dirs = [d for d in unpacked_files if os.path.isdir(d)] if len(unpacked_dirs) != 1: raise UnsupportedPath('Could not find source directory') source_dir, = unpacked_dirs autobuild_dir(box, source_dir, basename, configure_options, stdout) finally: if keep_temp: log.info('Not deleting temporary files in directory %s', build_dir) else: rmtree(build_dir)
def autobuild(box, filename, configure_options='', keep_temp=False, stdout=None): if not os.path.exists(filename): raise UserError('File %s does not exist' % filename) if os.path.isdir(filename): source_dir = os.path.abspath(filename) autobuild_dir(box, source_dir, os.path.basename(source_dir), configure_options) else: build_dir = mkdtemp() try: basename, unpack_cmd = guess_unpack_cmd(filename) log.info('Unpacking the file...') check_call(unpack_cmd, cwd=build_dir) unpacked_files = [os.path.join(build_dir, f) for f in os.listdir(build_dir)] unpacked_dirs = [d for d in unpacked_files if os.path.isdir(d)] if len(unpacked_dirs) != 1: raise UnsupportedPath('Could not find source directory') source_dir, = unpacked_dirs autobuild_dir(box, source_dir, basename, configure_options, stdout) finally: if keep_temp: log.info('Not deleting temporary files in directory %s', build_dir) else: rmtree(build_dir)
def _create_env_script(self): virtual_path = self.virtual_path path_updates = '\n'.join('export %s="$VIRTUAL_PATH/%s${%s:+:$%s}"' % (v, d, v, v) for v, d in STANDARD_PATH_VARS) # Collect package env scripts pkg_env_scripts = [] for pkg in self.packages(only_enabled=True): local_env_script = os.path.join(pkg.path, 'bpt_meta', 'env_script') if os.path.exists(local_env_script): f = open(local_env_script) try: pkg_env_scripts.append(f.read()) finally: f.close() pkg_env_scripts = '\n'.join(pkg_env_scripts) env_script = open(ENV_SCRIPT_TMPL).read() % locals() # XXX(ot) close file? env_script_file = open(self.env_script, 'w') try: env_script_file.write(env_script) finally: env_script_file.close() os.chmod(self.env_script, 0755) log.info('Created env script')
def unittest(self): log.info("Testing sourcedir %s", self.path) sh_line = 'source "%s";' % BASE_SH_SCRIPT + 'cd "%s";' % self._sourcedir + "source bpt-rules;" + "bpt_unittest;" exitstatus = call(["bash", "-e", "-c", sh_line]) if exitstatus != 0: log.warning("unittest exited with exit code %s. Some tests may have failed", exitstatus) return False return True
def clean(self, deep=False): log.info('Cleaning sourcedir %s', self.path) sh_line = ('source "%s";' % BASE_SH_SCRIPT + 'cd "%s";' % self._sourcedir + 'rm -f .bpt_status;' + 'source bpt-rules;' + 'bpt_clean;') if deep: sh_line += 'bpt_deepclean;' exitstatus, outtext = getstatusoutput("bash -e -c '%s'" % sh_line) assert exitstatus == 0, (exitstatus, outtext)
def enable_package(self, package): # Disable other versions of the same application for other in self.packages(only_enabled=True): if other is not package and other.app_name.lower() == package.app_name.lower(): self.disable_package(other) log.info('Enabling package %s', package) package.enabled = True self._link_package(package) self._create_env_script()
def disable_package(self, package, remove=False): if not remove: log.info('Disabling package %s', package) else: log.info('Removing package %s', package) package.enabled = False self._unlink_package(package) self._create_env_script() if remove: shutil.rmtree(package.path)
def enable_package(self, package): # Disable other versions of the same application for other in self.packages(only_enabled=True): if other is not package and other.app_name.lower( ) == package.app_name.lower(): self.disable_package(other) log.info('Enabling package %s', package) package.enabled = True self._link_package(package) self._create_env_script()
def unittest(self): log.info('Testing sourcedir %s', self.path) sh_line = ('source "%s";' % BASE_SH_SCRIPT + 'cd "%s";' % self._sourcedir + 'source bpt-rules;' + 'bpt_unittest;') exitstatus = call(['bash', '-e', '-c', sh_line]) if exitstatus != 0: log.warning( 'unittest exited with exit code %s. Some tests may have failed', exitstatus) return False return True
def clean(self, deep=False): log.info('Cleaning sourcedir %s', self.path) sh_line = ('source "%s";' % BASE_SH_SCRIPT + 'cd "%s";' % self._sourcedir + 'rm -f .bpt_status;' + 'source bpt-rules;' + 'bpt_clean;' ) if deep: sh_line += 'bpt_deepclean;' exitstatus, outtext = getstatusoutput("bash -e -c '%s'" % sh_line) assert exitstatus == 0, (exitstatus, outtext)
def unittest(self): log.info('Testing sourcedir %s', self.path) sh_line = ('source "%s";' % BASE_SH_SCRIPT + 'cd "%s";' % self._sourcedir + 'source bpt-rules;' + 'bpt_unittest;' ) exitstatus = call(['bash', '-e', '-c', sh_line]) if exitstatus != 0: log.warning('unittest exited with exit code %s. Some tests may have failed', exitstatus) return False return True
def autobuild_dir(box, source_dir, basename, configure_options, stdout=None): name, version = guess_name_version(basename) log.info('Guessed application name "%s", version "%s"', name, version) # XXX(ot): disable package if something goes wrong? pkg = box.create_package(basename, app_name=name, app_version=version, enabled=False) if os.path.exists(os.path.join(source_dir, 'configure')): cmd_list = [ "./configure --prefix '%s' %s" % (pkg.path, configure_options), "make -j%d install" % cpu_count() ] elif os.path.exists(os.path.join(source_dir, 'setup.py')): envvars = '' if SETUPTOOLS_WORKAROUND: # Workaround two bugs of setuptools # (fixed in http://bugs.python.org/setuptools/issue54 ) # - Put the site-packages path in python's path # - Create the site-packages directory # XXX(ot): find a better solution # XXX(ot): this assumes that python inside the box is the same as the current python_version = '.'.join([str(x) for x in sys.version_info[:2]]) site_path = '%s/lib/python%s/site-packages/' % (pkg.path, python_version) envvars = 'PYTHONPATH="%s${PYTHONPATH:+:$PYTHONPATH}"' % site_path try: os.makedirs(site_path) except OSError: pass cmd_list = [ "%s python setup.py install --prefix '%s' %s" % (envvars, pkg.path, configure_options), ] else: raise UnsupportedPath('Do not know how to build source') log.info('Building and installing as package %s', pkg.name) for cmd in cmd_list: check_call(['bash', '-e', box.env_script, cmd], cwd=source_dir, stdout=stdout) box.enable_package(pkg)
def sync(self): '''Recreate all the symlinks and the env script, restoring the consistency of the box.''' # Clean all symlinks for d in DYN_DIRS: d_path = os.path.join(self.path, d) shutil.rmtree(d_path) os.makedirs(d_path) # Relink all packages for package in self.packages(only_enabled=True): self._link_package(package) self._create_env_script() log.info('Synchronized box')
def build(self, box, name_suffix='', stdout=None): appname = self.get_var('BPT_APP_NAME') version = self.get_var('BPT_APP_VERSION') # Check last box the sourcedir was built in bpt_status_file = os.path.join(self.path, '.bpt_status') if os.path.exists(bpt_status_file): bpt_status = load_info(bpt_status_file) last_box_id = bpt_status.get('last_box_id', box.box_id) if last_box_id != box.box_id: log.info( 'Intermediate files built for another package box. Cleaning first.' ) self.clean() # Write the current box_id store_info(bpt_status_file, dict(last_box_id=box.box_id)) if not box.check_platform(): raise UserError( 'Current platform is different from box\'s platform') pkg_name = '%s-%s%s' % (appname, version, name_suffix) pkg = box.create_package(pkg_name, app_name=appname, app_version=version, enabled=False) log.info('Building application %s, in sourcedir %s', appname, self._sourcedir) # Build sh_line = ('source "%s";' % BASE_SH_SCRIPT + 'cd "%s";' % self._sourcedir + 'export BPT_PKG_PREFIX="%s";' % pkg.path + 'export BPT_CPU_COUNT="%d";' % cpu_count() + 'source bpt-rules;' + 'bpt_download;' + 'bpt_unpack;' + 'bpt_build;') retcode = call(['bash', '-e', box.env_script, sh_line], stdout=stdout) if retcode != 0: raise UserError('FATAL: build script exited with status %s' % retcode) box.enable_package(pkg) return pkg
def build(self, box, name_suffix='', stdout=None): appname = self.get_var('BPT_APP_NAME') version = self.get_var('BPT_APP_VERSION') # Check last box the sourcedir was built in bpt_status_file = os.path.join(self.path, '.bpt_status') if os.path.exists(bpt_status_file): bpt_status = load_info(bpt_status_file) last_box_id = bpt_status.get('last_box_id', box.box_id) if last_box_id != box.box_id: log.info('Intermediate files built for another package box. Cleaning first.') self.clean() # Write the current box_id store_info(bpt_status_file, dict(last_box_id=box.box_id)) if not box.check_platform(): raise UserError('Current platform is different from box\'s platform') pkg_name = '%s-%s%s' % (appname, version, name_suffix) pkg = box.create_package(pkg_name, app_name=appname, app_version=version, enabled=False) log.info('Building application %s, in sourcedir %s', appname, self._sourcedir) # Build sh_line = ('source "%s";' % BASE_SH_SCRIPT + 'cd "%s";' % self._sourcedir + 'export BPT_PKG_PREFIX="%s";' % pkg.path + 'export BPT_CPU_COUNT="%d";' % cpu_count() + 'source bpt-rules;' + 'bpt_download;' + 'bpt_unpack;' + 'bpt_build;' ) retcode = call(['bash', '-e', box.env_script, sh_line], stdout=stdout) if retcode != 0: raise UserError('FATAL: build script exited with status %s' % retcode) box.enable_package(pkg) return pkg
def build(self, box, name_suffix="", stdout=None): appname = self.get_var("BPT_APP_NAME") version = self.get_var("BPT_APP_VERSION") # Check last box the sourcedir was built in bpt_status_file = os.path.join(self.path, ".bpt_status") if os.path.exists(bpt_status_file): bpt_status = load_info(bpt_status_file) last_box_id = bpt_status.get("last_box_id", box.box_id) if last_box_id != box.box_id: log.info("Intermediate files built for another package box. Cleaning first.") self.clean() # Write the current box_id store_info(bpt_status_file, dict(last_box_id=box.box_id)) if not box.check_platform(): raise UserError("Current platform is different from box's platform") pkg_name = "%s-%s%s" % (appname, version, name_suffix) pkg = box.create_package(pkg_name, app_name=appname, app_version=version, enabled=False) log.info("Building application %s, in sourcedir %s", appname, self._sourcedir) # Build sh_line = ( 'source "%s";' % BASE_SH_SCRIPT + 'cd "%s";' % self._sourcedir + 'export BPT_PKG_PREFIX="%s";' % pkg.path + "source bpt-rules;" + "bpt_download;" + "bpt_unpack;" + "bpt_build;" ) retcode = call(["bash", "-e", box.env_script, sh_line], stdout=stdout) if retcode != 0: raise UserError("FATAL: build script exited with status %s" % retcode) box.enable_package(pkg) return pkg
def main(argv, do_log=True): # set up default logging # TODO(giuott): Add a verbosity option if do_log: logging.basicConfig() log.setLevel(logging.INFO) try: parser = setup_optparse() options, args = parser.parse_args(argv[1:]) except ParserExit: return 0 if not args: parser.print_help() return 255 command = args[0] cmd_args = args[1:] config = Config() try: if options.box_path is not None: config.box = Box(options.box_path) else: config.box = get_current_box() if config.box is not None: log.info('Using current box "%s"', config.box.name) return ui.command.dispatch(command, config, cmd_args) except ui.command.CommandNotFound: log.error("Command %s not found", command) parser.print_help() return 255 except bpt.UserError, exc: log.error('Aborting: %s', str(exc)) return 1
for directory in STANDARD_DIRS: os.makedirs(os.path.join(dest_path, directory)) except OSError, exc: raise UserError( 'Impossible to create destination directories: "%s"' % str(exc)) box_info = dict() box_info['id'] = str(uuid1()) box_info['platform'] = _get_platform() box_info['bpt_version'] = bpt.__version__ store_info(os.path.join(dest_path, 'bpt_meta', 'box_info'), box_info) box = cls(dest_path) box.sync() log.info('Created box with id %s in directory %s', box.box_id, box.path) return box def sync(self): '''Recreate all the symlinks and the env script, restoring the consistency of the box.''' # Clean all symlinks for d in DYN_DIRS: d_path = os.path.join(self.path, d) shutil.rmtree(d_path) os.makedirs(d_path) # Relink all packages for package in self.packages(only_enabled=True): self._link_package(package)
os.makedirs(dest_path) for directory in STANDARD_DIRS: os.makedirs(os.path.join(dest_path, directory)) except OSError, exc: raise UserError('Impossible to create destination directories: "%s"' % str(exc)) box_info = dict() box_info['id'] = str(uuid1()) box_info['platform'] = _get_platform() box_info['bpt_version'] = bpt.__version__ store_info(os.path.join(dest_path, 'bpt_meta', 'box_info'), box_info) box = cls(dest_path) box.sync() log.info('Created box with id %s in directory %s', box.box_id, box.path) return box def sync(self): '''Recreate all the symlinks and the env script, restoring the consistency of the box.''' # Clean all symlinks for d in DYN_DIRS: d_path = os.path.join(self.path, d) shutil.rmtree(d_path) os.makedirs(d_path) # Relink all packages for package in self.packages(only_enabled=True): self._link_package(package)