@@ -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 "
@@ -558,7 +566,9 @@ function build_sketches { # build_sketches <ide_path> <user_path> <target> <path
558566 continue
559567 fi
560568 echo " "
569+
561570 echo " Building Sketch Index $sketchnum - $sketchdirname "
571+
562572 build_sketch " ${args[@]} " -s " $sketchdir " " ${xtra_opts[@]} "
563573 local result=$?
564574 if [ $result -ne 0 ]; then
@@ -580,13 +590,160 @@ function build_sketches { # build_sketches <ide_path> <user_path> <target> <path
580590 return 0
581591}
582592
593+ function install_libs { # install_libs <ide_path> <sketchdir> [-v]
594+ local ide_path=" "
595+ local sketchdir=" "
596+ local verbose=false
597+
598+ # Return codes:
599+ # 0 = success / nothing to do
600+ # 2 = usage / arguments error
601+ # 3 = prerequisite missing (arduino-cli)
602+ # 4 = ci.json invalid
603+ # N = arduino-cli exit status when a library install fails
604+
605+ while [ -n " $1 " ]; do
606+ case " $1 " in
607+ -ai ) shift ; ide_path=$1 ;;
608+ -s ) shift ; sketchdir=$1 ;;
609+ -v ) verbose=true ;;
610+ * )
611+ echo " ERROR: Unknown argument: $1 " >&2
612+ echo " USAGE: install_libs -ai <ide_path> -s <sketchdir> [-v]" >&2
613+ return 2
614+ ;;
615+ esac
616+ shift
617+ done
618+
619+ if [ -z " $ide_path " ]; then
620+ echo " ERROR: IDE path not provided" >&2
621+ echo " USAGE: install_libs -ai <ide_path> -s <sketchdir> [-v]" >&2
622+ return 2
623+ fi
624+ if [ -z " $sketchdir " ]; then
625+ echo " ERROR: Sketch directory not provided" >&2
626+ echo " USAGE: install_libs -ai <ide_path> -s <sketchdir> [-v]" >&2
627+ return 2
628+ fi
629+ if [ ! -f " $ide_path /arduino-cli" ]; then
630+ echo " ERROR: arduino-cli not found at $ide_path /arduino-cli" >&2
631+ return 3
632+ fi
633+
634+ # No ci.json => nothing to install
635+ if [ ! -f " $sketchdir /ci.json" ]; then
636+ [ " $verbose " = true ] && echo " No ci.json found in $sketchdir , skipping library installation"
637+ return 0
638+ fi
639+
640+ # Validate JSON early
641+ if ! jq -e . " $sketchdir /ci.json" > /dev/null 2>&1 ; then
642+ echo " ERROR: $sketchdir /ci.json is not valid JSON" >&2
643+ return 4
644+ fi
645+
646+ local libs_type
647+ libs_type=$( jq -r ' .libs | type' " $sketchdir /ci.json" 2> /dev/null)
648+ if [ -z " $libs_type " ] || [ " $libs_type " = " null" ]; then
649+ [ " $verbose " = true ] && echo " No libs field found in ci.json, skipping library installation"
650+ return 0
651+ elif [ " $libs_type " != " array" ]; then
652+ echo " ERROR: libs field in ci.json must be an array, found: $libs_type " >&2
653+ return 4
654+ fi
655+
656+ local libs_count
657+ libs_count=$( jq -r ' .libs | length' " $sketchdir /ci.json" 2> /dev/null)
658+ if [ " $libs_count " -eq 0 ]; then
659+ [ " $verbose " = true ] && echo " libs array is empty in ci.json, skipping library installation"
660+ return 0
661+ fi
662+
663+ echo " Installing $libs_count libraries from $sketchdir /ci.json"
664+
665+ local needs_unsafe=false
666+ local original_unsafe_setting=" "
667+ local libs
668+ libs=$( jq -r ' .libs[]? // empty' " $sketchdir /ci.json" )
669+
670+ # Detect if any lib is a Git URL (needs unsafe install)
671+ for lib in $libs ; do
672+ if [[ " $lib " == https://github.com/* ]]; then
673+ needs_unsafe=true
674+ break
675+ fi
676+ done
677+
678+ # Enable unsafe installs if needed, remember original setting
679+ if [ " $needs_unsafe " = true ]; then
680+ [ " $verbose " = true ] && echo " Checking current unsafe install setting..."
681+ original_unsafe_setting=$( " $ide_path /arduino-cli" config get library.enable_unsafe_install 2> /dev/null || echo " false" )
682+ if [ " $original_unsafe_setting " = " false" ]; then
683+ [ " $verbose " = true ] && echo " Enabling unsafe installs for Git URLs..."
684+ if ! " $ide_path /arduino-cli" config set library.enable_unsafe_install true > /dev/null 2>&1 ; then
685+ echo " WARNING: Failed to enable unsafe installs, Git URL installs may fail" >&2
686+ # continue; the install will surface a real error if it matters
687+ fi
688+ else
689+ [ " $verbose " = true ] && echo " Unsafe installs already enabled"
690+ fi
691+ fi
692+
693+ local rc=0 install_status=0 output=" "
694+ for lib in $libs ; do
695+ [ " $verbose " = true ] && echo " Processing library: $lib "
696+
697+ if [[ " $lib " == https://github.com/* ]]; then
698+ [ " $verbose " = true ] && echo " Installing library from GitHub URL: $lib "
699+ if [ " $verbose " = true ]; then
700+ " $ide_path /arduino-cli" lib install --git-url " $lib "
701+ install_status=$?
702+ else
703+ output=$( " $ide_path /arduino-cli" lib install --git-url " $lib " 2>&1 )
704+ install_status=$?
705+ [ $install_status -ne 0 ] && echo " $output " | grep -Ei " error|warning|warn" >&2 || true
706+ fi
707+ else
708+ [ " $verbose " = true ] && echo " Installing library by name: $lib "
709+ if [ " $verbose " = true ]; then
710+ " $ide_path /arduino-cli" lib install " $lib "
711+ install_status=$?
712+ else
713+ output=$( " $ide_path /arduino-cli" lib install " $lib " 2>&1 )
714+ install_status=$?
715+ [ $install_status -ne 0 ] && echo " $output " | grep -Ei " error|warning|warn" >&2 || true
716+ fi
717+ fi
718+
719+ if [ $install_status -ne 0 ]; then
720+ echo " ERROR: Failed to install library: $lib " >&2
721+ rc=$install_status
722+ break
723+ else
724+ [ " $verbose " = true ] && echo " Successfully installed library: $lib "
725+ fi
726+ done
727+
728+ # Restore unsafe setting if we changed it
729+ if [ " $needs_unsafe " = true ] && [ " $original_unsafe_setting " = " false" ]; then
730+ [ " $verbose " = true ] && echo " Restoring original unsafe install setting..."
731+ " $ide_path /arduino-cli" config set library.enable_unsafe_install false > /dev/null 2>&1 || true
732+ fi
733+
734+ [ $rc -eq 0 ] && echo " Library installation completed"
735+ return $rc
736+ }
737+
738+
583739USAGE="
584740USAGE: ${0} [command] [options]
585741Available commands:
586742 count: Count sketches.
587743 build: Build a sketch.
588744 chunk_build: Build a chunk of sketches.
589745 check_requirements: Check if target meets sketch requirements.
746+ install_libs: Install libraries from ci.json file.
590747"
591748
592749cmd=$1
@@ -606,6 +763,8 @@ case "$cmd" in
606763 ;;
607764 " check_requirements" ) check_requirements " $@ "
608765 ;;
766+ " install_libs" ) install_libs " $@ "
767+ ;;
609768 * )
610769 echo " ERROR: Unrecognized command"
611770 echo " $USAGE "
0 commit comments