def execute(self): if len(self.actions) == 0: ui.logger(__name__).warning('No actions necessary.') return location = self.project.location tfd, tfn = tempfile.mkstemp(prefix='pros-project-', suffix=f'-{self.project.name}.zip', text='w+b') with os.fdopen(tfd, 'w+b') as tf: with zipfile.ZipFile(tf, mode='w') as zf: files, length = it.tee(location.glob('**/*'), 2) length = len(list(length)) with ui.progressbar(files, length=length, label=f'Backing up {self.project.name} to {tfn}') as pb: for file in pb: zf.write(file, arcname=file.relative_to(location)) try: with ui.Notification(): for action in self.actions: ui.logger(__name__).debug(action.describe(self.conductor, self.project)) rv = action.execute(self.conductor, self.project) ui.logger(__name__).debug(f'{action} returned {rv}') if rv is not None and not rv: raise ValueError('Action did not complete successfully') ui.echo('All actions performed successfully') except Exception as e: ui.logger(__name__).warning(f'Failed to perform transaction, restoring project to previous state') with zipfile.ZipFile(tfn) as zf: with ui.progressbar(zf.namelist(), label=f'Restoring {self.project.name} from {tfn}') as pb: for file in pb: zf.extract(file, path=location) ui.logger(__name__).exception(e) finally: ui.echo(f'Removing {tfn}') os.remove(tfn)
def test(): ui.echo('Hello World!') with ui.Notification(): ui.echo('Hello from another box') ui.echo('Back on the other one', nl=False) ui.echo('Whoops I missed a newline') with ui.Notification(): ui.echo('Yet another box') with ui.progressbar(range(20)) as bar: for _ in bar: time.sleep(0.1) ui.echo('more below the ', nl=False) ui.echo('progressbar') ui.echo('Back in the other notification') logger(__name__).warning('Hello') try: raise Exception('Hey') except Exception as e: logger(__name__).exception(e) ui.finalize('test', {'hello': 'world'}, human_prefix='Created ')
def confirm(self, *args, **kwargs): assert self.can_confirm self.exit() project = self.conductor.new_project( path=self.directory.value, target=self.targets.value, version=self.kernel_versions.value, no_default_libs=not self.install_default_libraries.value, project_name=self.project_name.value) from pros.conductor.project import ProjectReport report = ProjectReport(project) ui.finalize('project-report', report) with ui.Notification(): ui.echo('Building project...') project.compile([])
def new_project(ctx: click.Context, path: str, target: str, version: str, force_user: bool = False, force_system: bool = False, no_default_libs: bool = False, compile_after: bool = True, build_cache: bool = None, **kwargs): """ Create a new PROS project Visit https://pros.cs.purdue.edu/v5/cli/conductor.html to learn more """ if version.lower() == 'latest' or not version: version = '>0' if not force_system and c.Project.find_project(path) is not None: logger(__name__).error( 'A project already exists in this location! Delete it first', extra={'sentry': False}) ctx.exit(-1) try: _conductor = c.Conductor() if target is None: target = _conductor.default_target project = _conductor.new_project(path, target=target, version=version, force_user=force_user, force_system=force_system, no_default_libs=no_default_libs, **kwargs) ui.echo('New PROS Project was created:', output_machine=False) ctx.invoke(info_project, project=project) if compile_after or build_cache: with ui.Notification(): ui.echo('Building project...') ctx.exit(project.compile([], scan_build=build_cache)) except Exception as e: pros.common.logger(__name__).exception(e) ctx.exit(-1)
def get_remote_templates(self, auto_check_freq: Optional[timedelta] = None, force_check: bool = False, **kwargs): if auto_check_freq is None: auto_check_freq = getattr(self, 'update_frequency', cli_config().update_frequency) logger(__name__).info( f'Last check of {self.name} was {self.last_remote_update} ' f'({datetime.now() - self.last_remote_update} vs {auto_check_freq}).' ) if force_check or datetime.now( ) - self.last_remote_update > auto_check_freq: with ui.Notification(): ui.echo(f'Updating {self.name}... ', nl=False) self.update_remote_templates(**kwargs) ui.echo('Done', color='green') for t in self.remote_templates: t.metadata['origin'] = self.name return self.remote_templates
def prompt_to_send(event: Dict[str, Any], hint: Optional[Dict[str, Any]]) -> Optional[Dict[str, Any]]: """ Asks the user for permission to send data to Sentry """ global cli_config with ui.Notification(): if cli_config is None or (cli_config.offer_sentry is not None and not cli_config.offer_sentry): return if 'extra' in event and not event['extra'].get('sentry', True): ui.logger(__name__).debug('Not sending candidate event because event was tagged with extra.sentry = False') return if 'exc_info' in hint and (not getattr(hint['exc_info'][1], 'sentry', True) or any(isinstance(hint['exc_info'][1], t) for t in SUPPRESSED_EXCEPTIONS)): ui.logger(__name__).debug('Not sending candidate event because exception was tagged with sentry = False') return if not event['tags']: event['tags'] = dict() extra_text = '' if 'message' in event: extra_text += event['message'] + '\n' if 'culprit' in event: extra_text += event['culprit'] + '\n' if 'logentry' in event and 'message' in event['logentry']: extra_text += event['logentry']['message'] + '\n' if 'exc_info' in hint: import traceback extra_text += ''.join(traceback.format_exception(*hint['exc_info'], limit=4)) event['tags']['confirmed'] = ui.confirm('We detected something went wrong! Do you want to send a report?', log=extra_text) if event['tags']['confirmed']: ui.echo('Sending bug report.') ui.echo(f'Want to get updates? Visit https://pros.cs.purdue.edu/report.html?event={event["event_id"]}') return event else: ui.echo('Not sending bug report.')