Skip to content

Commit 03b5724

Browse files
committed
feat: Add install_libs function to handle library installation from ci.json
1 parent c386501 commit 03b5724

File tree

2 files changed

+154
-0
lines changed

2 files changed

+154
-0
lines changed

.github/scripts/sketch_utils.sh

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,14 @@ function build_sketch { # build_sketch <ide_path> <user_path> <path-to-ino> [ext
244244
fi
245245
fi
246246

247+
# Install libraries from ci.json if they exist
248+
install_libs -ai "$ide_path" -s "$sketchdir" -v
249+
install_result=$?
250+
if [ $install_result -ne 0 ]; then
251+
echo "ERROR: Library installation failed for $sketchname" >&2
252+
exit $install_result
253+
fi
254+
247255
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
248256
if [ -n "$ARDUINO_BUILD_DIR" ]; then
249257
build_dir="$ARDUINO_BUILD_DIR"
@@ -580,13 +588,153 @@ function build_sketches { # build_sketches <ide_path> <user_path> <target> <path
580588
return 0
581589
}
582590

591+
function install_libs { # install_libs <ide_path> <sketchdir> [-v]
592+
local ide_path=""
593+
local sketchdir=""
594+
local verbose=false
595+
596+
while [ -n "$1" ]; do
597+
case "$1" in
598+
-ai ) shift; ide_path=$1 ;;
599+
-s ) shift; sketchdir=$1 ;;
600+
-v ) verbose=true ;;
601+
* )
602+
echo "ERROR: Unknown argument: $1" >&2
603+
echo "USAGE: install_libs -ai <ide_path> -s <sketchdir> [-v]" >&2
604+
return 1
605+
;;
606+
esac
607+
shift
608+
done
609+
610+
if [ -z "$ide_path" ]; then
611+
echo "ERROR: IDE path not provided" >&2
612+
echo "USAGE: install_libs -ai <ide_path> -s <sketchdir> [-v]" >&2
613+
return 1
614+
fi
615+
if [ -z "$sketchdir" ]; then
616+
echo "ERROR: Sketch directory not provided" >&2
617+
echo "USAGE: install_libs -ai <ide_path> -s <sketchdir> [-v]" >&2
618+
return 1
619+
fi
620+
if [ ! -f "$ide_path/arduino-cli" ]; then
621+
echo "ERROR: arduino-cli not found at $ide_path/arduino-cli" >&2
622+
return 1
623+
fi
624+
625+
# No ci.json => nothing to install
626+
if [ ! -f "$sketchdir/ci.json" ]; then
627+
[ "$verbose" = true ] && echo "No ci.json found in $sketchdir, skipping library installation"
628+
return 0
629+
fi
630+
631+
# Validate JSON early
632+
if ! jq -e . "$sketchdir/ci.json" >/dev/null 2>&1; then
633+
echo "ERROR: $sketchdir/ci.json is not valid JSON" >&2
634+
return 1
635+
fi
636+
637+
local libs_type
638+
libs_type=$(jq -r '.libs | type' "$sketchdir/ci.json" 2>/dev/null)
639+
if [ -z "$libs_type" ] || [ "$libs_type" = "null" ]; then
640+
[ "$verbose" = true ] && echo "No libs field found in ci.json, skipping library installation"
641+
return 0
642+
elif [ "$libs_type" != "array" ]; then
643+
echo "ERROR: libs field in ci.json must be an array, found: $libs_type" >&2
644+
return 1
645+
fi
646+
647+
local libs_count
648+
libs_count=$(jq -r '.libs | length' "$sketchdir/ci.json" 2>/dev/null)
649+
if [ "$libs_count" -eq 0 ]; then
650+
[ "$verbose" = true ] && echo "libs array is empty in ci.json, skipping library installation"
651+
return 0
652+
fi
653+
654+
echo "Installing $libs_count libraries from $sketchdir/ci.json"
655+
656+
local needs_unsafe=false
657+
local original_unsafe_setting=""
658+
local libs
659+
libs=$(jq -r '.libs[]? // empty' "$sketchdir/ci.json")
660+
661+
# Detect if any lib is a Git URL (needs unsafe install)
662+
for lib in $libs; do
663+
if [[ "$lib" == https://github.com/* ]]; then
664+
needs_unsafe=true
665+
break
666+
fi
667+
done
668+
669+
# Enable unsafe installs if needed, remember original setting
670+
if [ "$needs_unsafe" = true ]; then
671+
[ "$verbose" = true ] && echo "Checking current unsafe install setting..."
672+
original_unsafe_setting=$("$ide_path/arduino-cli" config get library.enable_unsafe_install 2>/dev/null || echo "false")
673+
if [ "$original_unsafe_setting" = "false" ]; then
674+
[ "$verbose" = true ] && echo "Enabling unsafe installs for Git URLs..."
675+
if ! "$ide_path/arduino-cli" config set library.enable_unsafe_install true >/dev/null 2>&1; then
676+
echo "WARNING: Failed to enable unsafe installs, Git URL installs may fail" >&2
677+
# continue; the install will surface a real error if it matters
678+
fi
679+
else
680+
[ "$verbose" = true ] && echo "Unsafe installs already enabled"
681+
fi
682+
fi
683+
684+
local rc=0 install_status=0 output=""
685+
for lib in $libs; do
686+
[ "$verbose" = true ] && echo "Processing library: $lib"
687+
688+
if [[ "$lib" == https://github.com/* ]]; then
689+
[ "$verbose" = true ] && echo "Installing library from GitHub URL: $lib"
690+
if [ "$verbose" = true ]; then
691+
"$ide_path/arduino-cli" lib install --git-url "$lib"
692+
install_status=$?
693+
else
694+
output=$("$ide_path/arduino-cli" lib install --git-url "$lib" 2>&1)
695+
install_status=$?
696+
[ $install_status -ne 0 ] && echo "$output" | grep -Ei "error|warning|warn" >&2 || true
697+
fi
698+
else
699+
[ "$verbose" = true ] && echo "Installing library by name: $lib"
700+
if [ "$verbose" = true ]; then
701+
"$ide_path/arduino-cli" lib install "$lib"
702+
install_status=$?
703+
else
704+
output=$("$ide_path/arduino-cli" lib install "$lib" 2>&1)
705+
install_status=$?
706+
[ $install_status -ne 0 ] && echo "$output" | grep -Ei "error|warning|warn" >&2 || true
707+
fi
708+
fi
709+
710+
if [ $install_status -ne 0 ]; then
711+
echo "ERROR: Failed to install library: $lib" >&2
712+
rc=$install_status
713+
break
714+
else
715+
[ "$verbose" = true ] && echo "Successfully installed library: $lib"
716+
fi
717+
done
718+
719+
# Restore unsafe setting if we changed it
720+
if [ "$needs_unsafe" = true ] && [ "$original_unsafe_setting" = "false" ]; then
721+
[ "$verbose" = true ] && echo "Restoring original unsafe install setting..."
722+
"$ide_path/arduino-cli" config set library.enable_unsafe_install false >/dev/null 2>&1 || true
723+
fi
724+
725+
[ $rc -eq 0 ] && echo "Library installation completed"
726+
return $rc
727+
}
728+
729+
583730
USAGE="
584731
USAGE: ${0} [command] [options]
585732
Available commands:
586733
count: Count sketches.
587734
build: Build a sketch.
588735
chunk_build: Build a chunk of sketches.
589736
check_requirements: Check if target meets sketch requirements.
737+
install_libs: Install libraries from ci.json file.
590738
"
591739

592740
cmd=$1
@@ -606,6 +754,8 @@ case "$cmd" in
606754
;;
607755
"check_requirements") check_requirements "$@"
608756
;;
757+
"install_libs") install_libs "$@"
758+
;;
609759
*)
610760
echo "ERROR: Unrecognized command"
611761
echo "$USAGE"

docs/en/contributing.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,10 @@ The ``ci.json`` file is used to specify how the test suite and sketches will han
425425
* ``fqbn``: A dictionary that specifies the FQBNs that will be used to compile the sketch. The key is the target name and the value is a list
426426
of FQBNs. The `default FQBNs <https://github.com/espressif/arduino-esp32/blob/a31a5fca1739993173caba995f7785b8eed6b30e/.github/scripts/sketch_utils.sh#L86-L91>`_
427427
are used if this field is not specified. This overrides the default FQBNs and the ``fqbn_append`` field.
428+
* ``libs``: A list of libraries that are required to run the test suite. The libraries will be installed automatically if they are not already present.
429+
Libraries are installed using the ``arduino-cli lib install`` command, so you can specify libraries by name + version (e.g., ``[email protected]``)
430+
or by URL (e.g., ``https://github.com/arduino-libraries/WiFi101.git``).
431+
More information can be found in the `Arduino CLI documentation <https://arduino.github.io/arduino-cli/1.3/commands/arduino-cli_lib_install/>`_.
428432

429433
The ``wifi`` test suite is a good example of how to use the ``ci.json`` file:
430434

0 commit comments

Comments
 (0)