Skip to content

Commit

Permalink
Merge branch 'develop' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
kunwarsahni01 authored Nov 19, 2021
2 parents f9c9987 + fcb3094 commit 8bdd99a
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 55 deletions.
50 changes: 32 additions & 18 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
variables:
python.version.linux: '3.7.x'
python.version.windows: '3.7.x'
python.version: '3.9.x'

jobs:
- job: UpdateBuildNumber
timeoutInMinutes: 5
pool:
vmImage: ubuntu-18.04
vmImage: ubuntu-latest

steps:
- task: UsePythonVersion@0
inputs:
versionSpec: $(python.version.linux)
versionSpec: $(python.version)
architecture: x64
- script: python version.py
- bash: echo "##vso[build.UpdateBuildNumber]`cat version`"
Expand All @@ -27,13 +26,13 @@ jobs:
x86:
buildArch: x86
pool:
vmImage: vs2017-win2016
vmImage: windows-latest
steps:
- powershell: choco install 7zip.install -y
displayName: Install 7z
- task: UsePythonVersion@0
inputs:
versionSpec: $(python.version.windows)
versionSpec: $(python.version)
architecture: $(buildArch)
- powershell: scripts/build.ps1
displayName: Build
Expand All @@ -42,6 +41,28 @@ jobs:
artifactName: 'pros_cli-$(Build.BuildNumber)-win-$(buildArch)'
targetPath: 'out'

- job: macOS
timeoutInMinutes: 30
dependsOn: UpdateBuildNumber
strategy:
maxParallel: 2
matrix:
x64:
buildArch: x64
pool:
vmImage: macos-latest
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: $(python.version)
architecture: $(buildArch)
- bash: scripts/build.sh
displayName: Build
- task: PublishPipelineArtifact@0
inputs:
artifactName: 'pros_cli-$(Build.BuildNumber)-macos-$(buildArch)'
targetPath: 'out'

- job: Linux
timeoutInMinutes: 30
dependsOn: UpdateBuildNumber
Expand All @@ -50,21 +71,12 @@ jobs:
matrix:
x64:
buildArch: x64
# x86:
# buildArch: x86
pool:
vmImage: ubuntu-18.04
vmImage: ubuntu-latest
steps:
# Microsoft/azure-pipelines-image-generation#225
# - bash: |
# sudo apt-add-repository ppa:deadsnakes/ppa
# sudo apt-get update
# sudo apt-get install python3.6 python3.6-dev python3-setuptools
# displayName: Use Python 3.6
# Hopefully this will work soon
- task: UsePythonVersion@0
inputs:
versionSpec: $(python.version.linux)
versionSpec: $(python.version)
architecture: $(buildArch)
- bash: scripts/build.sh
displayName: Build
Expand All @@ -77,11 +89,13 @@ jobs:
dependsOn:
- UpdateBuildNumber
- Linux
pool:
vmImage: ubuntu-latest
condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq(variables['Build.SourceBranch'], 'refs/heads/develop'), startsWith(variables['Build.SourceBranch'], 'refs/tags/')))
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: $(python.version.linux)
versionSpec: $(python.version)
architecture: x64
- checkout: none
- task: DownloadPipelineArtifact@2
Expand Down
2 changes: 1 addition & 1 deletion pip_version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.2.2
3.2.2
20 changes: 19 additions & 1 deletion pros/cli/click_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,24 @@ def get_help_record(self, ctx):
return
return super().get_help_record(ctx)

class PROSDeprecated(click.Option):
def __init__(self, *args, replacement: str = None, **kwargs):
kwargs['help'] = "This option has been deprecated."
if not replacement==None:
kwargs['help'] += " Its replacement is '--{}'".format(replacement)
super(PROSDeprecated, self).__init__(*args, **kwargs)
self.group = "Deprecated"
self.optiontype = "flag" if str(self.type)=="BOOL" else "switch"
self.to_use = replacement
self.arg = args[0][len(args[0])-1]
self.msg = "The '{}' {} has been deprecated. Please use '--{}' instead."
if replacement==None:
self.msg = self.msg.split(".")[0]+"."

def type_cast_value(self, ctx, value):
if not value==self.default:
print("Warning! : "+self.msg.format(self.arg, self.optiontype, self.to_use)+"\n")
return value

class PROSGroup(PROSFormatted, click.Group):
def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -130,4 +148,4 @@ class PROSRoot(PROSGroup):


