def do_sync(self, args): """ Synchronizes installed application with the specfile. """ if (not os.path.exists(args.file)) or (not os.path.isfile(args.file)): logger.error('file not found: %s' % Color.GREEN+args.file+Color.END) return specs = self.load_specs(args.file) if specs is None: return self.setup_config_dir(specs['path']) rootpath = specs['path'] for app_name in specs['apps']: app_specs = specs['apps'][app_name] if not app_specs['path'].startswith(os.path.sep): app_specs['path'] = os.path.join(rootpath, app_specs['path']) app = AppFactory.load(self, app_name, app_specs) app.sync() if app.is_updated: app.build() if args.unlisted: for _, folder in find_versionned_folders(rootpath): folder, app_name = os.path.split(folder) logger.warn('found unlisted application in %s: %s' % ( folder, Color.GREEN+app_name+Color.END ))
def download(self): fname = self.url.split('/')[-1].split('?')[0] temppath = os.path.join(gettempdir(), fname) opener = urlopen(self.url) try: data = opener.read() except Exception as err: log_to_file(str(err)) # self._log_output(err) return False with open(temppath, 'wb') as ofile: ofile.write(data) handler = None for extension in self.archive_handlers: if fname.endswith(extension): handler = self.archive_handlers[extension] break if handler is None: logger.error('unsupported archive for application %s' % Color.GREEN+self.name+Color.END) return False mode = 'r' archive_type = fname.split('.')[-1] if archive_type in ('gz', 'bz2'): mode = 'r:%s' % archive_type archive = handler(temppath, mode=mode) archive.extractall(self.path) os.remove(temppath) self.is_updated = True return True
def update(self): if self.app_type not in self.update_commands: logger.error('unsupported VCS for application %s' % Color.GREEN+self.name+Color.END) return False op_ok = False with chdir(self.path): cmds = self.update_commands[self.app_type] for cmd in cmds: op_ok = run_command(cmd) if not op_ok: break self.is_updated = op_ok # TODO: check if some changes have been pulled return op_ok
def run_command(cmd): logger.debug('running external command: %s' % Color.GREEN + cmd + Color.END) cmd = shlex.split(cmd) p = Popen(cmd, shell=False, stdout=PIPE, stderr=PIPE) stdout, stderr = p.communicate() # display STDOUT content if stdout: for line in stdout.splitlines(): logger.debug(Color.BLUE+line+Color.END) # display an error (STDERR or generic message) if returncode is non-zero if p.returncode != 0: tmpname = log_to_file(stderr) logger.error('an error occured, see %s for more details' % (Color.GREEN+tmpname+Color.END)) return False return True
def load_specs(self, fpath): """ Loads a specifications file and checks for missing fields. """ with open(fpath) as ifile: logger.debug('loading specfile: %s' % Color.GREEN+fpath+Color.END) data = json.load(ifile) for field in self.tba_required_fields: if field not in data: logger.error('missing top-level field in specs: %s' % Color.GREEN+field+Color.END) return None for app_name in data['apps']: app_specs = data['apps'][app_name] for app_field in self.app_required_fields: if app_field not in app_specs: logger.error('missing app field in specs: %s' % Color.GREEN+app_field+Color.END) return None return data
def do_genspec(self, args): """ Scans current folder for versionned applications and creates a specfile accordingly. """ self.setup_config_dir(args.path) new_specs = { 'path': args.path, 'apps': {} } if args.merge is not None: new_specs = self.load_specs(args.merge) apps_specs = new_specs['apps'] new_apps_found = False for vcs_type, app_folder in find_versionned_folders(args.path): app_path = app_folder[len(args.path)+1:] if app_path not in [apps_specs[a]['path'] for a in apps_specs]: new_apps_found = True folder, app_name = os.path.split(app_folder) logger.info('found%s application in %s: %s (%s)' % ( ' new' if args.merge is not None else '', folder, Color.GREEN+app_name+Color.END, vcs_type )) cfg_file, regex, handler = self.vcs_repo_finders[vcs_type] cfg_path = os.path.join(app_folder, cfg_file) app_specs = { 'type': vcs_type, 'url': handler(regex, cfg_path), 'path': app_path, } apps_specs[app_name] = app_specs if new_apps_found: outfile = args.merge or args.file if os.path.exists(outfile): logger.warning('file already exists: %s' % Color.GREEN+outfile+Color.END) if not yes_no('Overwrite ?'): logger.error('operation aborted by user') return with open(outfile, 'w') as ofile: json.dump(new_specs, ofile, sort_keys=True, indent=2, separators=(',', ': ')) logger.info('specfile written to %s' % Color.GREEN+outfile+Color.END) logger.info('you may now add build information to the new specfile') else: logger.info('no new application found')
def download(self): if self.app_type not in self.download_commands: logger.error('unsupported VCS for application %s' % Color.GREEN+self.name+Color.END) return False cmd = self.download_commands[self.app_type] % (self.url, self.path) return run_command(cmd)