Skip to content

Commit

Permalink
Merge pull request #27 from nrobinson2000/feat/poetry
Browse files Browse the repository at this point in the history
Migrate to poetry and fix some bugs
  • Loading branch information
nrobinson2000 authored May 23, 2024
2 parents f061fa6 + 849937b commit e649016
Show file tree
Hide file tree
Showing 25 changed files with 781 additions and 325 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python-pip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
python-version: [3.9]
python-version: [3.11]

steps:
- uses: actions/checkout@v2
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ neopo/neopo.c
Makefile
temp
venv
poetry.lock
3 changes: 2 additions & 1 deletion ci/test-neopo.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#Attempt to use neopo as python module to configure and build project
# Attempt to use neopo as python module to configure and build project
import neopo

neopo.create("testpy", "argon", "2.0.0-rc.3")
neopo.build("testpy")
7 changes: 5 additions & 2 deletions completion/generate.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from neopo.command import commands, iterable_commands, legacy_commands

print(r'''# neopo(1) completion
print(
r"""# neopo(1) completion
# depends on jq(1)
_find_toolchains() {
Expand Down Expand Up @@ -141,4 +142,6 @@
COMPREPLY=($(compgen -W "$_iterable" -- "$cur"));;
esac
} &&
complete -F _neopo neopo''' % (" ".join(commands.keys()), " ".join(iterable_commands.keys())))
complete -F _neopo neopo"""
% (" ".join(commands.keys()), " ".join(iterable_commands.keys()))
)
30 changes: 24 additions & 6 deletions neopo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,31 @@

# Disable RuntimeWarning for neopo.particle and neopo.script
import warnings

warnings.filterwarnings("ignore", category=RuntimeWarning)

# Import module api
from .cli import (
build,
clean,
configure,
create,
flags,
flash,
flash_all,
get,
install,
iterate,
legacy,
libs,
main,
particle,
run,
script,
settings,
uninstall,
update,
upgrade,
versions,
)
from .command import script_wait
from .cli import main, particle
from .cli import iterate, legacy, script
from .cli import install, upgrade, uninstall, versions, create
from .cli import build, flash, flash_all, clean
from .cli import run, configure, flags, settings, libs
from .cli import update, get
1 change: 1 addition & 0 deletions neopo/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# https://neopo.xyz

import sys

from .command import main

if __name__ == "__main__":
Expand Down
100 changes: 75 additions & 25 deletions neopo/build.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
import os
import time
import pathlib
import subprocess
import time

# Local imports
from .common import PARTICLE_DEPS, running_on_windows, particle_cli, projectFiles
from .common import ProcessError, ProjectError, UserError, min_particle_env
from .manifest import load_manifest, get_manifest_value
from .project import get_settings, check_libraries, get_flags
from .toolchain import get_compiler, check_firmware_version, get_firmware_path, platform_convert
from .common import (
PARTICLE_DEPS,
ProcessError,
ProjectError,
UserError,
min_particle_env,
particle_cli,
projectFiles,
running_on_windows,
)
from .manifest import get_manifest_value, load_manifest
from .project import check_libraries, get_flags, get_settings
from .toolchain import (
check_firmware_version,
get_compiler,
get_firmware_path,
platform_convert,
)
from .utility import write_executable


# Export a build command to a script
def export_build_process(project_path, process, environment, target):
path = os.path.join(project_path, "bin")
Expand All @@ -30,17 +44,20 @@ def export_build_process(project_path, process, environment, target):

print("Exported to %s" % script)


# Add a path to an environment
def add_to_path(environment, path):
environment["PATH"] += os.pathsep + path


# Add buildtools to PATH
def add_build_tools(environment, version=None):
tools_version = version if version else get_manifest_value("buildtools")
toolpath = os.path.join(PARTICLE_DEPS, "buildtools", tools_version)
toolpath = os.path.join(toolpath, "bin") if running_on_windows else toolpath
add_to_path(environment, toolpath)


# Build and flash bootloader to connected device [WIP]
def flash_bootloader(platform, firmware_version, verbosity=1):
bootloader_bin = build_bootloader(platform, firmware_version, verbosity)
Expand All @@ -50,22 +67,24 @@ def flash_bootloader(platform, firmware_version, verbosity=1):

try:
subprocess.run(usb_listen, env=temp_env, shell=running_on_windows, check=True)
time.sleep(2) # Account for device to enter listening mode
time.sleep(2) # Account for device to enter listening mode
subprocess.run(serial_flash, env=temp_env, shell=running_on_windows, check=True)
# Return cleanly if ^C was pressed
except KeyboardInterrupt:
return
except subprocess.CalledProcessError:
return


# Build bootloader and return path to built file [WIP]
def build_bootloader(platform, firmware_version, verbosity=1):
compiler_version, script_version, tools_version, _ = load_manifest()

temp_env = min_particle_env()
add_build_tools(temp_env, tools_version)
add_to_path(temp_env, os.path.join(
PARTICLE_DEPS, "gcc-arm", compiler_version, "bin"))
add_to_path(
temp_env, os.path.join(PARTICLE_DEPS, "gcc-arm", compiler_version, "bin")
)

device_os_path = os.path.join(PARTICLE_DEPS, "deviceOS", firmware_version)
bootloader = os.path.join(device_os_path, "bootloader")
Expand All @@ -75,24 +94,36 @@ def build_bootloader(platform, firmware_version, verbosity=1):
OLDPWD = os.path.abspath(os.curdir)
try:
os.chdir(bootloader)
subprocess.run(process, env=temp_env, shell=running_on_windows, check=True,
stdout=subprocess.PIPE if verbosity == -1 else None,
stderr=subprocess.PIPE if verbosity == -1 else None)
subprocess.run(
process,
env=temp_env,
shell=running_on_windows,
check=True,
stdout=subprocess.PIPE if verbosity == -1 else None,
stderr=subprocess.PIPE if verbosity == -1 else None,
)
except subprocess.CalledProcessError as error:
pass
finally:
os.chdir(OLDPWD)

platform_id = platform_convert(platform, "name", "id")

target = os.path.join(device_os_path, "build", "target", "bootloader",
"platform-%s-m-lto" % platform_id, "bootloader.bin")
target = os.path.join(
device_os_path,
"build",
"target",
"bootloader",
"platform-%s-m-lto" % platform_id,
"bootloader.bin",
)

if os.path.isfile(target):
return target
else:
raise ProcessError("%s was not built!" % target)


# Use the Makefile to build the specified target
def build_project(project_path, command, help_only, verbosity, export=False):
compiler_version, script_version, tools_version, firmware_version = load_manifest()
Expand All @@ -108,9 +139,10 @@ def build_project(project_path, command, help_only, verbosity, export=False):

# Command used to invoke the Workbench makefile
process = [
"make", "-f", os.path.join(PARTICLE_DEPS,
"buildscripts", script_version, "Makefile"),
"PARTICLE_CLI_PATH=" + particle
"make",
"-f",
os.path.join(PARTICLE_DEPS, "buildscripts", script_version, "Makefile"),
"PARTICLE_CLI_PATH=" + particle,
]

# Add [-s] flag to make to silence output
Expand All @@ -133,13 +165,17 @@ def build_project(project_path, command, help_only, verbosity, export=False):
except (FileNotFoundError, KeyError) as error:
if os.path.isfile(os.path.join(project_path, projectFiles["properties"])):
raise ProjectError(
"Project not configured!\nUse: neopo configure <platform> <version> <project>") from error
"Project not configured!\nUse: neopo configure <platform> <version> <project>"
) from error
else:
raise UserError("%s is not a Particle project!" % project_path) from error
raise UserError(
"%s is not a Particle project!" % project_path
) from error

# Add compiler to path
add_to_path(temp_env, os.path.join(
PARTICLE_DEPS, "gcc-arm", compiler_version, "bin"))
add_to_path(
temp_env, os.path.join(PARTICLE_DEPS, "gcc-arm", compiler_version, "bin")
)

# Set additional variables for make
device_os_path = get_firmware_path(firmware_version)
Expand All @@ -157,12 +193,18 @@ def build_project(project_path, command, help_only, verbosity, export=False):

# Run makefile with given verbosity
try:
subprocess.run(process, env=temp_env, shell=running_on_windows, check=True,
stdout=subprocess.PIPE if verbosity == -1 else None,
stderr=subprocess.PIPE if verbosity == -1 else None)
subprocess.run(
process,
env=temp_env,
shell=running_on_windows,
check=True,
stdout=subprocess.PIPE if verbosity == -1 else None,
stderr=subprocess.PIPE if verbosity == -1 else None,
)
except subprocess.CalledProcessError as error:
raise ProcessError("\n*** %s FAILED ***\n" % command.upper()) from error


# Parse the project path from the specified index and run a Makefile target
def build_command(command, index, args, export=False):
verbose_index = index
Expand Down Expand Up @@ -193,10 +235,12 @@ def build_command(command, index, args, export=False):
# Build the given project with a command and verbosity
build_project(project, command, False, verbosity, export)


# Print help information directly from Makefile
def build_help():
build_project(None, None, True, 0)


# Wrapper for [run]
def run_command(args, export=False):
try:
Expand All @@ -205,23 +249,29 @@ def run_command(args, export=False):
build_help()
raise UserError("You must supply a Makefile target!") from error


# Wrappers for commands that build
def flash_command(args):
build_command("flash-user", 2, args)


def compile_command(args):
build_command("compile-user", 2, args)


def flash_all_command(args):
build_command("flash-all", 2, args)


def clean_command(args):
build_command("clean-user", 2, args)


# Wrapper for export
def export_command(args):
run_command(args, True)


# Wrapper for flash-bootloader
def flash_bootloader_command(args):
try:
Expand All @@ -235,7 +285,7 @@ def flash_bootloader_command(args):
verbosity = args[4]
except IndexError:
verbosity = None
verbosity_level=verbosity_dict[verbosity]
verbosity_level = verbosity_dict[verbosity]

if not check_firmware_version(device_platform, firmware_version):
raise ProjectError("Firmware related error!")
Expand Down
Loading

0 comments on commit e649016

Please sign in to comment.