Skip to content

Add configuration UI #158

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 59 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
b739904
Initial project template
lucasssvaz Feb 21, 2024
352e85a
Fix EOF
lucasssvaz Feb 21, 2024
e2c0516
Simplify
lucasssvaz Feb 21, 2024
ed73ad9
Test
lucasssvaz Feb 28, 2024
bc48e6b
Fix
lucasssvaz Feb 29, 2024
ca29343
Improve Screens
lucasssvaz Feb 29, 2024
4cf89ba
Add placeholder Readme
lucasssvaz Feb 29, 2024
dc1539a
Remove unused imports
lucasssvaz Feb 29, 2024
c142e5b
Fix CWD
lucasssvaz Mar 1, 2024
6921aee
Fix target selection
lucasssvaz Mar 1, 2024
21092e4
Misc improvements
lucasssvaz Mar 1, 2024
1e986a7
WIP compile screen
lucasssvaz Mar 1, 2024
b21e885
Update
lucasssvaz Mar 1, 2024
f4701bb
Fix command
lucasssvaz Mar 1, 2024
430bb18
Finish compile screen
lucasssvaz Mar 1, 2024
2416cdf
Added comments and improvements
lucasssvaz Mar 1, 2024
6e9dd8f
Run on task
lucasssvaz Mar 2, 2024
88da64d
Make style a bit more Arduino-esque
me-no-dev Mar 2, 2024
bfd8159
Merge branch 'master' into feature/config_ui
lucasssvaz Mar 4, 2024
c53b7eb
Add CLI arguments
lucasssvaz Mar 6, 2024
18ce802
Merge branch 'master' into feature/config_ui
lucasssvaz Mar 6, 2024
683e548
Small improvements
lucasssvaz Mar 6, 2024
e9fbf63
Rename
lucasssvaz Mar 6, 2024
0d6d21a
Add custom widgets
lucasssvaz Mar 8, 2024
bb13cc0
Fix widgets
lucasssvaz Mar 8, 2024
b118528
Add remaining settings
lucasssvaz Mar 8, 2024
9f4becd
Improve style
lucasssvaz Mar 8, 2024
6a5319a
Improve compilation screen
lucasssvaz Mar 8, 2024
54f1082
Handle exception
lucasssvaz Mar 8, 2024
2d8e462
Add no copy argument
lucasssvaz Mar 9, 2024
f649a80
Replace "arch" with "uname -m"
lucasssvaz Mar 9, 2024
31dbd36
Merge branch 'bugfix/arch_cmd' into feature/config_ui
lucasssvaz Mar 9, 2024
4581265
Fix copy argument
lucasssvaz Mar 9, 2024
e735844
Fix arg message
lucasssvaz Mar 9, 2024
e2de23a
Fix chdir
lucasssvaz Mar 9, 2024
b1e3681
Improve header
lucasssvaz Mar 9, 2024
fd5c2fc
Properly kill subprocess
lucasssvaz Mar 9, 2024
cdd170d
Fix compilation issues
lucasssvaz Mar 9, 2024
8662df0
Hide setting depending on switch state
lucasssvaz Mar 12, 2024
9d32f26
QoL improvements
lucasssvaz Mar 12, 2024
8caa77e
Improve style
lucasssvaz Mar 12, 2024
8364e75
Add python version check
lucasssvaz Mar 12, 2024
d2a0f10
Separate main menu screen
lucasssvaz Mar 18, 2024
e90707e
Fix quit and improve logs
lucasssvaz Mar 18, 2024
7eef90c
Propagate exit code
lucasssvaz Mar 18, 2024
febe5fa
Rename quit to exit for consistency
lucasssvaz Mar 18, 2024
9fbb3f8
Add readme
lucasssvaz Mar 18, 2024
8358f57
Improve Readme
lucasssvaz Mar 18, 2024
7ae42f4
Add keybindings
lucasssvaz Mar 18, 2024
d58881f
Improve readme
lucasssvaz Mar 18, 2024
c184c89
Revert "Merge branch 'bugfix/arch_cmd' into feature/config_ui"
lucasssvaz Mar 19, 2024
11c3298
Merge branch 'master' into feature/config_ui
lucasssvaz Apr 3, 2024
303bad3
Merge branch 'master' into feature/config_ui
me-no-dev Apr 5, 2024
6bdcb04
Target list based on JSON and support for any combination of targets
lucasssvaz Apr 5, 2024
f0702ef
Improve documentation
lucasssvaz Apr 5, 2024
6e5ea45
Add note to the documentation
lucasssvaz Apr 5, 2024
b252b7c
Fix copy after compilation
lucasssvaz Apr 5, 2024
967d887
Fix bugs
lucasssvaz Apr 5, 2024
d82696b
Improve documentation
lucasssvaz Apr 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions tools/config_editor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.venv/
__pycache__/
26 changes: 26 additions & 0 deletions tools/config_editor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Arduino Static Libraries Configuration Editor