class PROSCommandCollection(PROSFormatted, click.CommandCollection):
pass
pass
3 changes: 2 additions & 1 deletion pros/cli/conductor.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ def new_project(ctx: click.Context, path: str, target: str, version: str,
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})
logger(__name__).error('A project already exists in this location at ' + c.Project.find_project(path) +
'! Delete it first. Are you creating a project in an existing one?', extra={'sentry': False})
ctx.exit(-1)
try:
_conductor = c.Conductor()
Expand Down
48 changes: 28 additions & 20 deletions pros/cli/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,23 @@ def upload_cli():
@click.argument('path', type=click.Path(exists=True), default=None, required=False)
@click.argument('port', type=str, default=None, required=False)
@project_option(required=False, allow_none=True)
@click.option('--run-after/--no-run-after', 'run_after', default=True, help='Immediately run the uploaded program')
@click.option('-q', '--quirk', type=int, default=0)
@click.option('--name', 'remote_name', type=str, default=None, required=False, help='Remote program name',
@click.option('--run-after/--no-run-after', 'run_after', default=None, help='Immediately run the uploaded program.',
cls=PROSDeprecated, replacement='after')
@click.option('--run-screen/--execute', 'run_screen', default=None, help='Display run program screen on the brain after upload.',
cls=PROSDeprecated, replacement='after')
@click.option('-af', '--after', type=click.Choice(['run','screen','none']), default=None, help='Action to perform on the brain after upload.',
cls=PROSOption, group='V5 Options')
@click.option('--slot', default=None, type=click.IntRange(min=1, max=8), help='Program slot on the GUI',
@click.option('--quirk', type=int, default=0)
@click.option('--name', 'remote_name', type=str, default=None, required=False, help='Remote program name.',
cls=PROSOption, group='V5 Options')
@click.option('--program-version', default=None, type=str, help='Specify version metadata for program',
@click.option('--slot', default=None, type=click.IntRange(min=1, max=8), help='Program slot on the GUI.',
cls=PROSOption, group='V5 Options')
@click.option('--program-version', default=None, type=str, help='Specify version metadata for program.',
cls=PROSOption, group='V5 Options', hidden=True)
@click.option('--icon', default=None, type=str,
cls=PROSOption, group='V5 Options', hidden=True)
@click.option('--ini-config', type=click.Path(exists=True), default=None, help='Specify a Program Configuration File',
@click.option('--ini-config', type=click.Path(exists=True), default=None, help='Specify a program configuration file.',
cls=PROSOption, group='V5 Options', hidden=True)
@click.option('--run-screen/--execute', 'run_screen', default=True,
cls=PROSOption, group='V5 Options', help='Open "run program" screen after uploading, instead of executing'
' program. This option may help with controller connectivity '
'reliability and prevent robots from running off tables.')
@click.option('--compress-bin/--no-compress-bin', 'compress_bin', cls=PROSOption, group='V5 Options', default=True,
help='Compress the program binary before uploading.')
@default_options
Expand Down Expand Up @@ -62,9 +63,8 @@ def upload(path: Optional[str], project: Optional[c.Project], port: str, **kwarg
options = dict(**project.upload_options)
if 'slot' in options and kwargs.get('slot', None) is None:
kwargs.pop('slot')
elif kwargs.get('slot', None) is None:
elif kwargs.get('slot', None) is None:
kwargs['slot'] = 1

options.update(kwargs)
kwargs = options

Expand Down Expand Up @@ -93,18 +93,27 @@ def upload(path: Optional[str], project: Optional[c.Project], port: str, **kwarg
kwargs['remote_name'] = os.path.splitext(os.path.basename(path))[0]
kwargs['remote_name'] = kwargs['remote_name'].replace('@', '_')
kwargs['slot'] -= 1
if kwargs['run_after'] and kwargs['run_screen']:
kwargs['run_after'] = vex.V5Device.FTCompleteOptions.RUN_SCREEN
elif kwargs['run_after'] and not kwargs['run_screen']:
kwargs['run_after'] = vex.V5Device.FTCompleteOptions.RUN_IMMEDIATELY
else:
kwargs['run_after'] = vex.V5Device.FTCompleteOptions.DONT_RUN

action_to_kwarg = {
'run' : vex.V5Device.FTCompleteOptions.RUN_IMMEDIATELY,
'screen' : vex.V5Device.FTCompleteOptions.RUN_SCREEN,
'none' : vex.V5Device.FTCompleteOptions.DONT_RUN
}
after_upload_default = 'screen'
#Determine which FTCompleteOption to assign to run_after
if kwargs['after']==None:
kwargs['after']=after_upload_default
if kwargs['run_after']:
kwargs['after']='run'
elif kwargs['run_screen']==False and not kwargs['run_after']:
kwargs['after']='none'
kwargs['run_after'] = action_to_kwarg[kwargs['after']]
kwargs.pop('run_screen')
kwargs.pop('after')
elif kwargs['target'] == 'cortex':
pass

logger(__name__).debug('Arguments: {}'.format(str(kwargs)))

# Do the actual uploading!
try:
ser = DirectPort(port)
Expand All @@ -122,7 +131,6 @@ def upload(path: Optional[str], project: Optional[c.Project], port: str, **kwarg
logger(__name__).exception(e, exc_info=True)
exit(1)


@upload_cli.command('lsusb', aliases=['ls-usb', 'ls-devices', 'lsdev', 'list-usb', 'list-devices'])
@click.option('--target', type=click.Choice(['v5', 'cortex']), default=None, required=False)
@default_options
Expand Down
20 changes: 11 additions & 9 deletions pros/common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,22 @@ def download_file(url: str, ext: Optional[str] = None, desc: Optional[str] = Non
"""
import requests
from pros.common.ui import progressbar
from rfc6266_parser import parse_requests_response
# from rfc6266_parser import parse_requests_response
import re

response = requests.get(url, stream=True)
if response.status_code == 200:
filename: str = url.rsplit('/', 1)[-1]
if 'Content-Disposition' in response.headers.keys():
try:
disposition = parse_requests_response(response)
if isinstance(ext, str):
filename = disposition.filename_sanitized(ext)
else:
filename = disposition.filename_unsafe
except RuntimeError:
pass
filename = re.findall("filename=(.+)", response.headers['Content-Disposition'])[0]
# try:
# disposition = parse_requests_response(response)
# if isinstance(ext, str):
# filename = disposition.filename_sanitized(ext)
# else:
# filename = disposition.filename_unsafe
# except RuntimeError:
# pass
output_path = os.path.join(get_pros_dir(), 'download', filename)

if os.path.exists(output_path):
Expand Down
22 changes: 20 additions & 2 deletions pros/conductor/project/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,17 @@ def make(self, build_args: List[str]):
make_cmd = 'make'
stdout_pipe = EchoPipe()
stderr_pipe = EchoPipe(err=True)
process = subprocess.Popen(executable=make_cmd, args=[make_cmd, *build_args], cwd=self.directory, env=env,
process=None
try:
process = subprocess.Popen(executable=make_cmd, args=[make_cmd, *build_args], cwd=self.directory, env=env,
stdout=stdout_pipe, stderr=stderr_pipe)
except Exception as e:
if not os.environ.get('PROS_TOOLCHAIN'):
ui.logger(__name__).warn("PROS toolchain not found! Please ensure the toolchain is installed correctly and your environment variables are set properly.\n")
ui.logger(__name__).error(f"ERROR WHILE CALLING '{make_cmd}.exe' WITH EXCEPTION: {str(e)}\n")
stdout_pipe.close()
stderr_pipe.close()
sys.exit()
stdout_pipe.close()
stderr_pipe.close()
process.wait()
Expand Down Expand Up @@ -275,7 +284,16 @@ def libscanbuild_capture(args: argparse.Namespace) -> Tuple[int, Iterable[Compil
else:
pipe = subprocess.DEVNULL
logger(__name__).debug(self.directory)
exit_code = run_build(args.build, env=environment, stdout=pipe, stderr=pipe, cwd=self.directory)
exit_code=None
try:
exit_code = run_build(args.build, env=environment, stdout=pipe, stderr=pipe, cwd=self.directory)
except Exception as e:
if not os.environ.get('PROS_TOOLCHAIN'):
ui.logger(__name__).warn("PROS toolchain not found! Please ensure the toolchain is installed correctly and your environment variables are set properly.\n")
ui.logger(__name__).error(f"ERROR WHILE CALLING '{make_cmd}.exe' WITH EXCEPTION: {str(e)}\n")
if not suppress_output:
pipe.close()
sys.exit()
if not suppress_output:
pipe.close()
# read the intercepted exec calls
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ colorama
pyzmq
cobs
scan-build==2.0.13
rfc6266-parser
sentry-sdk
observable
pypng==0.0.20
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.2.2
3.2.2
2 changes: 1 addition & 1 deletion win_version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.2.2.0
3.2.2.0

0 comments on commit 8bdd99a

Please sign in to comment.