main.sh
  1  #!/usr/bin/env bash
  2  
  3  BOARD_NAME=""
  4  FQBN_SELECTED=""
  5  SERIAL_PORT=""
  6  
  7  editors=("nano" "micro" "gedit" "vim" "nvim" "hx" "code" "codium")
  8  installed_editors=()
  9  
 10  sketch_file=""
 11  
 12  install_dependencies() {
 13    # Check if Homebrew is installed
 14    if ! command -v brew &>/dev/null; then
 15      echo "Installing Homebrew..."
 16      /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
 17  
 18      # Add Homebrew to PATH
 19      if [ -n "$ZSH_VERSION" ]; then
 20        echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >>~/.zshrc
 21        eval "$(/opt/homebrew/bin/brew shellenv)"
 22        source ~/.zshrc
 23      elif [ -n "$BASH_VERSION" ]; then
 24        echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >>~/.bashrc
 25        eval "$(/opt/homebrew/bin/brew shellenv)"
 26        source ~/.bashrc
 27      fi
 28    fi
 29  
 30    # Install Gum
 31    if ! command -v gum &>/dev/null; then
 32      echo "Installing Gum..."
 33      brew install gum
 34    fi
 35  
 36    # Install Arduino CLI
 37    if ! command -v arduino-cli &>/dev/null; then
 38      echo "Installing Arduino CLI..."
 39      curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
 40    fi
 41  
 42    # Install Timer
 43    if ! command -v timer &>/dev/null; then
 44      echo "Installing Timer..."
 45      brew install caarlos0/tap/timer
 46    fi
 47  
 48    clear
 49  }
 50  
 51  serial_monitor() {
 52    local baud_rate=$(gum input --placeholder "Baud Rate")
 53    arduino-cli monitor -p $SERIAL_PORT -b $FQBN_SELECTED --config $baud_rate
 54    trap 'gum confirm "Return to Homepage ?" && main || exit' SIGINT
 55  
 56    echo "Press Ctrl+C again"
 57    while true; do
 58      sleep 1
 59    done
 60  }
 61  
 62  check_for_updates() {
 63    local current_version="v1.1.0"
 64  
 65    # Check if the system is online by pinging Google
 66    if ! ping -q -c 1 -W 1 8.8.8.8 >/dev/null 2>&1; then
 67      echo "No internet connection. Skipping update check."
 68      return 0 # Proceed to main program
 69    fi
 70  
 71    # First check if GitHub token is set
 72    if [ -z "$ACI_GITHUB_TOKEN" ]; then
 73      echo "Warning: ACI_GITHUB_TOKEN is not set" >&2
 74      echo "Please set your GitHub token with: export ACI_GITHUB_TOKEN='your_token_here'" >&2
 75      return 1
 76    fi
 77  
 78    # Get the latest version with error checking and store full response
 79    # Added -k to skip SSL verification
 80    local api_response=$(curl -k -s -H "Authorization: token $ACI_GITHUB_TOKEN" \
 81      -H "Accept: application/vnd.github.v3+json" \
 82      "https://api.github.com/repos/Vaishnav-Sabari-Girish/arduino-cli-interactive/releases/latest")
 83  
 84    # Store the curl exit code
 85    local curl_exit_code=$?
 86  
 87    # Check if curl command succeeded
 88    if [ $curl_exit_code -ne 0 ]; then
 89      echo "Error: Failed to fetch latest version information (Exit code: $curl_exit_code)" >&2
 90      return 1
 91    fi
 92  
 93    # Check if response is empty
 94    if [ -z "$api_response" ]; then
 95      echo "Error: Empty response from GitHub API" >&2
 96      return 1
 97    fi
 98  
 99    # Check if response is valid JSON
100    if ! echo "$api_response" | jq empty >/dev/null 2>&1; then
101      echo "Error: Invalid JSON response from GitHub API" >&2
102      echo "Raw response: $api_response" >&2
103      return 1
104    fi
105  
106    # Try to extract the version
107    local latest_version=$(echo "$api_response" | jq -r '.tag_name')
108  
109    # Check if version was extracted successfully
110    if [ -z "$latest_version" ] || [ "$latest_version" = "null" ]; then
111      echo "Error: Could not find version tag in response" >&2
112      echo "Raw response: $api_response" >&2
113      return 1
114    fi
115  
116    if [ "$current_version" != "$latest_version" ]; then
117      cat >&2 <<-EOF
118  📦 Update available!
119  Current version: $current_version
120  Latest version:  $latest_version
121  To upgrade, run:
122      brew upgrade vaishnav-sabari-girish/arduino-cli-interactive
123  EOF
124      return 2 # Return code 2 indicates update available
125    fi
126  
127    return 0 # Return code 0 indicates up to date
128  }
129  
130  list_libraries() {
131    echo "These are the libraries installed in your system"
132    printf "\n"
133    arduino-cli lib list
134  
135    gum confirm "Return to homepage ?" && main || :
136  }
137  
138  lib_examples() {
139    installed_editors=()
140  
141    local lib_example=$(arduino-cli lib list | tail -n +2 | awk '{print $1, $2}' |
142      sed 's/  *[0-9][^ ]*//g' |
143      sed 's/-//g' | gum filter --placeholder "Input Library name to get example" --indicator=">")
144    local example_chosen=$(arduino-cli lib examples $lib_example | tail -n +2 | awk 'NF' | gum choose)
145  
146    local lib_dir=$(echo $example_chosen | sed 's/^[[:space:]-]*//')
147  
148    local ex_file=$(gum file $lib_dir)
149  
150    gum pager <$ex_file
151    sketch_file=("${lib_dir}${ex_file}")
152  
153    main
154  
155  }
156  
157  edit_config_file() {
158    if [ -e $HOME/.arduino15/arduino-cli.yaml ]; then
159      arduino-cli config init
160    fi
161  
162    installed_editors=()
163  
164    echo "Choose your preferred editor."
165    echo "Note that these editors are already installed in your system"
166  
167    timer 1s
168  
169    for editor in "${editors[@]}"; do
170      if command -v $editor &>/dev/null; then
171        installed_editors+=("$editor")
172      fi
173    done
174  
175    chosen_editor=$(printf "%s\n" "${installed_editors[@]}" | gum choose)
176    timer 0.5s
177  
178    $chosen_editor "$HOME/.arduino15/arduino-cli.yaml"
179  
180    gum confirm "Check file contents" && gum pager <$HOME/.arduino15/arduino-cli.yaml || main
181  
182  }
183  
184  edit_sketch() {
185    installed_editors=()
186  
187    echo "Choose file to edit : "
188    sketch_file=$(gum file --height 6)
189    timer 0.5s
190    echo "Choose your preferred editor."
191    echo "Note that these editors are already installed in your system"
192  
193    timer 1s
194  
195    for editor in "${editors[@]}"; do
196      if command -v $editor &>/dev/null; then
197        installed_editors+=("$editor")
198      fi
199    done
200  
201    chosen_editor=$(printf "%s\n" "${installed_editors[@]}" | gum choose)
202    timer 0.5
203  
204    "$chosen_editor" "$sketch_file"
205  
206    gum confirm "Check file contents" && gum pager <"$sketch_file" || main
207  
208  }
209  
210  create_new_sketch() {
211    arduino-cli sketch new $1
212    echo "New Sketch Created"
213    echo "At path ${PWD}" | gum style --foreground 47
214  
215    timer 2s
216    clear
217    main
218  }
219  
220  upload_code() {
221    #local file_u=$(gum file --height 5)
222    echo "Select Serial port to which the board is connected"
223    SERIAL_PORT=$(arduino-cli board list | awk '/\/dev\/tty/ {print $1}' | gum choose)
224    echo "Is your bootloader old (mostly for Nano) or the latest one"
225    local booltoader_old_new=$(gum choose "Old Bootloader" "New Bootloader")
226  
227    case $booltoader_old_new in
228    "New Bootloader")
229      arduino-cli upload --fqbn $FQBN_SELECTED -p $SERIAL_PORT $sketch_file
230      ;;
231    "Old Bootloader")
232      arduino-cli upload --fqbn "${FQBN_SELECTED}:cpu=atmega328old" -p $SERIAL_PORT $sketch_file
233      ;;
234    *)
235      echo "Invalid Option"
236      ;;
237    esac
238    echo "Uploaded Sketch" $sketch_file
239    gum style --foreground 47 $sketch_file
240  
241    timer 2.5s
242    clear
243    main
244  }
245  
246  compile_code() {
247    echo "Select file to be compiled"
248    #local file_c=$(gum file --height 5)
249    gum spin --spinner moon --title "Compiling for $BOARD_NAME" -- arduino-cli compile --fqbn $FQBN_SELECTED $sketch_file -v
250    echo "Compiled Sketch at path"
251    gum style --foreground 47 $sketch_file
252  
253    gum confirm "Return to Home?" && main || exit
254  }
255  
256  list_installed_boards() {
257    local boards=$(arduino-cli board listall)
258    local selected_line=$(echo "$boards" | gum filter --placeholder "Select a board")
259  
260    BOARD_NAME=$(echo "$selected_line" | awk '{print substr($0, 1, index($0, $NF)-1)}' | xargs)
261    FQBN_SELECTED=$(echo "$selected_line" | awk '{print $NF}')
262  
263    echo "Board Name:" | gum style --foreground 46
264    echo "$BOARD_NAME" | gum style --foreground 47
265    echo "FQBN:" | gum style --foreground 46
266    echo "$FQBN_SELECTED" | gum style --foreground 47
267  
268    confirm_board_selection
269  
270    timer 2s
271    clear
272    main
273  }
274  
275  confirm_board_selection() {
276    gum confirm "Current Selected Board : $BOARD_NAME" && main || list_installed_boards
277  }
278  
279  install_libraries() {
280    local lib_name=$(gum input --placeholder "Enter Library Name to install")
281    local lib_chosen=$(arduino-cli lib search $lib_name | awk '
282    /Name/ {name=$2}
283    /Author/ {
284        author="";
285        for(i=2; i<=NF; i++){
286          if($i ~ /</) 
287            break;
288          author=author " " $i;
289        }
290        print name,  " : ", author; 
291      }
292    ' | gum choose)
293  
294    local lib_to_install=$(echo "$lib_chosen" | awk -F' : ' '{print $1}' | tr -d '"')
295    arduino-cli lib install $lib_to_install
296    timer 2s
297    main
298  }
299  
300  main() {
301    clear
302    install_dependencies
303  
304    check_for_updates
305    local intro="Welcome to arduino-cli-interactive"
306    echo "$intro" | gum style --foreground 47 --border-foreground 217 --border double --align center --width 50
307    echo "You have chosen the board : $BOARD_NAME 
308          with FQBN : $FQBN_SELECTED
309          Sketch file :  $sketch_file
310          Serial Port : $SERIAL_PORT"
311  
312    timer 1s
313    local choice=$(gum choose --height 12 "Select Board" "Create New Sketch" "Edit the Sketch" \
314      "Compile Code" "Upload Code" "Serial Monitor" "Install Libraries" "Display Installed Libraries" \
315      "View Examples" "Edit Configurations" "Exit")
316  
317    case $choice in
318    "Create New Sketch")
319      local sketch_name=$(gum input --placeholder "Enter Name of Sketch")
320      create_new_sketch $sketch_name
321      ;;
322    "Edit the Sketch")
323      edit_sketch
324      ;;
325  
326    "Edit Configurations")
327      edit_config_file
328      ;;
329    "Compile Code")
330      compile_code
331      ;;
332    "Upload Code")
333      upload_code
334      ;;
335    "Serial Monitor")
336      serial_monitor
337      ;;
338    "Install Libraries")
339      install_libraries
340      ;;
341    "Display Installed Libraries")
342      list_libraries
343      ;;
344    "View Examples")
345      lib_examples
346      ;;
347    "Select Board")
348      list_installed_boards
349      ;;
350    "Exit")
351      echo "See you again !!!" | gum style --foreground 47
352      exit
353      ;;
354    *)
355      echo "Unknown option"
356      ;;
357    esac
358  }
359  
360  main