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)
Exemple #2
0
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([])
Exemple #4
0
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)
Exemple #5
0
 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
Exemple #6
0
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.')