This is a simple application to configure the static libraries for the ESP32 Arduino core.
It allows the user to select the targets to compile, change the configuration options and compile the libraries.

## Requirements
- Python 3.9 or later
- The "textual" library (install it using `pip install textual`)
- The requirements from esp32-arduino-lib-builder

### WSL
If you are using WSL, it is recommended to use the Windows Terminal to visualize the application. Otherwise, the application layout and colors might not be displayed correctly.
The Windows Terminal can be installed from the Microsoft Store.

## Usage

These command line arguments can be used to pre-configure the application:

Command line arguments:
-t, --target <target> Target to be compiled. Choose from: all, esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2. Default: all
--copy, --no-copy Enable/disable copying the compiled libraries to arduino-esp32. Enabled by default
-c, --arduino-path <path> Path to arduino-esp32 directory. Default: OS dependent
-A, --arduino-branch <branch> Branch of the arduino-esp32 repository to be used. Default: set by the build script
-I, --idf-branch <branch> Branch of the ESP-IDF repository to be used. Default: set by the build script
-i, --idf-commit <commit> Commit of the ESP-IDF repository to be used. Default: set by the build script
-D, --debug-level <level> Debug level to be set to ESP-IDF. Choose from: default, none, error, warning, info, debug, verbose. Default: default
257 changes: 257 additions & 0 deletions tools/config_editor/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
#!/usr/bin/env python

"""
Arduino Static Libraries Configuration Editor

This is a simple application to configure the static libraries for the ESP32 Arduino core.
It allows the user to select the targets to compile, change the configuration options and compile the libraries.

Requires Python 3.9 or later.

The application is built using the "textual" library, which is a Python library for building text-based user interfaces.

Note that this application still needs the requirements from esp32-arduino-lib-builder to be installed.

Command line arguments:
-t, --target <target> Target to be compiled. Choose from: all, esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2. Default: all
--copy, --no-copy Enable/disable copying the compiled libraries to arduino-esp32. Enabled by default
-c, --arduino-path <path> Path to arduino-esp32 directory. Default: OS dependent
-A, --arduino-branch <branch> Branch of the arduino-esp32 repository to be used. Default: set by the build script
-I, --idf-branch <branch> Branch of the ESP-IDF repository to be used. Default: set by the build script
-i, --idf-commit <commit> Commit of the ESP-IDF repository to be used. Default: set by the build script
-D, --debug-level <level> Debug level to be set to ESP-IDF. Choose from: default, none, error, warning, info, debug, verbose. Default: default

"""

import argparse
import json
import os
import platform
import sys

from pathlib import Path

try:
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import VerticalScroll
from textual.screen import Screen
from textual.widgets import Button, Header, Label, Footer
except ImportError:
print("Please install the \"textual\" package before running this script.")
exit(1)

from settings import SettingsScreen
from editor import EditorScreen
from compile import CompileScreen

class MainScreen(Screen):
# Main screen class

# Set the key bindings
BINDINGS = [
Binding("c", "app.push_screen('compile')", "Compile"),
Binding("e", "app.push_screen('editor')", "Editor"),
Binding("s", "app.push_screen('settings')", "Settings"),
Binding("q", "app.quit", "Quit"),
]

def on_button_pressed(self, event: Button.Pressed) -> None:
# Event handler called when a button is pressed
if event.button.id == "compile-button":
print("Compile button pressed")
self.app.push_screen("compile")
elif event.button.id == "settings-button":
print("Settings button pressed")
self.app.push_screen("settings")
elif event.button.id == "editor-button":
print("Editor button pressed")
self.app.push_screen("editor")
elif event.button.id == "quit-button":
print("Quit button pressed")
self.app.exit()

def compose(self) -> ComposeResult:
# Compose main menu
yield Header()
with VerticalScroll(id="main-menu-container"):
yield Label("ESP32 Arduino Static Libraries Configuration Editor", id="main-menu-title")
yield Button("Compile Static Libraries", id="compile-button", classes="main-menu-button")
yield Button("Sdkconfig Editor", id="editor-button", classes="main-menu-button")
yield Button("Settings", id="settings-button", classes="main-menu-button")
yield Button("Quit", id="quit-button", classes="main-menu-button")
yield Footer()

def on_mount(self) -> None:
# Event handler called when the app is mounted for the first time
self.title = "Configurator"
self.sub_title = "Main Menu"
print("Main screen mounted.")

class ConfigEditorApp(App):
# Main application class

# Set the root and script paths
SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__))
ROOT_PATH = os.path.abspath(os.path.join(SCRIPT_PATH, "..", ".."))

# Set the application options
supported_targets = []
setting_enable_copy = True

# Options to be set by the command line arguments
setting_target = ""
setting_arduino_path = ""
setting_arduino_branch = ""
setting_idf_branch = ""
setting_idf_commit = ""
setting_debug_level = ""

ENABLE_COMMAND_PALETTE = False
CSS_PATH = "style.tcss"
SCREENS = {
"main": MainScreen(),
"settings": SettingsScreen(),
"compile": CompileScreen(),
"editor": EditorScreen(),
}

def on_mount(self) -> None:
print("Application mounted. Initial options:")
print("Python version: " + sys.version)
print("Root path: " + self.ROOT_PATH)
print("Script path: " + self.SCRIPT_PATH)
print("Supported Targets: " + ", ".join(self.supported_targets))
print("Default targets: " + self.setting_target)
print("Enable Copy: " + str(self.setting_enable_copy))
print("Arduino Path: " + str(self.setting_arduino_path))
print("Arduino Branch: " + str(self.setting_arduino_branch))
print("IDF Branch: " + str(self.setting_idf_branch))
print("IDF Commit: " + str(self.setting_idf_commit))
print("IDF Debug Level: " + str(self.setting_debug_level))
self.push_screen("main")

def arduino_default_path():
sys_name = platform.system()
home = str(Path.home())
if sys_name == "Linux":
return os.path.join(home, "Arduino", "hardware", "espressif", "esp32")
else: # Windows and MacOS
return os.path.join(home, "Documents", "Arduino", "hardware", "espressif", "esp32")

def check_arduino_path():
return os.path.isdir(arduino_default_path())

def main() -> None:
# Set the PYTHONUNBUFFERED environment variable to "1" to disable the output buffering
os.environ['PYTHONUNBUFFERED'] = "1"

# Check Python version
if sys.version_info < (3, 9):
print("This script requires Python 3.9 or later")
exit(1)

app = ConfigEditorApp()

target_choices = []

# Parse build JSON file
build_json_path = os.path.join(app.ROOT_PATH, "configs", "builds.json")
if os.path.isfile(build_json_path):
with open(build_json_path, "r") as build_json_file:
build_json = json.load(build_json_file)
for target in build_json["targets"]:
try:
default = False if target["skip"] else True
except:
default = True
target_choices.append((target["target"], default))
else:
print("Error: configs/builds.json file not found.")
exit(1)

target_choices.sort(key=lambda x: x[0])

parser = argparse.ArgumentParser(description="Configure and compile the ESP32 Arduino static libraries")

parser.add_argument("-t", "--target",
metavar="<target>",
type=str,
default="default",
required=False,
help="Comma separated list of targets to be compiled. Choose from: " + ", ".join([x[0] for x in target_choices])
+ ". Default: All except " + ", ".join([x[0] for x in target_choices if not x[1]]))

parser.add_argument("--copy",
type=bool,
action=argparse.BooleanOptionalAction,
default=True if check_arduino_path() else False,
required=False,
help="Enable/disable copying the compiled libraries to arduino-esp32. Enabled by default")

parser.add_argument("-c", "--arduino-path",
metavar="<arduino path>",
type=str,
default=arduino_default_path(),
required=False,
help="Path to arduino-esp32 directory. Default: " + arduino_default_path())

parser.add_argument("-A", "--arduino-branch",
metavar="<arduino branch>",
type=str,
default="",
required=False,
help="Branch of the arduino-esp32 repository to be used")

parser.add_argument("-I", "--idf-branch",
metavar="<IDF branch>",
type=str,
default="",
required=False,
help="Branch of the ESP-IDF repository to be used")

parser.add_argument("-i", "--idf-commit",
metavar="<IDF commit>",
type=str,
default="",
required=False,
help="Commit of the ESP-IDF repository to be used")

debug_level_choices = ("default", "none", "error", "warning", "info", "debug", "verbose")
parser.add_argument("-D", "--debug-level",
metavar="<level>",
type=str,
default="default",
choices=debug_level_choices,
required=False,
help="Debug level to be set to ESP-IDF. Choose from: " + ", ".join(debug_level_choices))

args = parser.parse_args()

# Set the options in the app
if args.target.strip() == "default":
args.target = ",".join([x[0] for x in target_choices if x[1]])
elif args.target.strip() == "all":
args.target = ",".join([x[0] for x in target_choices])

app.supported_targets = [x[0] for x in target_choices]
app.setting_target = args.target
app.setting_enable_copy = args.copy
app.setting_arduino_path = os.path.abspath(args.arduino_path)
app.setting_arduino_branch = args.arduino_branch
app.setting_idf_branch = args.idf_branch
app.setting_idf_commit = args.idf_commit
app.setting_debug_level = args.debug_level

# Change to the root directory of the app to the root of the project
os.chdir(app.ROOT_PATH)

# Main function to run the app
app.run()

# Propagate the exit code from the app
exit(app.return_code or 0)

if __name__ == "__main__":
# If this script is run directly, start the app
main()
Loading
Loading