├── internal ├── updater │ ├── artifacts │ │ ├── .gitignore │ │ ├── read.xml │ │ ├── artifacts_read_xml.go │ │ ├── artifacts_linux_amd64.go │ │ ├── artifacts_linux_arm64.go │ │ ├── artifacts_darwin_amd64.go │ │ ├── artifacts_darwin_arm64.go │ │ ├── artifacts_windows_amd64.go │ │ └── download_resources.sh │ ├── http_client.go │ ├── download_image.go │ └── flasher.go └── tablestyle │ └── tablestyle.go ├── buf.lock ├── .gitignore ├── cmd ├── arduino-flasher-cli │ ├── drivers │ │ ├── src │ │ │ ├── unoq.cat │ │ │ ├── dpinst-x86.exe │ │ │ ├── dpinst-amd64.exe │ │ │ └── unoq.inf │ │ ├── drivers_others.go │ │ ├── drivers.go │ │ └── drivers_windows.go │ ├── version │ │ ├── check_for_updates.go │ │ └── version.go │ ├── download │ │ └── download.go │ ├── list │ │ └── list.go │ ├── main.go │ ├── daemon │ │ └── daemon.go │ └── flash │ │ └── flash.go ├── i18n │ ├── i18n.go │ └── i18n_test.go └── feedback │ ├── errorcodes.go │ ├── feedback_test.go │ ├── stdio.go │ └── feedback.go ├── dprint.json ├── buf.yaml ├── buf.gen.yaml ├── .editorconfig ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── go-test.yml │ ├── block-merge-label.yml │ ├── checks.yaml │ └── check-go-dependencies-task.yml ├── README.md ├── license_header.tpl ├── service ├── service.go └── service_list.go ├── .golangci.yml ├── rpc └── cc │ └── arduino │ └── flasher │ └── v1 │ ├── commands.proto │ ├── commands_grpc.pb.go │ └── commands.pb.go ├── .licenses └── arduino-flasher-cli │ └── go │ ├── github.com │ ├── mattn │ │ ├── go-isatty.dep.yml │ │ ├── go-colorable.dep.yml │ │ └── go-runewidth.dep.yml │ ├── jedib0t │ │ └── go-pretty │ │ │ └── v6 │ │ │ ├── text.dep.yml │ │ │ └── table.dep.yml │ ├── schollz │ │ └── progressbar │ │ │ └── v3.dep.yml │ ├── h2non │ │ ├── filetype.dep.yml │ │ └── filetype │ │ │ ├── types.dep.yml │ │ │ ├── matchers.dep.yml │ │ │ └── matchers │ │ │ └── isobmff.dep.yml │ ├── codeclysm │ │ └── extract │ │ │ └── v4.dep.yml │ ├── rivo │ │ └── uniseg.dep.yml │ ├── mitchellh │ │ └── colorstring.dep.yml │ ├── fatih │ │ └── color.dep.yml │ ├── ulikunitz │ │ ├── xz.dep.yml │ │ └── xz │ │ │ ├── internal │ │ │ ├── hash.dep.yml │ │ │ └── xlog.dep.yml │ │ │ └── lzma.dep.yml │ ├── spf13 │ │ ├── pflag.dep.yml │ │ └── cobra.dep.yml │ ├── arduino │ │ └── go-windows-runas.dep.yml │ ├── shirou │ │ └── gopsutil │ │ │ └── v4 │ │ │ ├── disk.dep.yml │ │ │ ├── common.dep.yml │ │ │ └── internal │ │ │ └── common.dep.yml │ └── juju │ │ └── errors.dep.yml │ ├── go.bug.st │ ├── cleanup.dep.yml │ ├── relaxed-semver.dep.yml │ └── f.dep.yml │ ├── golang.org │ └── x │ │ ├── term.dep.yml │ │ ├── sys │ │ └── unix.dep.yml │ │ └── text │ │ └── width.dep.yml │ └── gopkg.in │ └── yaml.v3.dep.yml ├── .licensed.yml ├── go.mod └── Taskfile.yml /internal/updater/artifacts/.gitignore: -------------------------------------------------------------------------------- 1 | resources_*/ 2 | -------------------------------------------------------------------------------- /buf.lock: -------------------------------------------------------------------------------- 1 | # Generated by buf. DO NOT EDIT. 2 | version: v2 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | 5 | build/ 6 | 7 | .bin/ 8 | -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/drivers/src/unoq.cat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/arduino-flasher-cli/main/cmd/arduino-flasher-cli/drivers/src/unoq.cat -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/drivers/src/dpinst-x86.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/arduino-flasher-cli/main/cmd/arduino-flasher-cli/drivers/src/dpinst-x86.exe -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/drivers/src/dpinst-amd64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/arduino-flasher-cli/main/cmd/arduino-flasher-cli/drivers/src/dpinst-amd64.exe -------------------------------------------------------------------------------- /internal/updater/artifacts/read.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dprint.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdown": {}, 3 | "yaml": {}, 4 | "excludes": [ 5 | ".licenses/**", 6 | "**/testdata/**" 7 | ], 8 | "plugins": [ 9 | "https://plugins.dprint.dev/markdown-0.17.8.wasm", 10 | "https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.0.wasm" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /buf.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | breaking: 3 | use: 4 | - FILE 5 | lint: 6 | use: 7 | - STANDARD 8 | - COMMENT_ENUM 9 | - COMMENT_ENUM_VALUE 10 | - COMMENT_FIELD 11 | - COMMENT_RPC 12 | - COMMENT_SERVICE 13 | modules: 14 | - path: rpc 15 | name: buf.build/arduino/arduino-flasher-cli 16 | -------------------------------------------------------------------------------- /buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | plugins: 3 | # Use protoc-gen-go 4 | - remote: buf.build/protocolbuffers/go:v1.34.2 5 | out: ./rpc 6 | opt: 7 | - paths=source_relative 8 | # Use of protoc-gen-go-grpc 9 | - remote: buf.build/grpc/go:v1.5.1 10 | out: ./rpc 11 | opt: 12 | - paths=source_relative 13 | inputs: 14 | - directory: ./rpc 15 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Default configuration for all files 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # Use utf-8 charset for modern languages 15 | [*.{go}] 16 | charset = utf-8 17 | 18 | # Use tab indentation for Go and Makefiles 19 | [{*.go,go.*}] 20 | indent_style = tab 21 | indent_size = 4 22 | 23 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Motivation 2 | 3 | 4 | 5 | ### Change description 6 | 7 | 8 | 9 | ### Additional Notes 10 | 11 | 12 | 13 | ### Reviewer checklist 14 | 15 | - [ ] PR addresses a single concern. 16 | - [ ] PR title and description are properly filled. 17 | - [ ] Changes will be merged in `main`. 18 | - [ ] Changes are covered by tests. 19 | - [ ] Logging is meaningful in case of troubleshooting. 20 | -------------------------------------------------------------------------------- /.github/workflows/go-test.yml: -------------------------------------------------------------------------------- 1 | name: Run Go Tests 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | go-test: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v3 15 | 16 | - name: Set up Go 17 | uses: actions/setup-go@v5 18 | with: 19 | go-version-file: go.mod 20 | 21 | - name: Run tests 22 | run: go tool task test 23 | env: 24 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino Flasher CLI 2 | 3 | A tool to download and flash Debian images on the board. 4 | 5 | ## Docs 6 | 7 | For a full guide on how to use it, see the [User documentation](https://docs.arduino.cc/tutorials/uno-q/update-image/). 8 | 9 | ## Build and test it locally 10 | 11 | Build it with `task build` and run: 12 | 13 | ```sh 14 | # Flash the latest release of the Debian image 15 | ./build/arduino-flasher-cli flash latest 16 | 17 | # Flash a local image. It works with either an archived or extracted image 18 | ./build/arduino-flasher-cli flash path/to/downloaded/image 19 | ``` 20 | -------------------------------------------------------------------------------- /.github/workflows/block-merge-label.yml: -------------------------------------------------------------------------------- 1 | name: Block Merge if "do-not-merge" Label Exists 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - labeled 8 | - unlabeled 9 | - synchronize # important for when new commits are pushed 10 | 11 | jobs: 12 | check-do-not-merge-label: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Check for "do-not-merge" label 16 | if: contains(github.event.pull_request.labels.*.name, 'do-not-merge') 17 | run: | 18 | echo "This Pull Request has the 'do-not-merge' label. Merging is blocked." 19 | echo "Please remove the 'do-not-merge' label to enable merging." 20 | exit 1 # This will cause the workflow to fail 21 | -------------------------------------------------------------------------------- /license_header.tpl: -------------------------------------------------------------------------------- 1 | This file is part of arduino-flasher-cli. 2 | 3 | Copyright{{ if .Year }} {{.Year}}{{ end }} {{.Holder}} 4 | 5 | This software is released under the GNU General Public License version 3, 6 | which covers the main part of arduino-flasher-cli. 7 | The terms of this license can be found at: 8 | https://www.gnu.org/licenses/gpl-3.0.en.html 9 | 10 | You can be released from the requirements of the above licenses by purchasing 11 | a commercial license. Buying such a license is mandatory if you want to 12 | modify or otherwise use the software for commercial activities involving the 13 | Arduino software without disclosing the source code of your own applications. 14 | To purchase a commercial license, send an email to license@arduino.cc. 15 | -------------------------------------------------------------------------------- /internal/updater/artifacts/artifacts_read_xml.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package artifacts 17 | 18 | import ( 19 | _ "embed" 20 | ) 21 | 22 | //go:embed read.xml 23 | var ReadXML []byte 24 | -------------------------------------------------------------------------------- /internal/updater/artifacts/artifacts_linux_amd64.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package artifacts 17 | 18 | import ( 19 | _ "embed" 20 | ) 21 | 22 | //go:embed resources_linux_amd64/qdl 23 | var QdlBinary []byte 24 | -------------------------------------------------------------------------------- /internal/updater/artifacts/artifacts_linux_arm64.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package artifacts 17 | 18 | import ( 19 | _ "embed" 20 | ) 21 | 22 | //go:embed resources_linux_arm64/qdl 23 | var QdlBinary []byte 24 | -------------------------------------------------------------------------------- /internal/updater/artifacts/artifacts_darwin_amd64.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package artifacts 17 | 18 | import ( 19 | _ "embed" 20 | ) 21 | 22 | //go:embed resources_darwin_amd64/qdl 23 | var QdlBinary []byte 24 | -------------------------------------------------------------------------------- /internal/updater/artifacts/artifacts_darwin_arm64.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package artifacts 17 | 18 | import ( 19 | _ "embed" 20 | ) 21 | 22 | //go:embed resources_darwin_arm64/qdl 23 | var QdlBinary []byte 24 | -------------------------------------------------------------------------------- /internal/updater/artifacts/artifacts_windows_amd64.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package artifacts 17 | 18 | import ( 19 | _ "embed" 20 | ) 21 | 22 | //go:embed resources_windows_amd64/qdl.exe 23 | var QdlBinary []byte 24 | -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/drivers/drivers_others.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | //go:build !windows 17 | 18 | package drivers 19 | 20 | // installDrivers is a no-op on non-Windows platforms 21 | func installDrivers() error { 22 | return nil 23 | } 24 | -------------------------------------------------------------------------------- /service/service.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package service 17 | 18 | import flasher "github.com/arduino/arduino-flasher-cli/rpc/cc/arduino/flasher/v1" 19 | 20 | type flasherServerImpl struct { 21 | flasher.UnsafeFlasherServer // Force compile error for unimplemented methods 22 | } 23 | 24 | func NewFlasherServer() flasher.FlasherServer { 25 | return &flasherServerImpl{} 26 | } 27 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | linters: 3 | enable: 4 | - bodyclose 5 | - dogsled 6 | - goconst 7 | - gocritic 8 | - goprintffuncname 9 | - gosec 10 | - importas 11 | - misspell 12 | - nakedret 13 | - prealloc 14 | - revive 15 | - staticcheck 16 | - unconvert 17 | - unparam 18 | - gochecknoinits 19 | settings: 20 | misspell: 21 | locale: US 22 | revive: 23 | rules: 24 | - name: indent-error-flow 25 | disabled: true 26 | goconst: 27 | ignore-string-values: 28 | - ".exe" 29 | - "windows" 30 | - "linux" 31 | - "darwin" 32 | 33 | exclusions: 34 | generated: lax 35 | presets: 36 | - comments 37 | - common-false-positives 38 | - legacy 39 | - std-error-handling 40 | paths: 41 | - third_party$ 42 | - builtin$ 43 | - examples$ 44 | formatters: 45 | enable: 46 | - gofmt 47 | - goimports 48 | settings: 49 | goimports: 50 | local-prefixes: 51 | - github.com/arduino/arduino-flasher-cli 52 | exclusions: 53 | generated: lax 54 | paths: 55 | - third_party$ 56 | - builtin$ 57 | - examples$ 58 | -------------------------------------------------------------------------------- /.github/workflows/checks.yaml: -------------------------------------------------------------------------------- 1 | name: Run Checks 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | # In the same branch only 1 workflow per time can run. In case we're not in the 10 | # main branch we cancel previous running workflow 11 | concurrency: 12 | group: ${{ github.workflow }}-${{ github.ref }} 13 | cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} 14 | 15 | permissions: 16 | contents: read 17 | # Used by the buf to create a comment with a brief summary of failing tets 18 | pull-requests: write 19 | 20 | jobs: 21 | run-checks: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | 26 | - name: build 27 | run: go tool task build # needed to download the embedded resources 28 | env: 29 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | 31 | - uses: dprint/check@v2.2 32 | with: 33 | dprint-version: 0.48.0 34 | 35 | - uses: golangci/golangci-lint-action@v8 36 | with: 37 | version: v2.4.0 38 | args: --timeout 300s 39 | 40 | - name: Check go mod 41 | run: | 42 | go mod tidy 43 | git diff --color --exit-code 44 | -------------------------------------------------------------------------------- /rpc/cc/arduino/flasher/v1/commands.proto: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | syntax = "proto3"; 17 | 18 | package cc.arduino.flasher.v1; 19 | 20 | option go_package = "github.com/arduino/arduino-flasher-cli/rpc/cc/arduino/flasher/v1;flasher"; 21 | 22 | service Flasher { 23 | rpc List(ListRequest) returns (ListResponse) {}; 24 | } 25 | 26 | message ListRequest {} 27 | 28 | message ListResponse { 29 | repeated Release releases = 1; 30 | } 31 | 32 | message Release { 33 | string build_id = 1; 34 | bool latest = 2; 35 | } 36 | -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/drivers/drivers.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package drivers 17 | 18 | import ( 19 | "github.com/spf13/cobra" 20 | 21 | "github.com/arduino/arduino-flasher-cli/cmd/feedback" 22 | "github.com/arduino/arduino-flasher-cli/cmd/i18n" 23 | ) 24 | 25 | func NewInstallDriversCmd() *cobra.Command { 26 | cmd := &cobra.Command{ 27 | Use: "install-drivers", 28 | Hidden: true, 29 | Run: func(cmd *cobra.Command, args []string) { 30 | if err := installDrivers(); err != nil { 31 | feedback.Fatal(i18n.Tr("error installing drivers: %v", err), feedback.ErrGeneric) 32 | } 33 | }, 34 | } 35 | return cmd 36 | } 37 | -------------------------------------------------------------------------------- /cmd/i18n/i18n.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package i18n 17 | 18 | import "fmt" 19 | 20 | type Locale interface { 21 | Get(msg string, args ...interface{}) string 22 | } 23 | 24 | type nullLocale struct{} 25 | 26 | func (n nullLocale) Parse([]byte) {} 27 | 28 | func (n nullLocale) Get(msg string, args ...interface{}) string { 29 | return fmt.Sprintf(msg, args...) 30 | } 31 | 32 | var locale Locale = &nullLocale{} 33 | 34 | func SetLocale(l Locale) { 35 | locale = l 36 | } 37 | 38 | // Tr returns msg translated to the selected locale 39 | // the msg argument must be a literal string 40 | func Tr(msg string, args ...interface{}) string { 41 | return locale.Get(msg, args...) 42 | } 43 | -------------------------------------------------------------------------------- /internal/tablestyle/tablestyle.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package tablestyle 17 | 18 | import ( 19 | "github.com/jedib0t/go-pretty/v6/table" 20 | "github.com/jedib0t/go-pretty/v6/text" 21 | ) 22 | 23 | var ( 24 | CustomCleanStyle = table.Style{ 25 | Name: "CustomClean", 26 | Box: table.BoxStyle{PaddingRight: " "}, 27 | Format: table.FormatOptions{ 28 | Footer: text.FormatUpper, 29 | Header: text.FormatUpper, 30 | Row: text.FormatDefault, 31 | RowAlign: text.AlignCenter, 32 | }, 33 | Options: table.Options{ 34 | DrawBorder: false, 35 | SeparateColumns: true, 36 | SeparateFooter: false, 37 | SeparateHeader: false, 38 | SeparateRows: false, 39 | }, 40 | } 41 | ) 42 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/mattn/go-isatty.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/mattn/go-isatty 3 | version: v0.0.20 4 | type: go 5 | summary: Package isatty implements interface to isatty 6 | homepage: https://pkg.go.dev/github.com/mattn/go-isatty 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | Copyright (c) Yasuhiro MATSUMOTO 12 | 13 | MIT License (Expat) 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | - sources: README.md 21 | text: MIT 22 | notices: [] 23 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/jedib0t/go-pretty/v6/text.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/jedib0t/go-pretty/v6/text 3 | version: v6.6.8 4 | type: go 5 | summary: 6 | homepage: https://pkg.go.dev/github.com/jedib0t/go-pretty/v6/text 7 | license: mit 8 | licenses: 9 | - sources: v6@v6.6.8/LICENSE 10 | text: | 11 | MIT License 12 | 13 | Copyright (c) 2018 jedib0t 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | notices: [] 33 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/jedib0t/go-pretty/v6/table.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/jedib0t/go-pretty/v6/table 3 | version: v6.6.8 4 | type: go 5 | summary: 6 | homepage: https://pkg.go.dev/github.com/jedib0t/go-pretty/v6/table 7 | license: mit 8 | licenses: 9 | - sources: v6@v6.6.8/LICENSE 10 | text: | 11 | MIT License 12 | 13 | Copyright (c) 2018 jedib0t 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | notices: [] 33 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/schollz/progressbar/v3.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/schollz/progressbar/v3 3 | version: v3.18.0 4 | type: go 5 | summary: 6 | homepage: https://pkg.go.dev/github.com/schollz/progressbar/v3 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | MIT License 12 | 13 | Copyright (c) 2017 Zack 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | - sources: README.md 33 | text: MIT 34 | notices: [] 35 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/mattn/go-colorable.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/mattn/go-colorable 3 | version: v0.1.13 4 | type: go 5 | summary: 6 | homepage: https://pkg.go.dev/github.com/mattn/go-colorable 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | The MIT License (MIT) 12 | 13 | Copyright (c) 2016 Yasuhiro Matsumoto 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | - sources: README.md 33 | text: MIT 34 | notices: [] 35 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/h2non/filetype.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/h2non/filetype 3 | version: v1.1.3 4 | type: go 5 | summary: 6 | homepage: https://pkg.go.dev/github.com/h2non/filetype 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | The MIT License 12 | 13 | Copyright (c) Tomas Aparicio 14 | 15 | Permission is hereby granted, free of charge, to any person 16 | obtaining a copy of this software and associated documentation 17 | files (the "Software"), to deal in the Software without 18 | restriction, including without limitation the rights to use, 19 | copy, modify, merge, publish, distribute, sublicense, and/or sell 20 | copies of the Software, and to permit persons to whom the 21 | Software is furnished to do so, subject to the following 22 | conditions: 23 | 24 | The above copyright notice and this permission notice shall be 25 | included in all copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 29 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 30 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 31 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 32 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 33 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 34 | OTHER DEALINGS IN THE SOFTWARE. 35 | - sources: README.md 36 | text: MIT - Tomas Aparicio 37 | notices: [] 38 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/codeclysm/extract/v4.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/codeclysm/extract/v4 3 | version: v4.0.0 4 | type: go 5 | summary: Package extract allows to extract archives in zip, tar.gz or tar.bz2 formats 6 | easily. 7 | homepage: https://pkg.go.dev/github.com/codeclysm/extract/v4 8 | license: mit 9 | licenses: 10 | - sources: LICENSE 11 | text: | 12 | The MIT License (MIT) 13 | 14 | Copyright (c) 2016 codeclysm 15 | 16 | Permission is hereby granted, free of charge, to any person obtaining a copy 17 | of this software and associated documentation files (the "Software"), to deal 18 | in the Software without restriction, including without limitation the rights 19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 20 | copies of the Software, and to permit persons to whom the Software is 21 | furnished to do so, subject to the following conditions: 22 | 23 | The above copyright notice and this permission notice shall be included in all 24 | copies or substantial portions of the Software. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 | SOFTWARE. 33 | notices: [] 34 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/mattn/go-runewidth.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/mattn/go-runewidth 3 | version: v0.0.16 4 | type: go 5 | summary: 6 | homepage: https://pkg.go.dev/github.com/mattn/go-runewidth 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | The MIT License (MIT) 12 | 13 | Copyright (c) 2016 Yasuhiro Matsumoto 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | - sources: README.md 33 | text: 'under the MIT License: http://mattn.mit-license.org/2013' 34 | notices: [] 35 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/rivo/uniseg.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/rivo/uniseg 3 | version: v0.4.7 4 | type: go 5 | summary: Package uniseg implements Unicode Text Segmentation, Unicode Line Breaking, 6 | and string width calculation for monospace fonts. 7 | homepage: https://pkg.go.dev/github.com/rivo/uniseg 8 | license: mit 9 | licenses: 10 | - sources: LICENSE.txt 11 | text: | 12 | MIT License 13 | 14 | Copyright (c) 2019 Oliver Kuederle 15 | 16 | Permission is hereby granted, free of charge, to any person obtaining a copy 17 | of this software and associated documentation files (the "Software"), to deal 18 | in the Software without restriction, including without limitation the rights 19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 20 | copies of the Software, and to permit persons to whom the Software is 21 | furnished to do so, subject to the following conditions: 22 | 23 | The above copyright notice and this permission notice shall be included in all 24 | copies or substantial portions of the Software. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 | SOFTWARE. 33 | notices: [] 34 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/h2non/filetype/types.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/h2non/filetype/types 3 | version: v1.1.3 4 | type: go 5 | summary: 6 | homepage: https://pkg.go.dev/github.com/h2non/filetype/types 7 | license: mit 8 | licenses: 9 | - sources: filetype@v1.1.3/LICENSE 10 | text: | 11 | The MIT License 12 | 13 | Copyright (c) Tomas Aparicio 14 | 15 | Permission is hereby granted, free of charge, to any person 16 | obtaining a copy of this software and associated documentation 17 | files (the "Software"), to deal in the Software without 18 | restriction, including without limitation the rights to use, 19 | copy, modify, merge, publish, distribute, sublicense, and/or sell 20 | copies of the Software, and to permit persons to whom the 21 | Software is furnished to do so, subject to the following 22 | conditions: 23 | 24 | The above copyright notice and this permission notice shall be 25 | included in all copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 29 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 30 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 31 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 32 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 33 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 34 | OTHER DEALINGS IN THE SOFTWARE. 35 | - sources: filetype@v1.1.3/README.md 36 | text: MIT - Tomas Aparicio 37 | notices: [] 38 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/mitchellh/colorstring.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/mitchellh/colorstring 3 | version: v0.0.0-20190213212951-d06e56a500db 4 | type: go 5 | summary: colorstring provides functions for colorizing strings for terminal output. 6 | homepage: https://pkg.go.dev/github.com/mitchellh/colorstring 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | The MIT License (MIT) 12 | 13 | Copyright (c) 2014 Mitchell Hashimoto 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in 23 | all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | THE SOFTWARE. 32 | notices: [] 33 | -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/drivers/src/unoq.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Installs WinUsb 3 | ; 4 | 5 | [Version] 6 | Signature = "$Windows NT$" 7 | Class = USBDevice 8 | ClassGUID = {88BAE032-5A81-49f0-BC3D-A4FF138216D6} 9 | Provider = %ManufacturerName% 10 | CatalogFile = unoq.cat 11 | DriverVer = 09/17/2025,10.48.00.000 12 | 13 | ; ========== Manufacturer/Models sections =========== 14 | 15 | [Manufacturer] 16 | %ManufacturerName% = Standard,NTamd64 17 | 18 | [Standard.NTamd64] 19 | %DeviceName% =USB_Install, USB\VID_05C6&PID_9008 20 | 21 | ; ========== Class definition =========== 22 | 23 | [ClassInstall32] 24 | AddReg = ClassInstall_AddReg 25 | 26 | [ClassInstall_AddReg] 27 | HKR,,,,%ClassName% 28 | HKR,,NoInstallClass,,1 29 | HKR,,IconPath,%REG_MULTI_SZ%,"%systemroot%\system32\setupapi.dll,-20" 30 | HKR,,LowerLogoVersion,,5.2 31 | 32 | ; =================== Installation =================== 33 | 34 | [USB_Install] 35 | Include = winusb.inf 36 | Needs = WINUSB.NT 37 | 38 | [USB_Install.Services] 39 | Include = winusb.inf 40 | Needs = WINUSB.NT.Services 41 | 42 | [USB_Install.HW] 43 | AddReg=Dev_AddReg 44 | 45 | [Dev_AddReg] 46 | HKR,,DeviceInterfaceGUIDs,0x10000,"{51de5bfa-d59d-4f3e-9b36-0b4b210dd53f}" 47 | 48 | ; [DestinationDirs] 49 | ; If your INF needs to copy files, you must not use the DefaultDestDir directive here. 50 | ; You must explicitly reference all file-list-section names in this section. 51 | 52 | ; =================== Strings =================== 53 | 54 | [Strings] 55 | ManufacturerName="Arduino" 56 | ClassName="Universal Serial Bus devices" 57 | DeviceName="Arduino UNO Q Download mode" 58 | REG_MULTI_SZ = 0x00010000 59 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/h2non/filetype/matchers.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/h2non/filetype/matchers 3 | version: v1.1.3 4 | type: go 5 | summary: 6 | homepage: https://pkg.go.dev/github.com/h2non/filetype/matchers 7 | license: mit 8 | licenses: 9 | - sources: filetype@v1.1.3/LICENSE 10 | text: | 11 | The MIT License 12 | 13 | Copyright (c) Tomas Aparicio 14 | 15 | Permission is hereby granted, free of charge, to any person 16 | obtaining a copy of this software and associated documentation 17 | files (the "Software"), to deal in the Software without 18 | restriction, including without limitation the rights to use, 19 | copy, modify, merge, publish, distribute, sublicense, and/or sell 20 | copies of the Software, and to permit persons to whom the 21 | Software is furnished to do so, subject to the following 22 | conditions: 23 | 24 | The above copyright notice and this permission notice shall be 25 | included in all copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 29 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 30 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 31 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 32 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 33 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 34 | OTHER DEALINGS IN THE SOFTWARE. 35 | - sources: filetype@v1.1.3/README.md 36 | text: MIT - Tomas Aparicio 37 | notices: [] 38 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/h2non/filetype/matchers/isobmff.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/h2non/filetype/matchers/isobmff 3 | version: v1.1.3 4 | type: go 5 | summary: 6 | homepage: https://pkg.go.dev/github.com/h2non/filetype/matchers/isobmff 7 | license: mit 8 | licenses: 9 | - sources: filetype@v1.1.3/LICENSE 10 | text: | 11 | The MIT License 12 | 13 | Copyright (c) Tomas Aparicio 14 | 15 | Permission is hereby granted, free of charge, to any person 16 | obtaining a copy of this software and associated documentation 17 | files (the "Software"), to deal in the Software without 18 | restriction, including without limitation the rights to use, 19 | copy, modify, merge, publish, distribute, sublicense, and/or sell 20 | copies of the Software, and to permit persons to whom the 21 | Software is furnished to do so, subject to the following 22 | conditions: 23 | 24 | The above copyright notice and this permission notice shall be 25 | included in all copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 29 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 30 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 31 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 32 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 33 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 34 | OTHER DEALINGS IN THE SOFTWARE. 35 | - sources: filetype@v1.1.3/README.md 36 | text: MIT - Tomas Aparicio 37 | notices: [] 38 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/fatih/color.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/fatih/color 3 | version: v1.18.0 4 | type: go 5 | summary: Package color is an ANSI color package to output colorized or SGR defined 6 | output to the standard output. 7 | homepage: https://pkg.go.dev/github.com/fatih/color 8 | license: mit 9 | licenses: 10 | - sources: LICENSE.md 11 | text: | 12 | The MIT License (MIT) 13 | 14 | Copyright (c) 2013 Fatih Arslan 15 | 16 | Permission is hereby granted, free of charge, to any person obtaining a copy of 17 | this software and associated documentation files (the "Software"), to deal in 18 | the Software without restriction, including without limitation the rights to 19 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 20 | the Software, and to permit persons to whom the Software is furnished to do so, 21 | subject to the following conditions: 22 | 23 | The above copyright notice and this permission notice shall be included in all 24 | copies or substantial portions of the Software. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 28 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 29 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 30 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | - sources: README.md 33 | text: The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) 34 | for more details 35 | notices: [] 36 | -------------------------------------------------------------------------------- /service/service_list.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package service 17 | 18 | import ( 19 | "cmp" 20 | "context" 21 | "slices" 22 | 23 | "go.bug.st/f" 24 | 25 | "github.com/arduino/arduino-flasher-cli/internal/updater" 26 | flasher "github.com/arduino/arduino-flasher-cli/rpc/cc/arduino/flasher/v1" 27 | ) 28 | 29 | func (s *flasherServerImpl) List(ctx context.Context, req *flasher.ListRequest) (*flasher.ListResponse, error) { 30 | client := updater.NewClient() 31 | 32 | manifest, err := client.GetInfoManifest(ctx) 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | releases := f.Map(manifest.Releases, func(r updater.Release) *flasher.Release { 38 | return &flasher.Release{ 39 | BuildId: r.Version, 40 | Latest: r.Version == manifest.Latest.Version, 41 | } 42 | }) 43 | slices.SortFunc(releases, func(a, b *flasher.Release) int { 44 | if a.Latest { 45 | if b.Latest { 46 | return 0 47 | } 48 | return -1 49 | } else if b.Latest { 50 | return 1 51 | } 52 | return cmp.Compare(b.BuildId, a.BuildId) 53 | }) 54 | 55 | return &flasher.ListResponse{Releases: releases}, nil 56 | } 57 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/ulikunitz/xz.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/ulikunitz/xz 3 | version: v0.5.12 4 | type: go 5 | summary: Package xz supports the compression and decompression of xz files. 6 | homepage: https://pkg.go.dev/github.com/ulikunitz/xz 7 | license: bsd-3-clause 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | Copyright (c) 2014-2022 Ulrich Kunitz 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | 17 | * Redistributions of source code must retain the above copyright notice, this 18 | list of conditions and the following disclaimer. 19 | 20 | * Redistributions in binary form must reproduce the above copyright notice, 21 | this list of conditions and the following disclaimer in the documentation 22 | and/or other materials provided with the distribution. 23 | 24 | * My name, Ulrich Kunitz, may not be used to endorse or promote products 25 | derived from this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 31 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 33 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 34 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 35 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | notices: [] 38 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/ulikunitz/xz/internal/hash.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/ulikunitz/xz/internal/hash 3 | version: v0.5.12 4 | type: go 5 | summary: Package hash provides rolling hashes. 6 | homepage: https://pkg.go.dev/github.com/ulikunitz/xz/internal/hash 7 | license: bsd-3-clause 8 | licenses: 9 | - sources: xz@v0.5.12/LICENSE 10 | text: | 11 | Copyright (c) 2014-2022 Ulrich Kunitz 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | 17 | * Redistributions of source code must retain the above copyright notice, this 18 | list of conditions and the following disclaimer. 19 | 20 | * Redistributions in binary form must reproduce the above copyright notice, 21 | this list of conditions and the following disclaimer in the documentation 22 | and/or other materials provided with the distribution. 23 | 24 | * My name, Ulrich Kunitz, may not be used to endorse or promote products 25 | derived from this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 31 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 33 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 34 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 35 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | notices: [] 38 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/ulikunitz/xz/lzma.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/ulikunitz/xz/lzma 3 | version: v0.5.12 4 | type: go 5 | summary: Package lzma supports the decoding and encoding of LZMA streams. 6 | homepage: https://pkg.go.dev/github.com/ulikunitz/xz/lzma 7 | license: bsd-3-clause 8 | licenses: 9 | - sources: xz@v0.5.12/LICENSE 10 | text: | 11 | Copyright (c) 2014-2022 Ulrich Kunitz 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | 17 | * Redistributions of source code must retain the above copyright notice, this 18 | list of conditions and the following disclaimer. 19 | 20 | * Redistributions in binary form must reproduce the above copyright notice, 21 | this list of conditions and the following disclaimer in the documentation 22 | and/or other materials provided with the distribution. 23 | 24 | * My name, Ulrich Kunitz, may not be used to endorse or promote products 25 | derived from this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 31 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 33 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 34 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 35 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | notices: [] 38 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/go.bug.st/cleanup.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: go.bug.st/cleanup 3 | version: v1.0.0 4 | type: go 5 | summary: 6 | homepage: https://pkg.go.dev/go.bug.st/cleanup 7 | license: bsd-3-clause 8 | licenses: 9 | - sources: LICENSE 10 | text: |2+ 11 | 12 | Copyright (c) 2018, Cristian Maglie. 13 | All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions 17 | are met: 18 | 19 | 1. Redistributions of source code must retain the above copyright 20 | notice, this list of conditions and the following disclaimer. 21 | 22 | 2. Redistributions in binary form must reproduce the above copyright 23 | notice, this list of conditions and the following disclaimer in 24 | the documentation and/or other materials provided with the 25 | distribution. 26 | 27 | 3. Neither the name of the copyright holder nor the names of its 28 | contributors may be used to endorse or promote products derived 29 | from this software without specific prior written permission. 30 | 31 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 34 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 35 | COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 36 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 37 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 38 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 39 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 41 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | notices: [] 45 | ... 46 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/go.bug.st/relaxed-semver.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: go.bug.st/relaxed-semver 3 | version: v0.15.0 4 | type: go 5 | summary: 6 | homepage: https://pkg.go.dev/go.bug.st/relaxed-semver 7 | license: bsd-3-clause 8 | licenses: 9 | - sources: LICENSE 10 | text: |2+ 11 | 12 | Copyright (c) 2018-2025, Cristian Maglie. 13 | All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions 17 | are met: 18 | 19 | 1. Redistributions of source code must retain the above copyright 20 | notice, this list of conditions and the following disclaimer. 21 | 22 | 2. Redistributions in binary form must reproduce the above copyright 23 | notice, this list of conditions and the following disclaimer in 24 | the documentation and/or other materials provided with the 25 | distribution. 26 | 27 | 3. Neither the name of the copyright holder nor the names of its 28 | contributors may be used to endorse or promote products derived 29 | from this software without specific prior written permission. 30 | 31 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 34 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 35 | COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 36 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 37 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 38 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 39 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 41 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | notices: [] 45 | ... 46 | -------------------------------------------------------------------------------- /internal/updater/artifacts/download_resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | BASE_DIR="$(cd "$(dirname "$0")" && pwd)" 6 | 7 | REPO="arduino/qdl-packing" 8 | TAG="v2.2-22" 9 | 10 | # Remove existing resource directories if they exist 11 | rm -rf $BASE_DIR/resources_* 12 | 13 | # Download and extract Linux 64-bit 14 | mkdir -p "$BASE_DIR/resources_linux_amd64" 15 | gh release download "$TAG" --repo "$REPO" --pattern "qdl_*_Linux_64bit.tar.gz" --dir "$BASE_DIR/resources_linux_amd64" 16 | tar -xzf $BASE_DIR/resources_linux_amd64/qdl_*_Linux_64bit.tar.gz -C "$BASE_DIR/resources_linux_amd64" qdl 17 | 18 | # Download and extract Linux arm64 19 | mkdir -p "$BASE_DIR/resources_linux_arm64" 20 | gh release download "$TAG" --repo "$REPO" --pattern "qdl_*_Linux_ARM64.tar.gz" --dir "$BASE_DIR/resources_linux_arm64" 21 | tar -xzf $BASE_DIR/resources_linux_arm64/qdl_*_Linux_ARM64.tar.gz -C "$BASE_DIR/resources_linux_arm64" qdl 22 | 23 | # Download and extract Windows 32-bit 24 | mkdir -p "$BASE_DIR/resources_windows_amd64" 25 | gh release download "$TAG" --repo "$REPO" --pattern "qdl_*_Windows_32bit.tar.gz" --dir "$BASE_DIR/resources_windows_amd64" 26 | tar -xzf $BASE_DIR/resources_windows_amd64/qdl_*_Windows_32bit.tar.gz -C "$BASE_DIR/resources_windows_amd64" qdl.exe 27 | 28 | # Download and extract macOS 64-bit 29 | mkdir -p "$BASE_DIR/resources_darwin_amd64" 30 | gh release download "$TAG" --repo "$REPO" --pattern "qdl_*_macOS_64bit.tar.gz" --dir "$BASE_DIR/resources_darwin_amd64" 31 | tar -xzf $BASE_DIR/resources_darwin_amd64/qdl_*_macOS_64bit.tar.gz -C "$BASE_DIR/resources_darwin_amd64" qdl 32 | 33 | # Download and extract macOS arm64 34 | mkdir -p "$BASE_DIR/resources_darwin_arm64" 35 | gh release download "$TAG" --repo "$REPO" --pattern "qdl_*_macOS_arm64.tar.gz" --dir "$BASE_DIR/resources_darwin_arm64" 36 | tar -xzf $BASE_DIR/resources_darwin_arm64/qdl_*_macOS_arm64.tar.gz -C "$BASE_DIR/resources_darwin_arm64" qdl 37 | 38 | # cleanup archive files 39 | rm -rf $BASE_DIR/resources_*/*.tar.gz 40 | 41 | echo "All files downloaded, extracted, and organized successfully." 42 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/go.bug.st/f.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: go.bug.st/f 3 | version: v0.4.0 4 | type: go 5 | summary: Package f is a golang library implementing some basic algorithms. 6 | homepage: https://pkg.go.dev/go.bug.st/f 7 | license: bsd-3-clause 8 | licenses: 9 | - sources: LICENSE 10 | text: |2+ 11 | 12 | Copyright (c) 2024, Cristian Maglie. 13 | All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions 17 | are met: 18 | 19 | 1. Redistributions of source code must retain the above copyright 20 | notice, this list of conditions and the following disclaimer. 21 | 22 | 2. Redistributions in binary form must reproduce the above copyright 23 | notice, this list of conditions and the following disclaimer in 24 | the documentation and/or other materials provided with the 25 | distribution. 26 | 27 | 3. Neither the name of the copyright holder nor the names of its 28 | contributors may be used to endorse or promote products derived 29 | from this software without specific prior written permission. 30 | 31 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 34 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 35 | COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 36 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 37 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 38 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 39 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 41 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | notices: [] 45 | ... 46 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/ulikunitz/xz/internal/xlog.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/ulikunitz/xz/internal/xlog 3 | version: v0.5.12 4 | type: go 5 | summary: Package xlog provides a simple logging package that allows to disable certain 6 | message categories. 7 | homepage: https://pkg.go.dev/github.com/ulikunitz/xz/internal/xlog 8 | license: bsd-3-clause 9 | licenses: 10 | - sources: xz@v0.5.12/LICENSE 11 | text: | 12 | Copyright (c) 2014-2022 Ulrich Kunitz 13 | All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | * Redistributions of source code must retain the above copyright notice, this 19 | list of conditions and the following disclaimer. 20 | 21 | * Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation 23 | and/or other materials provided with the distribution. 24 | 25 | * My name, Ulrich Kunitz, may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 29 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 32 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 34 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 35 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 36 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | notices: [] 39 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/spf13/pflag.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/spf13/pflag 3 | version: v1.0.7 4 | type: go 5 | summary: Package pflag is a drop-in replacement for Go's flag package, implementing 6 | POSIX/GNU-style --flags. 7 | homepage: https://pkg.go.dev/github.com/spf13/pflag 8 | license: bsd-3-clause 9 | licenses: 10 | - sources: LICENSE 11 | text: | 12 | Copyright (c) 2012 Alex Ogier. All rights reserved. 13 | Copyright (c) 2012 The Go Authors. All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are 17 | met: 18 | 19 | * Redistributions of source code must retain the above copyright 20 | notice, this list of conditions and the following disclaimer. 21 | * Redistributions in binary form must reproduce the above 22 | copyright notice, this list of conditions and the following disclaimer 23 | in the documentation and/or other materials provided with the 24 | distribution. 25 | * Neither the name of Google Inc. nor the names of its 26 | contributors may be used to endorse or promote products derived from 27 | this software without specific prior written permission. 28 | 29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | notices: [] 41 | -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/version/check_for_updates.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package version 17 | 18 | import ( 19 | "encoding/json" 20 | "fmt" 21 | "net/http" 22 | "strings" 23 | "time" 24 | 25 | semver "go.bug.st/relaxed-semver" 26 | ) 27 | 28 | const maxTime time.Duration = 1 * time.Second 29 | 30 | func checkForUpdates(version string) (string, error) { 31 | currentVersion, err := semver.Parse(version) 32 | if err != nil { 33 | return "", err 34 | } 35 | 36 | client := http.Client{Timeout: maxTime} 37 | resp, err := client.Get("https://api.github.com/repos/arduino/arduino-flasher-cli/releases/latest") 38 | if err != nil { 39 | return "", err 40 | } 41 | defer resp.Body.Close() 42 | if resp.StatusCode != http.StatusOK { 43 | return "", fmt.Errorf("failed to fetch latest release: status code %d", resp.StatusCode) 44 | } 45 | var release struct { 46 | TagName string `json:"tag_name"` 47 | } 48 | err = json.NewDecoder(resp.Body).Decode(&release) 49 | if err != nil { 50 | return "", err 51 | } 52 | 53 | release.TagName = strings.TrimPrefix(release.TagName, "v") 54 | latestVersion, err := semver.Parse(release.TagName) 55 | if err != nil { 56 | return "", err 57 | } 58 | 59 | // Do nothing if the Arduino Flasher CLI is up to date 60 | if currentVersion.GreaterThanOrEqual(latestVersion) { 61 | return "", nil 62 | } 63 | 64 | return latestVersion.String(), nil 65 | } 66 | -------------------------------------------------------------------------------- /cmd/feedback/errorcodes.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package feedback 17 | 18 | // ExitCode to be used for Fatal. 19 | type ExitCode int 20 | 21 | const ( 22 | // Success (0 is the no-error return code in Unix) 23 | Success ExitCode = iota 24 | 25 | // ErrGeneric Generic error (1 is the reserved "catchall" code in Unix) 26 | ErrGeneric 27 | 28 | _ // (2 Is reserved in Unix) 29 | 30 | // ErrNoConfigFile is returned when the config file is not found (3) 31 | ErrNoConfigFile 32 | 33 | _ // (4 was ErrBadCall and has been removed) 34 | 35 | // ErrNetwork is returned when a network error occurs (5) 36 | ErrNetwork 37 | 38 | // ErrCoreConfig represents an error in the cli core config, for example some basic 39 | // files shipped with the installation are missing, or cannot create or get basic 40 | // directories vital for the CLI to work. (6) 41 | ErrCoreConfig 42 | 43 | // ErrBadArgument is returned when the arguments are not valid (7) 44 | ErrBadArgument 45 | 46 | // ErrFailedToListenToTCPPort is returned if the CLI failed to open a TCP port 47 | // to listen for incoming connections (8) 48 | ErrFailedToListenToTCPPort 49 | 50 | // ErrBadTCPPortArgument is returned if the TCP port argument is not valid (9) 51 | ErrBadTCPPortArgument 52 | 53 | // ErrInitializingInventory is returned when the inventory cannot be initialized, 54 | // usually depends on a wrong configuration of the data dir (10) 55 | ErrInitializingInventory 56 | 57 | // ErrMissingProgrammer is returned when the programmer argument is missing (11) 58 | ErrMissingProgrammer 59 | ) 60 | -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/version/version.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package version 17 | 18 | import ( 19 | "fmt" 20 | 21 | "github.com/fatih/color" 22 | "github.com/spf13/cobra" 23 | 24 | "github.com/arduino/arduino-flasher-cli/cmd/feedback" 25 | "github.com/arduino/arduino-flasher-cli/cmd/i18n" 26 | ) 27 | 28 | func NewVersionCmd(version string) *cobra.Command { 29 | cmd := &cobra.Command{ 30 | Use: "version", 31 | Short: "Print the version number of Arduino Flasher CLI", 32 | Run: func(cmd *cobra.Command, args []string) { 33 | feedback.PrintResult(versionResult{ 34 | Name: "Arduino Flasher CLI", 35 | Version: version, 36 | }) 37 | 38 | latest, err := checkForUpdates(version) 39 | if err != nil { 40 | feedback.Warning(color.YellowString("\n\nFailed to check for updates: "+err.Error()) + "\n") 41 | } 42 | if latest != "" { 43 | msg := fmt.Sprintf("\n\n%s %s → %s\n%s", 44 | color.YellowString(i18n.Tr("A new release of Arduino Flasher CLI is available:")), 45 | color.CyanString(version), 46 | color.CyanString(latest), 47 | color.YellowString("https://www.arduino.cc/en/software/#flasher-tool")) 48 | feedback.Warning(msg) 49 | } 50 | }, 51 | } 52 | return cmd 53 | } 54 | 55 | type versionResult struct { 56 | Name string `json:"name"` 57 | Version string `json:"version"` 58 | } 59 | 60 | func (r versionResult) String() string { 61 | resultMessage := fmt.Sprintf("Arduino Flasher CLI version %s", r.Version) 62 | return resultMessage 63 | } 64 | 65 | func (r versionResult) Data() interface{} { 66 | return r 67 | } 68 | -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/drivers/drivers_windows.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package drivers 17 | 18 | import ( 19 | "embed" 20 | "log/slog" 21 | "runtime" 22 | 23 | "github.com/arduino/go-paths-helper" 24 | ) 25 | 26 | //go:embed src 27 | var drivers embed.FS 28 | 29 | // installDrivers installs the Windows driver using dpinst.exe. This requires 30 | // administrative privileges. 31 | func installDrivers() error { 32 | tmpDir, err := paths.MkTempDir("", "arduino-flasher-windriver-") 33 | if err != nil { 34 | return err 35 | } 36 | defer tmpDir.RemoveAll() 37 | 38 | dpinstArch := "drivers/dpinst-x86.exe" 39 | if runtime.GOARCH == "amd64" { 40 | dpinstArch = "drivers/dpinst-amd64.exe" 41 | } 42 | dpinst, err := drivers.ReadFile(dpinstArch) 43 | if err != nil { 44 | return err 45 | } 46 | driverCat, err := drivers.ReadFile("drivers/unoq.cat") 47 | if err != nil { 48 | return err 49 | } 50 | driverInf, err := drivers.ReadFile("drivers/unoq.inf") 51 | if err != nil { 52 | return err 53 | } 54 | dpinstPath := tmpDir.Join("dpinst.exe") 55 | err = dpinstPath.WriteFile(dpinst) 56 | if err != nil { 57 | return err 58 | } 59 | catPath := tmpDir.Join("unoq.cat") 60 | err = catPath.WriteFile(driverCat) 61 | if err != nil { 62 | return err 63 | } 64 | infPath := tmpDir.Join("unoq.inf") 65 | err = infPath.WriteFile(driverInf) 66 | if err != nil { 67 | return err 68 | } 69 | 70 | slog.Info("Installing Windows driver") 71 | dpinstProc, err := paths.NewProcessFromPath(nil, dpinstPath, "/SE", "/SW", "/SA") 72 | if err != nil { 73 | return err 74 | } 75 | dpinstProc.SetDir(tmpDir.String()) 76 | return dpinstProc.Run() 77 | } 78 | -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/download/download.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package download 17 | 18 | import ( 19 | "context" 20 | "os" 21 | 22 | "github.com/arduino/go-paths-helper" 23 | "github.com/spf13/cobra" 24 | 25 | "github.com/arduino/arduino-flasher-cli/cmd/feedback" 26 | "github.com/arduino/arduino-flasher-cli/cmd/i18n" 27 | "github.com/arduino/arduino-flasher-cli/internal/updater" 28 | ) 29 | 30 | func NewDownloadCmd() *cobra.Command { 31 | var destDir string 32 | cmd := &cobra.Command{ 33 | Use: "download", 34 | Short: "Download a Linux image to the specified path", 35 | Args: cobra.ExactArgs(1), 36 | Example: " " + os.Args[0] + " download latest\n" + 37 | " " + os.Args[0] + " download 20251024-412\n" + 38 | " " + os.Args[0] + " download latest --dest-dir /tmp\n", 39 | Run: func(cmd *cobra.Command, args []string) { 40 | runDownloadCommand(cmd.Context(), args, destDir) 41 | }, 42 | } 43 | cmd.Flags().StringVar(&destDir, "dest-dir", ".", "Path to the directory in which the image will be downloaded") 44 | 45 | return cmd 46 | } 47 | 48 | func runDownloadCommand(ctx context.Context, args []string, destDir string) { 49 | targetVersion := args[0] 50 | downloadPath := paths.New(destDir) 51 | if !downloadPath.IsDir() { 52 | feedback.Fatal(i18n.Tr("error: %s is not a directory. Please, select an existing directory.", destDir), feedback.ErrBadArgument) 53 | } 54 | 55 | downloadPath, _, err := updater.DownloadImage(ctx, targetVersion, downloadPath) 56 | if err != nil { 57 | feedback.Fatal(i18n.Tr("error downloading the image: %v", err), feedback.ErrBadArgument) 58 | } 59 | pathAbs, _ := downloadPath.Abs() 60 | feedback.Print(i18n.Tr("\nDebian image successfully downloaded: %s", pathAbs.String())) 61 | } 62 | -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/list/list.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package list 17 | 18 | import ( 19 | "context" 20 | 21 | "github.com/jedib0t/go-pretty/v6/table" 22 | "github.com/spf13/cobra" 23 | 24 | "github.com/arduino/arduino-flasher-cli/cmd/feedback" 25 | "github.com/arduino/arduino-flasher-cli/cmd/i18n" 26 | "github.com/arduino/arduino-flasher-cli/internal/tablestyle" 27 | "github.com/arduino/arduino-flasher-cli/internal/updater" 28 | ) 29 | 30 | func NewListCmd() *cobra.Command { 31 | cmd := &cobra.Command{ 32 | Use: "list", 33 | Short: "List the available Linux images", 34 | Args: cobra.NoArgs, 35 | Run: func(cmd *cobra.Command, args []string) { 36 | runListCommand(cmd.Context()) 37 | }, 38 | } 39 | return cmd 40 | } 41 | 42 | func runListCommand(ctx context.Context) { 43 | client := updater.NewClient() 44 | 45 | manifest, err := client.GetInfoManifest(ctx) 46 | if err != nil { 47 | feedback.Fatal(i18n.Tr("error retrieving the manifest: %v", err), feedback.ErrBadArgument) 48 | } 49 | 50 | feedback.PrintResult(listResult{Latest: manifest.Latest, Releases: manifest.Releases}) 51 | } 52 | 53 | type listResult struct { 54 | Latest updater.Release `json:"latest"` 55 | Releases []updater.Release `json:"releases"` 56 | } 57 | 58 | // Data implements Result interface 59 | func (lr listResult) Data() interface{} { 60 | return lr 61 | } 62 | 63 | // String implements Result interface 64 | func (lr listResult) String() string { 65 | t := table.NewWriter() 66 | t.SetStyle(tablestyle.CustomCleanStyle) 67 | t.AppendHeader(table.Row{"VERSION", "LATEST"}) 68 | 69 | for i := len(lr.Releases) - 1; i >= 0; i-- { 70 | row := table.Row{lr.Releases[i].Version} 71 | if lr.Releases[i].Version == lr.Latest.Version { 72 | row = append(row, "✓") 73 | } 74 | t.AppendRow(row) 75 | } 76 | return t.Render() 77 | } 78 | -------------------------------------------------------------------------------- /.licensed.yml: -------------------------------------------------------------------------------- 1 | sources: 2 | go: true 3 | 4 | cache_path: .licenses 5 | 6 | apps: 7 | - source_path: . 8 | 9 | # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-dependencies/GPL-3.0/.licensed.yml 10 | allowed: 11 | # The following are based on: https://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses 12 | - gpl-1.0-or-later 13 | - gpl-1.0+ # Deprecated ID for `gpl-1.0-or-later` 14 | - gpl-2.0-or-later 15 | - gpl-2.0+ # Deprecated ID for `gpl-2.0-or-later` 16 | - gpl-3.0-only 17 | - gpl-3.0 # Deprecated ID for `gpl-3.0-only` 18 | - gpl-3.0-or-later 19 | - gpl-3.0+ # Deprecated ID for `gpl-3.0-or-later` 20 | - lgpl-2.0-or-later 21 | - lgpl-2.0+ # Deprecated ID for `lgpl-2.0-or-later` 22 | - lgpl-2.1-only 23 | - lgpl-2.1 # Deprecated ID for `lgpl-2.1-only` 24 | - lgpl-2.1-or-later 25 | - lgpl-2.1+ # Deprecated ID for `lgpl-2.1-or-later` 26 | - lgpl-3.0-only 27 | - lgpl-3.0 # Deprecated ID for `lgpl-3.0-only` 28 | - lgpl-3.0-or-later 29 | - lgpl-3.0+ # Deprecated ID for `lgpl-3.0-or-later` 30 | - fsfap 31 | - apache-2.0 32 | - artistic-2.0 33 | - clartistic 34 | - sleepycat 35 | - bsl-1.0 36 | - bsd-3-clause 37 | - cecill-2.0 38 | - bsd-3-clause-clear 39 | # "Cryptix General License" - no SPDX ID (https://github.com/spdx/license-list-XML/issues/456) 40 | - ecos-2.0 41 | - ecl-2.0 42 | - efl-2.0 43 | - eudatagrid 44 | - mit 45 | - bsd-2-clause # Subsumed by `bsd-2-clause-views` 46 | - bsd-2-clause-netbsd # Deprecated ID for `bsd-2-clause` 47 | - bsd-2-clause-views # This is the version linked from https://www.gnu.org/licenses/license-list.html#FreeBSD 48 | - bsd-2-clause-freebsd # Deprecated ID for `bsd-2-clause-views` 49 | - ftl 50 | - hpnd 51 | - imatix 52 | - imlib2 53 | - ijg 54 | # "Informal license" - this is a general class of license 55 | - intel 56 | - isc 57 | - mpl-2.0 58 | - ncsa 59 | # "License of Netscape JavaScript" - no SPDX ID 60 | - oldap-2.7 61 | # "License of Perl 5 and below" - possibly `Artistic-1.0-Perl` ? 62 | - cc0-1.0 63 | - cc-pddc 64 | - psf-2.0 65 | - ruby 66 | - sgi-b-2.0 67 | - smlnj 68 | - standardml-nj # Deprecated ID for `smlnj` 69 | - unicode-dfs-2015 70 | - upl-1.0 71 | - unlicense 72 | - vim 73 | - w3c 74 | - wtfpl 75 | - lgpl-2.0-or-later with wxwindows-exception-3.1 76 | - wxwindows # Deprecated ID for `lgpl-2.0-or-later with wxwindows-exception-3.1` 77 | - x11 78 | - xfree86-1.1 79 | - zlib 80 | - zpl-2.0 81 | - zpl-2.1 82 | # The following are based on individual license text 83 | - eupl-1.2 84 | - liliq-r-1.1 85 | - liliq-rplus-1.1 86 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/arduino/go-windows-runas.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/arduino/go-windows-runas 3 | version: v1.0.1 4 | type: go 5 | summary: 6 | homepage: https://pkg.go.dev/github.com/arduino/go-windows-runas 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | Copyright (c) 2025, ARDUINO SA. 12 | All rights reserved. 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy 15 | of this software and associated documentation files (the “Software”), to deal 16 | in the Software without restriction, including without limitation the rights 17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the Software is furnished 19 | to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in all 22 | copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 | SOFTWARE 31 | - sources: README.md 32 | text: |- 33 | Copyright (c) 2025, ARDUINO SA. 34 | All rights reserved. 35 | 36 | Permission is hereby granted, free of charge, to any person obtaining a copy 37 | of this software and associated documentation files (the “Software”), to deal 38 | in the Software without restriction, including without limitation the rights 39 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 40 | copies of the Software, and to permit persons to whom the Software is furnished 41 | to do so, subject to the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included in all 44 | copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 47 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 48 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 49 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 50 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 51 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 52 | SOFTWARE 53 | notices: [] 54 | -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/main.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package main 17 | 18 | import ( 19 | "context" 20 | "log/slog" 21 | "os" 22 | 23 | "github.com/spf13/cobra" 24 | "go.bug.st/cleanup" 25 | 26 | "github.com/arduino/arduino-flasher-cli/cmd/arduino-flasher-cli/daemon" 27 | "github.com/arduino/arduino-flasher-cli/cmd/arduino-flasher-cli/download" 28 | "github.com/arduino/arduino-flasher-cli/cmd/arduino-flasher-cli/drivers" 29 | "github.com/arduino/arduino-flasher-cli/cmd/arduino-flasher-cli/flash" 30 | "github.com/arduino/arduino-flasher-cli/cmd/arduino-flasher-cli/list" 31 | "github.com/arduino/arduino-flasher-cli/cmd/arduino-flasher-cli/version" 32 | "github.com/arduino/arduino-flasher-cli/cmd/feedback" 33 | "github.com/arduino/arduino-flasher-cli/cmd/i18n" 34 | "github.com/arduino/arduino-flasher-cli/service" 35 | ) 36 | 37 | // Version will be set a build time with -ldflags 38 | var Version string = "0.0.0-dev" 39 | var format string 40 | 41 | func main() { 42 | rootCmd := &cobra.Command{ 43 | Use: "arduino-flasher-cli", 44 | Short: "A CLI to update your Arduino UNO Q board, by downloading and flashing the latest Arduino Linux image", 45 | Example: " " + os.Args[0] + " flash latest\n" + 46 | " " + os.Args[0] + " list\n", 47 | PersistentPreRun: func(cmd *cobra.Command, args []string) { 48 | format, ok := feedback.ParseOutputFormat(format) 49 | if !ok { 50 | feedback.Fatal(i18n.Tr("Invalid output format: %s", format), feedback.ErrBadArgument) 51 | } 52 | feedback.SetFormat(format) 53 | }, 54 | SilenceUsage: true, 55 | SilenceErrors: true, 56 | } 57 | 58 | rootCmd.PersistentFlags().StringVar(&format, "format", "text", "Output format (text, json)") 59 | 60 | rootCmd.AddCommand( 61 | flash.NewFlashCmd(), 62 | drivers.NewInstallDriversCmd(), 63 | list.NewListCmd(), 64 | download.NewDownloadCmd(), 65 | version.NewVersionCmd(Version), 66 | daemon.NewDaemonCommand(service.NewFlasherServer()), 67 | ) 68 | 69 | ctx := context.Background() 70 | ctx, _ = cleanup.InterruptableContext(ctx) 71 | if err := rootCmd.ExecuteContext(ctx); err != nil { 72 | slog.Error(err.Error()) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /cmd/i18n/i18n_test.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package i18n 17 | 18 | import ( 19 | "bytes" 20 | "testing" 21 | "text/template" 22 | 23 | "github.com/leonelquinteros/gotext" 24 | "github.com/stretchr/testify/require" 25 | ) 26 | 27 | func setPo(poFile string) { 28 | dict := gotext.NewPo() 29 | dict.Parse([]byte(poFile)) 30 | SetLocale(dict) 31 | } 32 | 33 | func TestPoTranslation(t *testing.T) { 34 | setPo(` 35 | msgid "test-key-ok" 36 | msgstr "test-key-translated" 37 | `) 38 | require.Equal(t, "test-key", Tr("test-key")) 39 | require.Equal(t, "test-key-translated", Tr("test-key-ok")) 40 | } 41 | 42 | func TestNoLocaleSet(t *testing.T) { 43 | locale = gotext.NewPo() 44 | require.Equal(t, "test-key", Tr("test-key")) 45 | } 46 | 47 | func TestTranslationWithVariables(t *testing.T) { 48 | setPo(` 49 | msgid "test-key-ok %s" 50 | msgstr "test-key-translated %s" 51 | `) 52 | require.Equal(t, "test-key", Tr("test-key")) 53 | require.Equal(t, "test-key-translated message", Tr("test-key-ok %s", "message")) 54 | } 55 | 56 | func TestTranslationInTemplate(t *testing.T) { 57 | setPo(` 58 | msgid "test-key" 59 | msgstr "test-key-translated %s" 60 | `) 61 | 62 | tpl, err := template.New("test-template").Funcs(template.FuncMap{ 63 | "tr": Tr, 64 | }).Parse(`{{ tr "test-key" .Value }}`) 65 | require.NoError(t, err) 66 | 67 | data := struct { 68 | Value string 69 | }{ 70 | "value", 71 | } 72 | var buf bytes.Buffer 73 | require.NoError(t, tpl.Execute(&buf, data)) 74 | 75 | require.Equal(t, "test-key-translated value", buf.String()) 76 | } 77 | 78 | func TestTranslationWithQuotedStrings(t *testing.T) { 79 | setPo(` 80 | msgid "test-key \"quoted\"" 81 | msgstr "test-key-translated" 82 | `) 83 | 84 | require.Equal(t, "test-key-translated", Tr("test-key \"quoted\"")) 85 | require.Equal(t, "test-key-translated", Tr(`test-key "quoted"`)) 86 | } 87 | 88 | func TestTranslationWithLineBreaks(t *testing.T) { 89 | setPo(` 90 | msgid "test-key \"quoted\"\n" 91 | "new line" 92 | msgstr "test-key-translated" 93 | `) 94 | 95 | require.Equal(t, "test-key-translated", Tr("test-key \"quoted\"\nnew line")) 96 | require.Equal(t, "test-key-translated", Tr(`test-key "quoted" 97 | new line`)) 98 | } 99 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/golang.org/x/term.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: golang.org/x/term 3 | version: v0.35.0 4 | type: go 5 | summary: Package term provides support functions for dealing with terminals, as commonly 6 | found on UNIX systems. 7 | homepage: https://pkg.go.dev/golang.org/x/term 8 | license: bsd-3-clause 9 | licenses: 10 | - sources: LICENSE 11 | text: | 12 | Copyright 2009 The Go Authors. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are 16 | met: 17 | 18 | * Redistributions of source code must retain the above copyright 19 | notice, this list of conditions and the following disclaimer. 20 | * Redistributions in binary form must reproduce the above 21 | copyright notice, this list of conditions and the following disclaimer 22 | in the documentation and/or other materials provided with the 23 | distribution. 24 | * Neither the name of Google LLC nor the names of its 25 | contributors may be used to endorse or promote products derived from 26 | this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | - sources: PATENTS 40 | text: | 41 | Additional IP Rights Grant (Patents) 42 | 43 | "This implementation" means the copyrightable works distributed by 44 | Google as part of the Go project. 45 | 46 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 47 | no-charge, royalty-free, irrevocable (except as stated in this section) 48 | patent license to make, have made, use, offer to sell, sell, import, 49 | transfer and otherwise run, modify and propagate the contents of this 50 | implementation of Go, where such license applies only to those patent 51 | claims, both currently owned or controlled by Google and acquired in 52 | the future, licensable by Google that are necessarily infringed by this 53 | implementation of Go. This grant does not include claims that would be 54 | infringed only as a consequence of further modification of this 55 | implementation. If you or your agent or exclusive licensee institute or 56 | order or agree to the institution of patent litigation against any 57 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 58 | that this implementation of Go or any code incorporated within this 59 | implementation of Go constitutes direct or contributory patent 60 | infringement, or inducement of patent infringement, then any patent 61 | rights granted to you under this License for this implementation of Go 62 | shall terminate as of the date such litigation is filed. 63 | notices: [] 64 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/golang.org/x/sys/unix.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: golang.org/x/sys/unix 3 | version: v0.37.0 4 | type: go 5 | summary: Package unix contains an interface to the low-level operating system primitives. 6 | homepage: https://pkg.go.dev/golang.org/x/sys/unix 7 | license: bsd-3-clause 8 | licenses: 9 | - sources: sys@v0.37.0/LICENSE 10 | text: | 11 | Copyright 2009 The Go Authors. 12 | 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are 15 | met: 16 | 17 | * Redistributions of source code must retain the above copyright 18 | notice, this list of conditions and the following disclaimer. 19 | * Redistributions in binary form must reproduce the above 20 | copyright notice, this list of conditions and the following disclaimer 21 | in the documentation and/or other materials provided with the 22 | distribution. 23 | * Neither the name of Google LLC nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | - sources: sys@v0.37.0/PATENTS 39 | text: | 40 | Additional IP Rights Grant (Patents) 41 | 42 | "This implementation" means the copyrightable works distributed by 43 | Google as part of the Go project. 44 | 45 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 46 | no-charge, royalty-free, irrevocable (except as stated in this section) 47 | patent license to make, have made, use, offer to sell, sell, import, 48 | transfer and otherwise run, modify and propagate the contents of this 49 | implementation of Go, where such license applies only to those patent 50 | claims, both currently owned or controlled by Google and acquired in 51 | the future, licensable by Google that are necessarily infringed by this 52 | implementation of Go. This grant does not include claims that would be 53 | infringed only as a consequence of further modification of this 54 | implementation. If you or your agent or exclusive licensee institute or 55 | order or agree to the institution of patent litigation against any 56 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 57 | that this implementation of Go or any code incorporated within this 58 | implementation of Go constitutes direct or contributory patent 59 | infringement, or inducement of patent infringement, then any patent 60 | rights granted to you under this License for this implementation of Go 61 | shall terminate as of the date such litigation is filed. 62 | notices: [] 63 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/golang.org/x/text/width.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: golang.org/x/text/width 3 | version: v0.24.0 4 | type: go 5 | summary: Package width provides functionality for handling different widths in text. 6 | homepage: https://pkg.go.dev/golang.org/x/text/width 7 | license: bsd-3-clause 8 | licenses: 9 | - sources: text@v0.24.0/LICENSE 10 | text: | 11 | Copyright 2009 The Go Authors. 12 | 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are 15 | met: 16 | 17 | * Redistributions of source code must retain the above copyright 18 | notice, this list of conditions and the following disclaimer. 19 | * Redistributions in binary form must reproduce the above 20 | copyright notice, this list of conditions and the following disclaimer 21 | in the documentation and/or other materials provided with the 22 | distribution. 23 | * Neither the name of Google LLC nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | - sources: text@v0.24.0/PATENTS 39 | text: | 40 | Additional IP Rights Grant (Patents) 41 | 42 | "This implementation" means the copyrightable works distributed by 43 | Google as part of the Go project. 44 | 45 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 46 | no-charge, royalty-free, irrevocable (except as stated in this section) 47 | patent license to make, have made, use, offer to sell, sell, import, 48 | transfer and otherwise run, modify and propagate the contents of this 49 | implementation of Go, where such license applies only to those patent 50 | claims, both currently owned or controlled by Google and acquired in 51 | the future, licensable by Google that are necessarily infringed by this 52 | implementation of Go. This grant does not include claims that would be 53 | infringed only as a consequence of further modification of this 54 | implementation. If you or your agent or exclusive licensee institute or 55 | order or agree to the institution of patent litigation against any 56 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 57 | that this implementation of Go or any code incorporated within this 58 | implementation of Go constitutes direct or contributory patent 59 | infringement, or inducement of patent infringement, then any patent 60 | rights granted to you under this License for this implementation of Go 61 | shall terminate as of the date such litigation is filed. 62 | notices: [] 63 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/gopkg.in/yaml.v3.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: gopkg.in/yaml.v3 3 | version: v3.0.1 4 | type: go 5 | summary: Package yaml implements YAML support for the Go language. 6 | homepage: https://pkg.go.dev/gopkg.in/yaml.v3 7 | license: apache-2.0 8 | licenses: 9 | - sources: LICENSE 10 | text: |2 11 | 12 | This project is covered by two different licenses: MIT and Apache. 13 | 14 | #### MIT License #### 15 | 16 | The following files were ported to Go from C files of libyaml, and thus 17 | are still covered by their original MIT license, with the additional 18 | copyright staring in 2011 when the project was ported over: 19 | 20 | apic.go emitterc.go parserc.go readerc.go scannerc.go 21 | writerc.go yamlh.go yamlprivateh.go 22 | 23 | Copyright (c) 2006-2010 Kirill Simonov 24 | Copyright (c) 2006-2011 Kirill Simonov 25 | 26 | Permission is hereby granted, free of charge, to any person obtaining a copy of 27 | this software and associated documentation files (the "Software"), to deal in 28 | the Software without restriction, including without limitation the rights to 29 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 30 | of the Software, and to permit persons to whom the Software is furnished to do 31 | so, subject to the following conditions: 32 | 33 | The above copyright notice and this permission notice shall be included in all 34 | copies or substantial portions of the Software. 35 | 36 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 37 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 38 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 39 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 40 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 41 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 42 | SOFTWARE. 43 | 44 | ### Apache License ### 45 | 46 | All the remaining project files are covered by the Apache license: 47 | 48 | Copyright (c) 2011-2019 Canonical Ltd 49 | 50 | Licensed under the Apache License, Version 2.0 (the "License"); 51 | you may not use this file except in compliance with the License. 52 | You may obtain a copy of the License at 53 | 54 | http://www.apache.org/licenses/LICENSE-2.0 55 | 56 | Unless required by applicable law or agreed to in writing, software 57 | distributed under the License is distributed on an "AS IS" BASIS, 58 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 59 | See the License for the specific language governing permissions and 60 | limitations under the License. 61 | - sources: README.md 62 | text: |- 63 | The yaml package is licensed under the MIT and Apache License 2.0 licenses. 64 | Please see the LICENSE file for details. 65 | notices: 66 | - sources: NOTICE 67 | text: |- 68 | Copyright 2011-2016 Canonical Ltd. 69 | 70 | Licensed under the Apache License, Version 2.0 (the "License"); 71 | you may not use this file except in compliance with the License. 72 | You may obtain a copy of the License at 73 | 74 | http://www.apache.org/licenses/LICENSE-2.0 75 | 76 | Unless required by applicable law or agreed to in writing, software 77 | distributed under the License is distributed on an "AS IS" BASIS, 78 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 79 | See the License for the specific language governing permissions and 80 | limitations under the License. 81 | -------------------------------------------------------------------------------- /cmd/feedback/feedback_test.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package feedback 17 | 18 | import ( 19 | "bytes" 20 | "encoding/json" 21 | "fmt" 22 | "testing" 23 | 24 | "github.com/stretchr/testify/require" 25 | ) 26 | 27 | func TestOutputSelection(t *testing.T) { 28 | reset() 29 | 30 | myErr := new(bytes.Buffer) 31 | myOut := new(bytes.Buffer) 32 | SetOut(myOut) 33 | SetErr(myErr) 34 | SetFormat(Text) 35 | 36 | // Could not change output stream after format has been set 37 | require.Panics(t, func() { SetOut(nil) }) 38 | require.Panics(t, func() { SetErr(nil) }) 39 | 40 | // Coule not change output format twice 41 | require.Panics(t, func() { SetFormat(JSON) }) 42 | 43 | Print("Hello") 44 | require.Equal(t, myOut.String(), "Hello\n") 45 | } 46 | 47 | func TestJSONOutputStream(t *testing.T) { 48 | reset() 49 | 50 | require.Panics(t, func() { OutputStreams() }) 51 | 52 | SetFormat(JSON) 53 | stdout, stderr, res := OutputStreams() 54 | fmt.Fprint(stdout, "Hello") 55 | fmt.Fprint(stderr, "Hello ERR") 56 | 57 | d, err := json.Marshal(res()) 58 | require.NoError(t, err) 59 | require.JSONEq(t, `{"stdout":"Hello","stderr":"Hello ERR"}`, string(d)) 60 | 61 | stdout.Write([]byte{0xc2, 'A'}) // Invaid UTF-8 62 | 63 | d, err = json.Marshal(res()) 64 | require.NoError(t, err) 65 | require.JSONEq(t, string(d), `{"stdout":"Hello\ufffdA","stderr":"Hello ERR"}`) 66 | } 67 | 68 | func TestJsonOutputOnCustomStreams(t *testing.T) { 69 | reset() 70 | 71 | myErr := new(bytes.Buffer) 72 | myOut := new(bytes.Buffer) 73 | SetOut(myOut) 74 | SetErr(myErr) 75 | SetFormat(JSON) 76 | 77 | // Could not change output stream after format has been set 78 | require.Panics(t, func() { SetOut(nil) }) 79 | require.Panics(t, func() { SetErr(nil) }) 80 | // Could not change output format twice 81 | require.Panics(t, func() { SetFormat(JSON) }) 82 | 83 | Print("Hello") // Output interactive data 84 | 85 | require.Equal(t, "", myOut.String()) 86 | require.Equal(t, "", myErr.String()) 87 | require.Equal(t, "Hello\n", bufferOut.String()) 88 | 89 | PrintResult(&testResult{Success: true}) 90 | 91 | require.JSONEq(t, myOut.String(), `{ "success": true }`) 92 | require.Equal(t, myErr.String(), "") 93 | myOut.Reset() 94 | 95 | _, _, res := OutputStreams() 96 | PrintResult(&testResult{Success: false, Output: res()}) 97 | 98 | require.JSONEq(t, ` 99 | { 100 | "success": false, 101 | "output": { 102 | "stdout": "Hello\n", 103 | "stderr": "" 104 | } 105 | }`, myOut.String()) 106 | require.Equal(t, myErr.String(), "") 107 | } 108 | 109 | type testResult struct { 110 | Success bool `json:"success"` 111 | Output *OutputStreamsResult `json:"output,omitempty"` 112 | } 113 | 114 | func (r *testResult) Data() interface{} { 115 | return r 116 | } 117 | 118 | func (r *testResult) String() string { 119 | if r.Success { 120 | return "Success" 121 | } 122 | return "Failure" 123 | } 124 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/shirou/gopsutil/v4/disk.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/shirou/gopsutil/v4/disk 3 | version: v4.25.10 4 | type: go 5 | summary: 'SPDX-License-Identifier: BSD-3-Clause' 6 | homepage: https://pkg.go.dev/github.com/shirou/gopsutil/v4/disk 7 | license: bsd-3-clause 8 | licenses: 9 | - sources: v4@v4.25.10/LICENSE 10 | text: |- 11 | gopsutil is distributed under BSD license reproduced below. 12 | 13 | Copyright (c) 2014, WAKAYAMA Shirou 14 | All rights reserved. 15 | 16 | Redistribution and use in source and binary forms, with or without modification, 17 | are permitted provided that the following conditions are met: 18 | 19 | * Redistributions of source code must retain the above copyright notice, this 20 | list of conditions and the following disclaimer. 21 | * Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation 23 | and/or other materials provided with the distribution. 24 | * Neither the name of the gopsutil authors nor the names of its contributors 25 | may be used to endorse or promote products derived from this software without 26 | specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 29 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 30 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 32 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 33 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 34 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 35 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 37 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | 39 | 40 | ------- 41 | internal/common/binary.go in the gopsutil is copied and modified from golang/encoding/binary.go. 42 | 43 | 44 | 45 | Copyright (c) 2009 The Go Authors. All rights reserved. 46 | 47 | Redistribution and use in source and binary forms, with or without 48 | modification, are permitted provided that the following conditions are 49 | met: 50 | 51 | * Redistributions of source code must retain the above copyright 52 | notice, this list of conditions and the following disclaimer. 53 | * Redistributions in binary form must reproduce the above 54 | copyright notice, this list of conditions and the following disclaimer 55 | in the documentation and/or other materials provided with the 56 | distribution. 57 | * Neither the name of Google Inc. nor the names of its 58 | contributors may be used to endorse or promote products derived from 59 | this software without specific prior written permission. 60 | 61 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 62 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 63 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 64 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 65 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 66 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 67 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 68 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 69 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 70 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 71 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 72 | - sources: v4@v4.25.10/README.md 73 | text: New BSD License (same as psutil) 74 | notices: [] 75 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/shirou/gopsutil/v4/common.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/shirou/gopsutil/v4/common 3 | version: v4.25.10 4 | type: go 5 | summary: 'SPDX-License-Identifier: BSD-3-Clause' 6 | homepage: https://pkg.go.dev/github.com/shirou/gopsutil/v4/common 7 | license: bsd-3-clause 8 | licenses: 9 | - sources: v4@v4.25.10/LICENSE 10 | text: |- 11 | gopsutil is distributed under BSD license reproduced below. 12 | 13 | Copyright (c) 2014, WAKAYAMA Shirou 14 | All rights reserved. 15 | 16 | Redistribution and use in source and binary forms, with or without modification, 17 | are permitted provided that the following conditions are met: 18 | 19 | * Redistributions of source code must retain the above copyright notice, this 20 | list of conditions and the following disclaimer. 21 | * Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation 23 | and/or other materials provided with the distribution. 24 | * Neither the name of the gopsutil authors nor the names of its contributors 25 | may be used to endorse or promote products derived from this software without 26 | specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 29 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 30 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 32 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 33 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 34 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 35 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 37 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | 39 | 40 | ------- 41 | internal/common/binary.go in the gopsutil is copied and modified from golang/encoding/binary.go. 42 | 43 | 44 | 45 | Copyright (c) 2009 The Go Authors. All rights reserved. 46 | 47 | Redistribution and use in source and binary forms, with or without 48 | modification, are permitted provided that the following conditions are 49 | met: 50 | 51 | * Redistributions of source code must retain the above copyright 52 | notice, this list of conditions and the following disclaimer. 53 | * Redistributions in binary form must reproduce the above 54 | copyright notice, this list of conditions and the following disclaimer 55 | in the documentation and/or other materials provided with the 56 | distribution. 57 | * Neither the name of Google Inc. nor the names of its 58 | contributors may be used to endorse or promote products derived from 59 | this software without specific prior written permission. 60 | 61 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 62 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 63 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 64 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 65 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 66 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 67 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 68 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 69 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 70 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 71 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 72 | - sources: v4@v4.25.10/README.md 73 | text: New BSD License (same as psutil) 74 | notices: [] 75 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/shirou/gopsutil/v4/internal/common.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/shirou/gopsutil/v4/internal/common 3 | version: v4.25.10 4 | type: go 5 | summary: 'SPDX-License-Identifier: BSD-3-Clause' 6 | homepage: https://pkg.go.dev/github.com/shirou/gopsutil/v4/internal/common 7 | license: bsd-3-clause 8 | licenses: 9 | - sources: v4@v4.25.10/LICENSE 10 | text: |- 11 | gopsutil is distributed under BSD license reproduced below. 12 | 13 | Copyright (c) 2014, WAKAYAMA Shirou 14 | All rights reserved. 15 | 16 | Redistribution and use in source and binary forms, with or without modification, 17 | are permitted provided that the following conditions are met: 18 | 19 | * Redistributions of source code must retain the above copyright notice, this 20 | list of conditions and the following disclaimer. 21 | * Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation 23 | and/or other materials provided with the distribution. 24 | * Neither the name of the gopsutil authors nor the names of its contributors 25 | may be used to endorse or promote products derived from this software without 26 | specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 29 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 30 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 32 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 33 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 34 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 35 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 37 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | 39 | 40 | ------- 41 | internal/common/binary.go in the gopsutil is copied and modified from golang/encoding/binary.go. 42 | 43 | 44 | 45 | Copyright (c) 2009 The Go Authors. All rights reserved. 46 | 47 | Redistribution and use in source and binary forms, with or without 48 | modification, are permitted provided that the following conditions are 49 | met: 50 | 51 | * Redistributions of source code must retain the above copyright 52 | notice, this list of conditions and the following disclaimer. 53 | * Redistributions in binary form must reproduce the above 54 | copyright notice, this list of conditions and the following disclaimer 55 | in the documentation and/or other materials provided with the 56 | distribution. 57 | * Neither the name of Google Inc. nor the names of its 58 | contributors may be used to endorse or promote products derived from 59 | this software without specific prior written permission. 60 | 61 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 62 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 63 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 64 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 65 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 66 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 67 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 68 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 69 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 70 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 71 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 72 | - sources: v4@v4.25.10/README.md 73 | text: New BSD License (same as psutil) 74 | notices: [] 75 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/arduino/arduino-flasher-cli 2 | 3 | go 1.25.1 4 | 5 | require ( 6 | github.com/arduino/go-paths-helper v1.14.0 7 | github.com/arduino/go-windows-runas v1.0.1 8 | github.com/codeclysm/extract/v4 v4.0.0 9 | github.com/fatih/color v1.18.0 10 | github.com/jedib0t/go-pretty/v6 v6.6.8 11 | github.com/leonelquinteros/gotext v1.7.2 12 | github.com/schollz/progressbar/v3 v3.18.0 13 | github.com/shirou/gopsutil/v4 v4.25.10 14 | github.com/spf13/cobra v1.9.1 15 | github.com/stretchr/testify v1.11.1 16 | go.bug.st/cleanup v1.0.0 17 | go.bug.st/f v0.4.0 18 | go.bug.st/relaxed-semver v0.15.0 19 | google.golang.org/grpc v1.77.0 20 | google.golang.org/protobuf v1.36.10 21 | ) 22 | 23 | require ( 24 | dario.cat/mergo v1.0.0 // indirect 25 | github.com/Ladicle/tabwriter v1.0.0 // indirect 26 | github.com/Masterminds/semver/v3 v3.4.0 // indirect 27 | github.com/Microsoft/go-winio v0.6.2 // indirect 28 | github.com/ProtonMail/go-crypto v1.1.6 // indirect 29 | github.com/alecthomas/chroma/v2 v2.19.0 // indirect 30 | github.com/chainguard-dev/git-urls v1.0.2 // indirect 31 | github.com/cloudflare/circl v1.6.1 // indirect 32 | github.com/cyphar/filepath-securejoin v0.4.1 // indirect 33 | github.com/davecgh/go-spew v1.1.1 // indirect 34 | github.com/dlclark/regexp2 v1.11.5 // indirect 35 | github.com/dominikbraun/graph v0.23.0 // indirect 36 | github.com/ebitengine/purego v0.9.0 // indirect 37 | github.com/elliotchance/orderedmap/v3 v3.1.0 // indirect 38 | github.com/emirpasic/gods v1.18.1 // indirect 39 | github.com/fsnotify/fsnotify v1.9.0 // indirect 40 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect 41 | github.com/go-git/go-billy/v5 v5.6.2 // indirect 42 | github.com/go-git/go-git/v5 v5.16.2 // indirect 43 | github.com/go-ole/go-ole v1.3.0 // indirect 44 | github.com/go-task/slim-sprig/v3 v3.0.0 // indirect 45 | github.com/go-task/task/v3 v3.44.1 // indirect 46 | github.com/go-task/template v0.2.0 // indirect 47 | github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect 48 | github.com/google/uuid v1.6.0 // indirect 49 | github.com/h2non/filetype v1.1.3 // indirect 50 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 51 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect 52 | github.com/joho/godotenv v1.5.1 // indirect 53 | github.com/juju/errors v1.0.0 // indirect 54 | github.com/kevinburke/ssh_config v1.2.0 // indirect 55 | github.com/klauspost/compress v1.18.0 // indirect 56 | github.com/klauspost/cpuid/v2 v2.2.7 // indirect 57 | github.com/mattn/go-colorable v0.1.13 // indirect 58 | github.com/mattn/go-isatty v0.0.20 // indirect 59 | github.com/mattn/go-runewidth v0.0.16 // indirect 60 | github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect 61 | github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect 62 | github.com/pjbgf/sha1cd v0.3.2 // indirect 63 | github.com/pmezard/go-difflib v1.0.0 // indirect 64 | github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect 65 | github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect 66 | github.com/rivo/uniseg v0.4.7 // indirect 67 | github.com/sajari/fuzzy v1.0.0 // indirect 68 | github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect 69 | github.com/skeema/knownhosts v1.3.1 // indirect 70 | github.com/spf13/pflag v1.0.7 // indirect 71 | github.com/stretchr/objx v0.5.2 // indirect 72 | github.com/ulikunitz/xz v0.5.12 // indirect 73 | github.com/xanzy/ssh-agent v0.3.3 // indirect 74 | github.com/yusufpapurcu/wmi v1.2.4 // indirect 75 | github.com/zeebo/xxh3 v1.0.2 // indirect 76 | golang.org/x/crypto v0.43.0 // indirect 77 | golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect 78 | golang.org/x/sync v0.17.0 // indirect 79 | golang.org/x/sys v0.37.0 // indirect 80 | golang.org/x/term v0.36.0 // indirect 81 | golang.org/x/text v0.30.0 // indirect 82 | google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect 83 | gopkg.in/warnings.v0 v0.1.2 // indirect 84 | gopkg.in/yaml.v3 v3.0.1 // indirect 85 | mvdan.cc/sh/v3 v3.12.0 // indirect 86 | ) 87 | 88 | tool github.com/go-task/task/v3/cmd/task 89 | -------------------------------------------------------------------------------- /cmd/feedback/stdio.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package feedback 17 | 18 | import ( 19 | "bytes" 20 | "errors" 21 | "io" 22 | 23 | "github.com/arduino/arduino-flasher-cli/cmd/i18n" 24 | ) 25 | 26 | // DirectStreams returns the underlying io.Writer to directly stream to 27 | // stdout and stderr. 28 | // If the selected output format is not Text, the function will error. 29 | // 30 | // Using the streams returned by this function allows direct control of 31 | // the output and the PrintResult function must not be used anymore 32 | func DirectStreams() (io.Writer, io.Writer, error) { 33 | if !formatSelected { 34 | panic("output format not yet selected") 35 | } 36 | if format != Text { 37 | return nil, nil, errors.New(i18n.Tr("available only in text format")) 38 | } 39 | return stdOut, stdErr, nil 40 | } 41 | 42 | // OutputStreams returns a pair of io.Writer to write the command output. 43 | // The returned writers will accumulate the output until the command 44 | // execution is completed, so they are not suitable for printing an unbounded 45 | // stream like a debug logger or an event watcher (use DirectStreams for 46 | // that purpose). 47 | // 48 | // If the output format is Text the output will be directly streamed to the 49 | // underlying stdio streams in real time. 50 | // 51 | // This function returns also a callback that must be called when the 52 | // command execution is completed, it will return an *OutputStreamsResult 53 | // object that can be used as a Result or to retrieve the accumulated output 54 | // to embed it in another object. 55 | func OutputStreams() (io.Writer, io.Writer, func() *OutputStreamsResult) { 56 | if !formatSelected { 57 | panic("output format not yet selected") 58 | } 59 | return feedbackOut, feedbackErr, getOutputStreamResult 60 | } 61 | 62 | // NewBufferedStreams returns a pair of io.Writer to buffer the command output. 63 | // The returned writers will accumulate the output until the command 64 | // execution is completed. The io.Writes will not affect other feedback streams. 65 | // 66 | // This function returns also a callback that must be called when the 67 | // command execution is completed, it will return an *OutputStreamsResult 68 | // object that can be used as a Result or to retrieve the accumulated output 69 | // to embed it in another object. 70 | func NewBufferedStreams() (io.Writer, io.Writer, func() *OutputStreamsResult) { 71 | out, err := bytes.NewBuffer(nil), bytes.NewBuffer(nil) 72 | return out, err, func() *OutputStreamsResult { 73 | return &OutputStreamsResult{ 74 | Stdout: out.String(), 75 | Stderr: err.String(), 76 | } 77 | } 78 | } 79 | 80 | func getOutputStreamResult() *OutputStreamsResult { 81 | return &OutputStreamsResult{ 82 | Stdout: bufferOut.String(), 83 | Stderr: bufferErr.String(), 84 | } 85 | } 86 | 87 | // OutputStreamsResult contains the accumulated stdout and stderr output 88 | // when the selected output format is not Text. 89 | type OutputStreamsResult struct { 90 | Stdout string `json:"stdout"` 91 | Stderr string `json:"stderr"` 92 | } 93 | 94 | // Data returns the result object itself, it is used to implement the Result interface. 95 | func (r *OutputStreamsResult) Data() interface{} { 96 | // In case of non-Text output format, the output is accumulated so return the buffer as a Result object 97 | return r 98 | } 99 | 100 | func (r *OutputStreamsResult) String() string { 101 | // In case of Text output format, the output is streamed to stdout and stderr directly, no need to print anything 102 | return "" 103 | } 104 | 105 | // Empty returns true if both Stdout and Stderr are empty. 106 | func (r *OutputStreamsResult) Empty() bool { 107 | return r.Stdout == "" && r.Stderr == "" 108 | } 109 | -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/daemon/daemon.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package daemon 17 | 18 | import ( 19 | "errors" 20 | "fmt" 21 | "net" 22 | "os" 23 | "strings" 24 | "syscall" 25 | 26 | "github.com/spf13/cobra" 27 | "google.golang.org/grpc" 28 | 29 | "github.com/arduino/arduino-flasher-cli/cmd/feedback" 30 | "github.com/arduino/arduino-flasher-cli/cmd/i18n" 31 | flasher "github.com/arduino/arduino-flasher-cli/rpc/cc/arduino/flasher/v1" 32 | ) 33 | 34 | func NewDaemonCommand(srv flasher.FlasherServer) *cobra.Command { 35 | var daemonPort string 36 | var maxGRPCRecvMsgSize int 37 | daemonCommand := &cobra.Command{ 38 | Use: "daemon", 39 | Short: i18n.Tr("Run the Arduino Flasher CLI as a gRPC daemon."), 40 | Example: " " + os.Args[0] + " daemon", 41 | Args: cobra.NoArgs, 42 | Run: func(cmd *cobra.Command, args []string) { 43 | runDaemonCommand(srv, daemonPort, maxGRPCRecvMsgSize) 44 | }, 45 | } 46 | 47 | daemonCommand.Flags().StringVar(&daemonPort, 48 | "port", "50052", 49 | i18n.Tr("The TCP port the daemon will listen to")) 50 | 51 | daemonCommand.Flags().IntVar(&maxGRPCRecvMsgSize, 52 | "max-grpc-recv-message-size", 16*1024*1024, 53 | i18n.Tr("Sets the maximum message size in bytes the daemon can receive")) 54 | 55 | return daemonCommand 56 | } 57 | 58 | func runDaemonCommand(srv flasher.FlasherServer, daemonPort string, maxGRPCRecvMsgSize int) { 59 | gRPCOptions := []grpc.ServerOption{} 60 | gRPCOptions = append(gRPCOptions, grpc.MaxRecvMsgSize(maxGRPCRecvMsgSize)) 61 | s := grpc.NewServer(gRPCOptions...) 62 | 63 | // register the commands service 64 | flasher.RegisterFlasherServer(s, srv) 65 | 66 | daemonIP := "127.0.0.1" 67 | lis, err := net.Listen("tcp", fmt.Sprintf("%s:%s", daemonIP, daemonPort)) 68 | if err != nil { 69 | // Invalid port, such as "Foo" 70 | var dnsError *net.DNSError 71 | if errors.As(err, &dnsError) { 72 | feedback.Fatal(i18n.Tr("Failed to listen on TCP port: %[1]s. %[2]s is unknown name.", daemonPort, dnsError.Name), feedback.ErrBadTCPPortArgument) 73 | } 74 | // Invalid port number, such as -1 75 | var addrError *net.AddrError 76 | if errors.As(err, &addrError) { 77 | feedback.Fatal(i18n.Tr("Failed to listen on TCP port: %[1]s. %[2]s is an invalid port.", daemonPort, addrError.Addr), feedback.ErrBadTCPPortArgument) 78 | } 79 | // Port is already in use 80 | var syscallErr *os.SyscallError 81 | if errors.As(err, &syscallErr) && errors.Is(syscallErr.Err, syscall.EADDRINUSE) { 82 | feedback.Fatal(i18n.Tr("Failed to listen on TCP port: %s. Address already in use.", daemonPort), feedback.ErrFailedToListenToTCPPort) 83 | } 84 | feedback.Fatal(i18n.Tr("Failed to listen on TCP port: %[1]s. Unexpected error: %[2]v", daemonPort, err), feedback.ErrFailedToListenToTCPPort) 85 | } 86 | 87 | // We need to retrieve the port used only if the user did not specify it 88 | // and let the OS choose it randomly, in all other cases we already know 89 | // which port is used. 90 | if daemonPort == "0" { 91 | address := lis.Addr() 92 | split := strings.Split(address.String(), ":") 93 | 94 | if len(split) <= 1 { 95 | feedback.Fatal(i18n.Tr("Invalid TCP address: port is missing"), feedback.ErrBadTCPPortArgument) 96 | } 97 | 98 | daemonPort = split[1] 99 | } 100 | 101 | feedback.PrintResult(daemonResult{ 102 | IP: daemonIP, 103 | Port: daemonPort, 104 | }) 105 | 106 | if err := s.Serve(lis); err != nil { 107 | feedback.Fatal(fmt.Sprintf("Failed to serve: %v", err), feedback.ErrFailedToListenToTCPPort) 108 | } 109 | } 110 | 111 | type daemonResult struct { 112 | IP string 113 | Port string 114 | } 115 | 116 | func (r daemonResult) Data() interface{} { 117 | return r 118 | } 119 | 120 | func (r daemonResult) String() string { 121 | return fmt.Sprintln(i18n.Tr("Daemon is now listening on %s:%s", r.IP, r.Port)) 122 | } 123 | -------------------------------------------------------------------------------- /internal/updater/http_client.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package updater 17 | 18 | import ( 19 | "context" 20 | "crypto/sha256" 21 | "encoding/hex" 22 | "encoding/json" 23 | "fmt" 24 | "io" 25 | "net/http" 26 | "net/url" 27 | 28 | "go.bug.st/f" 29 | ) 30 | 31 | var baseURL = f.Must(url.Parse("https://downloads.arduino.cc")) 32 | 33 | const pathRelease = "debian-im/Stable" 34 | 35 | // Client holds the base URL, command name, allows custom HTTP client, and optional headers. 36 | type Client struct { 37 | HTTPClient HTTPDoer 38 | Headers map[string]string // Optional headers to add to each request 39 | } 40 | 41 | // HTTPDoer is an interface for http.Client or mocks. 42 | type HTTPDoer interface { 43 | Do(req *http.Request) (*http.Response, error) 44 | } 45 | 46 | // Option is a functional option for configuring Client. 47 | type Option func(*Client) 48 | 49 | // WithHeaders sets custom headers for the Client. 50 | func WithHeaders(headers map[string]string) Option { 51 | return func(c *Client) { 52 | c.Headers = headers 53 | } 54 | } 55 | 56 | // WithHTTPClient sets a custom HTTP client for the Client. 57 | func WithHTTPClient(client HTTPDoer) Option { 58 | return func(c *Client) { 59 | c.HTTPClient = client 60 | } 61 | } 62 | 63 | // NewClient creates a new Client with optional configuration. 64 | func NewClient(opts ...Option) *Client { 65 | c := &Client{ 66 | HTTPClient: http.DefaultClient, 67 | Headers: nil, 68 | } 69 | for _, opt := range opts { 70 | opt(c) 71 | } 72 | return c 73 | } 74 | 75 | // addHeaders adds custom headers to the request if present. 76 | func (c *Client) addHeaders(req *http.Request) { 77 | for k, v := range c.Headers { 78 | req.Header.Set(k, v) 79 | } 80 | } 81 | 82 | // GetInfoManifest fetches and decodes the Debian images info.json. 83 | func (c *Client) GetInfoManifest(ctx context.Context) (Manifest, error) { 84 | manifestURL := baseURL.JoinPath(pathRelease, "info.json").String() 85 | req, err := http.NewRequestWithContext(ctx, "GET", manifestURL, nil) 86 | if err != nil { 87 | return Manifest{}, fmt.Errorf("failed to create request: %w", err) 88 | } 89 | c.addHeaders(req) 90 | // #nosec G107 -- manifestURL is constructed from trusted config and parameters 91 | resp, err := c.HTTPClient.Do(req) 92 | if err != nil { 93 | return Manifest{}, fmt.Errorf("failed to GET manifest: %w", err) 94 | } 95 | defer resp.Body.Close() 96 | if resp.StatusCode != http.StatusOK { 97 | return Manifest{}, fmt.Errorf("bad http status from %s: %v", manifestURL, resp.Status) 98 | } 99 | 100 | var res Manifest 101 | if err := json.NewDecoder(resp.Body).Decode(&res); err != nil { 102 | return Manifest{}, fmt.Errorf("invalid manifest JSON: %w", err) 103 | } 104 | if sha256Byte, err := hex.DecodeString(res.Latest.Sha256); err != nil { 105 | return Manifest{}, fmt.Errorf("could not convert sha256 from hex to bytes: %w", err) 106 | } else if len(sha256Byte) != sha256.Size { 107 | return Manifest{}, fmt.Errorf("bad sha256sum in manifest: got %d bytes", len(sha256Byte)) 108 | } 109 | return res, nil 110 | } 111 | 112 | // FetchZip fetches the Debian image archive. 113 | func (c *Client) FetchZip(ctx context.Context, zipURL string) (io.ReadCloser, int64, error) { 114 | req, err := http.NewRequestWithContext(ctx, "GET", zipURL, nil) 115 | if err != nil { 116 | return nil, 0, fmt.Errorf("failed to create request: %w", err) 117 | } 118 | c.addHeaders(req) 119 | // #nosec G107 -- zipURL is constructed from trusted config and parameters 120 | resp, err := c.HTTPClient.Do(req) 121 | if err != nil { 122 | return nil, 0, fmt.Errorf("failed to GET zip: %w", err) 123 | } 124 | if resp.StatusCode != http.StatusOK { 125 | resp.Body.Close() 126 | return nil, 0, fmt.Errorf("bad http status from %s: %v", zipURL, resp.Status) 127 | } 128 | return resp.Body, resp.ContentLength, nil 129 | } 130 | -------------------------------------------------------------------------------- /cmd/arduino-flasher-cli/flash/flash.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package flash 17 | 18 | import ( 19 | "context" 20 | "fmt" 21 | "os" 22 | "runtime" 23 | "strings" 24 | 25 | "github.com/arduino/go-paths-helper" 26 | runas "github.com/arduino/go-windows-runas" 27 | "github.com/fatih/color" 28 | "github.com/spf13/cobra" 29 | 30 | "github.com/arduino/arduino-flasher-cli/cmd/feedback" 31 | "github.com/arduino/arduino-flasher-cli/cmd/i18n" 32 | "github.com/arduino/arduino-flasher-cli/internal/updater" 33 | ) 34 | 35 | func NewFlashCmd() *cobra.Command { 36 | var forceYes, preserveUser bool 37 | var tempDir string 38 | appCmd := &cobra.Command{ 39 | Use: "flash", 40 | Short: "Flash a Debian image on the board", 41 | Long: `Flash a Debian image on the board. 42 | 43 | WARNING: This operation will completely replace the current system on the board. 44 | Make sure to backup any important data before proceeding. 45 | 46 | This command accepts either: 47 | - A local file path to a compressed Debian image file (e.g., .tar.zst, .tar.xz) or a decompressed Debian image folder 48 | - A version tag to download from the remote repository 49 | 50 | When providing a local file path: 51 | - The path can be relative or absolute 52 | - The file is extracted in a temp folder (if needed) 53 | - The image is flashed into the board 54 | 55 | When providing a version tag: 56 | - Use 'latest' to download the most recent stable image 57 | - Use a specific version tag (e.g., '20250915-173') to download that exact version 58 | - The image will be automatically downloaded (in a temp folder), the sha is verified, and flashed 59 | 60 | 61 | NOTE: On Windows, required drivers are automatically installed with elevated privileges. 62 | `, 63 | Example: " " + os.Args[0] + " flash latest\n" + 64 | " " + os.Args[0] + " flash 20250915-173\n" + 65 | " " + os.Args[0] + " flash ./my-image.tar.zst\n" + 66 | " " + os.Args[0] + " flash /path/to/debian-image.tar.zst\n" + 67 | " " + os.Args[0] + " flash /path/to/debian-image.tar.xz \n" + 68 | " " + os.Args[0] + " flash /path/to/arduino-unoq-debian-image-20250915-173 \n" + 69 | " " + os.Args[0] + " flash latest --temp-dir /path/to/custom/tempDir \n", 70 | 71 | Args: cobra.ExactArgs(1), 72 | Run: func(cmd *cobra.Command, args []string) { 73 | checkDriversInstalled() 74 | runFlashCommand(cmd.Context(), args, forceYes, preserveUser, tempDir) 75 | }, 76 | } 77 | appCmd.Flags().BoolVarP(&forceYes, "yes", "y", false, "Automatically confirm all prompts") 78 | appCmd.Flags().StringVar(&tempDir, "temp-dir", "", "Path to the directory in which the image will be downloaded and extracted") 79 | appCmd.Flags().BoolVar(&preserveUser, "preserve-user", false, "Preserve user partition") 80 | 81 | return appCmd 82 | } 83 | 84 | func checkDriversInstalled() { 85 | if runtime.GOOS != "windows" { 86 | return 87 | } 88 | cmd, _ := os.Executable() 89 | pwd, _ := os.Getwd() 90 | if _, err := runas.RunElevated(cmd, pwd, []string{"install-drivers"}, true); err != nil { 91 | feedback.Fatal(i18n.Tr("error installing drivers: %v", err), feedback.ErrGeneric) 92 | } 93 | } 94 | 95 | func runFlashCommand(ctx context.Context, args []string, forceYes bool, preserveUser bool, tempDir string) { 96 | imagePath, err := paths.New(args[0]).Abs() 97 | if err != nil { 98 | feedback.Fatal(i18n.Tr("could not find image absolute path: %v", err), feedback.ErrBadArgument) 99 | } 100 | 101 | if !forceYes && !preserveUser { 102 | feedback.Print(color.RedString("\nWARNING: flashing a new Linux image will erase any existing data that you have on the board.\n")) 103 | feedback.Printf("Do you want to proceed and flash %s on the board? (yes/no)", args[0]) 104 | 105 | var yesInput string 106 | _, err := fmt.Scanf("%s\n", &yesInput) 107 | if err != nil { 108 | feedback.Fatal(err.Error(), feedback.ErrBadArgument) 109 | } 110 | yes := strings.ToLower(yesInput) == "yes" || strings.ToLower(yesInput) == "y" 111 | 112 | if !yes { 113 | return 114 | } 115 | } 116 | 117 | err = updater.Flash(ctx, imagePath, args[0], forceYes, preserveUser, tempDir) 118 | if err != nil { 119 | feedback.Fatal(i18n.Tr("error flashing the board: %v", err), feedback.ErrBadArgument) 120 | } 121 | feedback.Print("\nThe board has been successfully flashed. You can now power-cycle the board (unplug and re-plug). Remember to remove the jumper.") 122 | } 123 | -------------------------------------------------------------------------------- /Taskfile.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | vars: 4 | GOLANGCI_LINT_VERSION: v2.5.0 5 | GOIMPORTS_VERSION: v0.38.0 6 | DPRINT_VERSION: 0.50.2 7 | VERSION: # if version is not passed we hack the semver by encoding the commit as pre-release 8 | sh: echo "${VERSION:-0.0.0-$(git rev-parse --short HEAD)}" 9 | 10 | tasks: 11 | init: 12 | desc: Setup local env 13 | deps: 14 | - install:linter 15 | - install:goimports 16 | - install:dprint 17 | 18 | install:linter: 19 | cmds: 20 | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b .bin/ {{ .GOLANGCI_LINT_VERSION }} 21 | 22 | install:goimports: 23 | cmds: 24 | - go install golang.org/x/tools/cmd/goimports@{{ .GOIMPORTS_VERSION }} 25 | 26 | install:dprint: 27 | cmds: 28 | - curl -fsSL https://dprint.dev/install.sh | sh -s {{ .DPRINT_VERSION }} 29 | - mkdir -p .bin && cp $HOME/.dprint/bin/dprint .bin/dprint # workaround for local install 30 | 31 | test: 32 | desc: Run all go tests 33 | deps: 34 | - build:artifacts 35 | cmds: 36 | - go test ./... -v -race {{ .CLI_ARGS }} 37 | 38 | test:cover: 39 | desc: Run all tests and open cover html report 40 | cmds: 41 | - task test -- -coverprofile=coverage.out 42 | - go tool cover -func=coverage.out 43 | - go tool cover -html=coverage.out 44 | 45 | lint: 46 | desc: Run the linters 47 | cmds: 48 | - ${PWD}/.bin/golangci-lint run --fix -v --timeout 300s {{ .CLI_ARGS }} 49 | 50 | fmt: 51 | desc: Run format 52 | cmds: 53 | - goimports -l -w . 54 | - ${PWD}/.bin/dprint fmt 55 | 56 | fmt-check: 57 | desc: Check format 58 | cmds: 59 | - ${PWD}/.bin/dprint check 60 | 61 | build: 62 | deps: 63 | - build:artifacts 64 | desc: "Build the arduino-flasher-cli locally" 65 | vars: 66 | VERSION: "{{.VERSION }}" 67 | cmds: 68 | - cmd: go build -ldflags "-X main.Version={{.VERSION}}" -v -o ./build/arduino-flasher-cli ./cmd/arduino-flasher-cli/ 69 | platforms: [linux, darwin] 70 | - cmd: go build -ldflags "-X main.Version={{.VERSION}}" -v -o ./build/arduino-flasher-cli.exe ./cmd/arduino-flasher-cli/ 71 | platforms: [windows] 72 | 73 | build:artifacts: 74 | desc: Prepare the arduino-flasher-cli artifacts 75 | internal: true 76 | status: 77 | - test -f ./internal/updater/artifacts/resources_darwin_amd64/qdl 78 | - test -f ./internal/updater/artifacts/resources_darwin_arm64/qdl 79 | - test -f ./internal/updater/artifacts/resources_linux_amd64/qdl 80 | - test -f ./internal/updater/artifacts/resources_linux_arm64/qdl 81 | - test -f ./internal/updater/artifacts/resources_windows_amd64/qdl.exe 82 | cmd: sh ./internal/updater/artifacts/download_resources.sh 83 | 84 | release: 85 | desc: Create a tag on the current commit and push it to the remote to create the release 86 | cmds: 87 | - | 88 | if [ -z "{{.CLI_ARGS}}" ]; then 89 | echo "Error: Version argument is required. Usage: task release -- " 90 | exit 1 91 | fi 92 | - git tag -a "{{.CLI_ARGS}}" -m "Release {{.CLI_ARGS}}" 93 | - git push origin "{{.CLI_ARGS}}" 94 | 95 | # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-dependencies-task/Taskfile.yml 96 | general:cache-dep-licenses: 97 | desc: Cache dependency license metadata 98 | deps: 99 | - task: general:prepare-deps 100 | cmds: 101 | - | 102 | if 103 | ! which licensed \ 104 | &>/dev/null 105 | then 106 | if [[ {{OS}} == "windows" ]]; then 107 | echo "Licensed does not have Windows support." 108 | echo "Please use Linux/macOS or download the dependencies cache from the GitHub Actions workflow artifact." 109 | else 110 | echo "licensed not found or not in PATH." 111 | echo "Please install: https://github.com/licensee/licensed#installation" 112 | fi 113 | exit 1 114 | fi 115 | - licensed cache 116 | 117 | # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-dependencies-task/Taskfile.yml 118 | general:check-dep-licenses: 119 | desc: Check for unapproved dependency licenses 120 | deps: 121 | - task: general:cache-dep-licenses 122 | cmds: 123 | - licensed status 124 | 125 | # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-go-dependencies-task/Taskfile.yml 126 | general:prepare-deps: 127 | desc: Prepare project dependencies for license check 128 | # No preparation is needed for Go module-based projects. 129 | 130 | protoc:compile: 131 | desc: Compile protobuf definitions 132 | cmds: 133 | - buf dep update 134 | - buf generate 135 | 136 | protoc:check: 137 | desc: Perform linting of the protobuf definitions 138 | cmds: 139 | - buf lint 140 | 141 | protoc:format: 142 | desc: Perform formatting of the protobuf definitions 143 | cmds: 144 | - buf format --write 145 | -------------------------------------------------------------------------------- /.github/workflows/check-go-dependencies-task.yml: -------------------------------------------------------------------------------- 1 | # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-go-dependencies-task.md 2 | name: Check Go Dependencies 3 | 4 | # See: https://docs.github.com/actions/reference/workflows-and-actions/events-that-trigger-workflows 5 | on: 6 | create: 7 | push: 8 | paths: 9 | - ".github/workflows/check-go-dependencies-task.ya?ml" 10 | - ".licenses/**" 11 | - ".licensed.json" 12 | - ".licensed.ya?ml" 13 | - "Taskfile.ya?ml" 14 | - "**/.gitmodules" 15 | - "**/go.mod" 16 | - "**/go.sum" 17 | pull_request: 18 | paths: 19 | - ".github/workflows/check-go-dependencies-task.ya?ml" 20 | - ".licenses/**" 21 | - ".licensed.json" 22 | - ".licensed.ya?ml" 23 | - "Taskfile.ya?ml" 24 | - "**/.gitmodules" 25 | - "**/go.mod" 26 | - "**/go.sum" 27 | schedule: 28 | # Run periodically to catch breakage caused by external changes. 29 | - cron: "0 8 * * WED" 30 | workflow_dispatch: 31 | repository_dispatch: 32 | 33 | jobs: 34 | run-determination: 35 | runs-on: ubuntu-latest 36 | permissions: {} 37 | outputs: 38 | result: ${{ steps.determination.outputs.result }} 39 | steps: 40 | - name: Determine if the rest of the workflow should run 41 | id: determination 42 | run: | 43 | RELEASE_BRANCH_REGEX="refs/heads/[0-9]+.[0-9]+.x" 44 | # The `create` event trigger doesn't support `branches` filters, so it's necessary to use Bash instead. 45 | if [[ 46 | "${{ github.event_name }}" != "create" || 47 | "${{ github.ref }}" =~ $RELEASE_BRANCH_REGEX 48 | ]]; then 49 | # Run the other jobs. 50 | RESULT="true" 51 | else 52 | # There is no need to run the other jobs. 53 | RESULT="false" 54 | fi 55 | 56 | echo "result=$RESULT" >>$GITHUB_OUTPUT 57 | 58 | check-cache: 59 | needs: run-determination 60 | if: needs.run-determination.outputs.result == 'true' 61 | runs-on: ubuntu-latest 62 | permissions: 63 | contents: read 64 | 65 | steps: 66 | - name: Checkout repository 67 | uses: actions/checkout@v5 68 | with: 69 | submodules: recursive 70 | 71 | # This is required to allow licensee/setup-licensed to install Licensed via Ruby gem. 72 | - name: Install Ruby 73 | uses: ruby/setup-ruby@v1 74 | with: 75 | ruby-version: ruby # Install latest version 76 | 77 | - name: Install licensed 78 | uses: licensee/setup-licensed@v1.3.2 79 | with: 80 | github_token: ${{ secrets.GITHUB_TOKEN }} 81 | version: 5.x 82 | 83 | - name: Install Go 84 | uses: actions/setup-go@v6 85 | with: 86 | go-version-file: go.mod 87 | 88 | - name: Update dependencies license metadata cache 89 | run: | 90 | go tool \ 91 | github.com/go-task/task/v3/cmd/task \ 92 | --silent \ 93 | general:cache-dep-licenses 94 | 95 | - name: Check for outdated cache 96 | id: diff 97 | run: | 98 | git add . 99 | if 100 | ! git diff \ 101 | --cached \ 102 | --color \ 103 | --exit-code 104 | then 105 | echo 106 | echo "::error::Dependency license metadata out of sync. See: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-go-dependencies-task.md#metadata-cache" 107 | exit 1 108 | fi 109 | 110 | # Some might find it convenient to have CI generate the cache rather than setting up for it locally 111 | - name: Upload cache to workflow artifact 112 | if: failure() && steps.diff.outcome == 'failure' 113 | uses: actions/upload-artifact@v4 114 | with: 115 | if-no-files-found: error 116 | include-hidden-files: true 117 | name: dep-licenses-cache 118 | path: .licenses/ 119 | 120 | check-deps: 121 | needs: run-determination 122 | if: needs.run-determination.outputs.result == 'true' 123 | runs-on: ubuntu-latest 124 | permissions: 125 | contents: read 126 | 127 | steps: 128 | - name: Checkout repository 129 | uses: actions/checkout@v5 130 | with: 131 | submodules: recursive 132 | 133 | # This is required to allow licensee/setup-licensed to install Licensed via Ruby gem. 134 | - name: Install Ruby 135 | uses: ruby/setup-ruby@v1 136 | with: 137 | ruby-version: ruby # Install latest version 138 | 139 | - name: Install licensed 140 | uses: licensee/setup-licensed@v1.3.2 141 | with: 142 | github_token: ${{ secrets.GITHUB_TOKEN }} 143 | version: 5.x 144 | 145 | - name: Install Go 146 | uses: actions/setup-go@v6 147 | with: 148 | go-version-file: go.mod 149 | 150 | - name: Check for dependencies with unapproved licenses 151 | run: | 152 | go tool \ 153 | github.com/go-task/task/v3/cmd/task \ 154 | --silent \ 155 | general:check-dep-licenses 156 | -------------------------------------------------------------------------------- /rpc/cc/arduino/flasher/v1/commands_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 17 | // versions: 18 | // - protoc-gen-go-grpc v1.5.1 19 | // - protoc (unknown) 20 | // source: cc/arduino/flasher/v1/commands.proto 21 | 22 | package flasher 23 | 24 | import ( 25 | context "context" 26 | 27 | grpc "google.golang.org/grpc" 28 | codes "google.golang.org/grpc/codes" 29 | status "google.golang.org/grpc/status" 30 | ) 31 | 32 | // This is a compile-time assertion to ensure that this generated file 33 | // is compatible with the grpc package it is being compiled against. 34 | // Requires gRPC-Go v1.64.0 or later. 35 | const _ = grpc.SupportPackageIsVersion9 36 | 37 | const ( 38 | Flasher_List_FullMethodName = "/cc.arduino.flasher.v1.Flasher/List" 39 | ) 40 | 41 | // FlasherClient is the client API for Flasher service. 42 | // 43 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 44 | type FlasherClient interface { 45 | List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) 46 | } 47 | 48 | type flasherClient struct { 49 | cc grpc.ClientConnInterface 50 | } 51 | 52 | func NewFlasherClient(cc grpc.ClientConnInterface) FlasherClient { 53 | return &flasherClient{cc} 54 | } 55 | 56 | func (c *flasherClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) { 57 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 58 | out := new(ListResponse) 59 | err := c.cc.Invoke(ctx, Flasher_List_FullMethodName, in, out, cOpts...) 60 | if err != nil { 61 | return nil, err 62 | } 63 | return out, nil 64 | } 65 | 66 | // FlasherServer is the server API for Flasher service. 67 | // All implementations must embed UnimplementedFlasherServer 68 | // for forward compatibility. 69 | type FlasherServer interface { 70 | List(context.Context, *ListRequest) (*ListResponse, error) 71 | mustEmbedUnimplementedFlasherServer() 72 | } 73 | 74 | // UnimplementedFlasherServer must be embedded to have 75 | // forward compatible implementations. 76 | // 77 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 78 | // pointer dereference when methods are called. 79 | type UnimplementedFlasherServer struct{} 80 | 81 | func (UnimplementedFlasherServer) List(context.Context, *ListRequest) (*ListResponse, error) { 82 | return nil, status.Errorf(codes.Unimplemented, "method List not implemented") 83 | } 84 | func (UnimplementedFlasherServer) mustEmbedUnimplementedFlasherServer() {} 85 | func (UnimplementedFlasherServer) testEmbeddedByValue() {} 86 | 87 | // UnsafeFlasherServer may be embedded to opt out of forward compatibility for this service. 88 | // Use of this interface is not recommended, as added methods to FlasherServer will 89 | // result in compilation errors. 90 | type UnsafeFlasherServer interface { 91 | mustEmbedUnimplementedFlasherServer() 92 | } 93 | 94 | func RegisterFlasherServer(s grpc.ServiceRegistrar, srv FlasherServer) { 95 | // If the following call pancis, it indicates UnimplementedFlasherServer was 96 | // embedded by pointer and is nil. This will cause panics if an 97 | // unimplemented method is ever invoked, so we test this at initialization 98 | // time to prevent it from happening at runtime later due to I/O. 99 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 100 | t.testEmbeddedByValue() 101 | } 102 | s.RegisterService(&Flasher_ServiceDesc, srv) 103 | } 104 | 105 | func _Flasher_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 106 | in := new(ListRequest) 107 | if err := dec(in); err != nil { 108 | return nil, err 109 | } 110 | if interceptor == nil { 111 | return srv.(FlasherServer).List(ctx, in) 112 | } 113 | info := &grpc.UnaryServerInfo{ 114 | Server: srv, 115 | FullMethod: Flasher_List_FullMethodName, 116 | } 117 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 118 | return srv.(FlasherServer).List(ctx, req.(*ListRequest)) 119 | } 120 | return interceptor(ctx, in, info, handler) 121 | } 122 | 123 | // Flasher_ServiceDesc is the grpc.ServiceDesc for Flasher service. 124 | // It's only intended for direct use with grpc.RegisterService, 125 | // and not to be introspected or modified (even as a copy) 126 | var Flasher_ServiceDesc = grpc.ServiceDesc{ 127 | ServiceName: "cc.arduino.flasher.v1.Flasher", 128 | HandlerType: (*FlasherServer)(nil), 129 | Methods: []grpc.MethodDesc{ 130 | { 131 | MethodName: "List", 132 | Handler: _Flasher_List_Handler, 133 | }, 134 | }, 135 | Streams: []grpc.StreamDesc{}, 136 | Metadata: "cc/arduino/flasher/v1/commands.proto", 137 | } 138 | -------------------------------------------------------------------------------- /internal/updater/download_image.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package updater 17 | 18 | import ( 19 | "bytes" 20 | "context" 21 | "crypto/sha256" 22 | "encoding/hex" 23 | "fmt" 24 | "io" 25 | "os" 26 | 27 | "github.com/arduino/go-paths-helper" 28 | "github.com/codeclysm/extract/v4" 29 | "github.com/schollz/progressbar/v3" 30 | 31 | "github.com/arduino/arduino-flasher-cli/cmd/feedback" 32 | "github.com/arduino/arduino-flasher-cli/cmd/i18n" 33 | ) 34 | 35 | type Manifest struct { 36 | Latest Release `json:"latest"` 37 | Releases []Release `json:"releases"` 38 | } 39 | 40 | type Release struct { 41 | Version string `json:"version"` 42 | Url string `json:"url"` 43 | Sha256 string `json:"sha256"` 44 | } 45 | 46 | // DownloadConfirmCB is a function that is called when a Debian image is ready to be downloaded. 47 | type DownloadConfirmCB func(target string) (bool, error) 48 | 49 | func DownloadAndExtract(ctx context.Context, targetVersion string, temp *paths.Path) (*paths.Path, string, error) { 50 | tmpZip, version, err := DownloadImage(ctx, targetVersion, temp) 51 | if err != nil { 52 | return nil, "", fmt.Errorf("error downloading the image: %v", err) 53 | } 54 | 55 | err = ExtractImage(ctx, tmpZip, tmpZip.Parent()) 56 | if err != nil { 57 | return nil, "", fmt.Errorf("error extracting the image: %v", err) 58 | } 59 | 60 | imagePath := tmpZip.Parent().Join("arduino-unoq-debian-image-" + version) 61 | if targetVersion == "latest" { 62 | version += "(latest)" 63 | } 64 | return imagePath, version, nil 65 | } 66 | 67 | func DownloadImage(ctx context.Context, targetVersion string, downloadPath *paths.Path) (*paths.Path, string, error) { 68 | var err error 69 | 70 | client := NewClient() 71 | manifest, err := client.GetInfoManifest(ctx) 72 | if err != nil { 73 | return nil, "", err 74 | } 75 | 76 | var rel *Release 77 | if targetVersion == "latest" || targetVersion == manifest.Latest.Version { 78 | rel = &manifest.Latest 79 | } else { 80 | for _, r := range manifest.Releases { 81 | if targetVersion == r.Version { 82 | rel = &r 83 | break 84 | } 85 | } 86 | } 87 | 88 | if rel == nil { 89 | return nil, "", fmt.Errorf("could not find Debian image %s", targetVersion) 90 | } 91 | 92 | download, size, err := client.FetchZip(ctx, rel.Url) 93 | if err != nil { 94 | return nil, "", fmt.Errorf("could not fetch Debian image: %w", err) 95 | } 96 | defer download.Close() 97 | 98 | tmpZip := downloadPath.Join("arduino-unoq-debian-image-" + rel.Version + ".tar.zst") 99 | tmpZipFile, err := tmpZip.Create() 100 | if err != nil { 101 | return nil, "", err 102 | } 103 | defer tmpZipFile.Close() 104 | 105 | // Download and keep track of the progress 106 | bar := progressbar.DefaultBytes( 107 | size, 108 | i18n.Tr("Downloading Debian image version %s", rel.Version), 109 | ) 110 | checksum := sha256.New() 111 | if _, err := io.Copy(io.MultiWriter(checksum, tmpZipFile, bar), download); err != nil { 112 | return nil, "", err 113 | } 114 | 115 | // Check the hash 116 | if sha256Byte, err := hex.DecodeString(rel.Sha256); err != nil { 117 | return nil, "", fmt.Errorf("could not convert sha256 from hex to bytes: %w", err) 118 | } else if s := checksum.Sum(nil); !bytes.Equal(s, sha256Byte) { 119 | return nil, "", fmt.Errorf("bad hash: %x (expected %x)", s, sha256Byte) 120 | } 121 | 122 | return tmpZip, rel.Version, nil 123 | } 124 | 125 | func ExtractImage(ctx context.Context, archive, temp *paths.Path) error { 126 | // Unzip the Debian image 127 | feedback.Print(i18n.Tr("Unzipping Debian image")) 128 | tmpZipFile, err := archive.Open() 129 | if err != nil { 130 | return fmt.Errorf("could not open archive: %w", err) 131 | } 132 | defer tmpZipFile.Close() 133 | 134 | if err := extract.Archive(ctx, tmpZipFile, temp.String(), func(s string) string { 135 | feedback.Print(s) 136 | return s 137 | }); err != nil { 138 | return fmt.Errorf("could not extract archive: %w", err) 139 | } 140 | return nil 141 | } 142 | 143 | // SetTempDir returns a temporary directory inside the user's cache directory (default). 144 | // The tempDir parameter is used to change the download/extraction directory. 145 | // The caller is responsible for removing the directory when no longer needed. 146 | func SetTempDir(prefix string, tempDir string) (*paths.Path, error) { 147 | cacheDir := paths.New(tempDir) 148 | 149 | if cacheDir == nil { 150 | userCacheDir, err := os.UserCacheDir() 151 | if err != nil { 152 | return nil, fmt.Errorf("could not get user's cache directory: %w", err) 153 | } 154 | 155 | cacheDir = paths.New(userCacheDir, "arduino-flasher-cli") 156 | _ = cacheDir.MkdirAll() 157 | } 158 | 159 | temp, err := paths.MkTempDir(cacheDir.String(), prefix) 160 | if err != nil { 161 | return nil, fmt.Errorf("could not create .cache directory: %w", err) 162 | } 163 | 164 | return temp, nil 165 | } 166 | -------------------------------------------------------------------------------- /cmd/feedback/feedback.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package feedback 17 | 18 | import ( 19 | "bytes" 20 | "encoding/json" 21 | "fmt" 22 | "io" 23 | "os" 24 | 25 | "github.com/arduino/arduino-flasher-cli/cmd/i18n" 26 | ) 27 | 28 | // OutputFormat is an output format 29 | type OutputFormat int 30 | 31 | const ( 32 | // Text is the plain text format, suitable for interactive terminals 33 | Text OutputFormat = iota 34 | // JSON format 35 | JSON 36 | // MinifiedJSON format 37 | MinifiedJSON 38 | ) 39 | 40 | var formats = map[string]OutputFormat{ 41 | "json": JSON, 42 | "jsonmini": MinifiedJSON, 43 | "text": Text, 44 | } 45 | 46 | func (f OutputFormat) String() string { 47 | for res, format := range formats { 48 | if format == f { 49 | return res 50 | } 51 | } 52 | panic("unknown output format") 53 | } 54 | 55 | // ParseOutputFormat parses a string and returns the corresponding OutputFormat. 56 | // The boolean returned is true if the string was a valid OutputFormat. 57 | func ParseOutputFormat(in string) (OutputFormat, bool) { 58 | format, found := formats[in] 59 | return format, found 60 | } 61 | 62 | var ( 63 | stdOut io.Writer 64 | stdErr io.Writer 65 | feedbackOut io.Writer 66 | feedbackErr io.Writer 67 | bufferOut *bytes.Buffer 68 | bufferErr *bytes.Buffer 69 | bufferWarnings []string 70 | format OutputFormat 71 | formatSelected bool 72 | ) 73 | 74 | // nolint:gochecknoinits 75 | func init() { 76 | reset() 77 | } 78 | 79 | // reset resets the feedback package to its initial state, useful for unit testing 80 | func reset() { 81 | stdOut = os.Stdout 82 | stdErr = os.Stderr 83 | feedbackOut = os.Stdout 84 | feedbackErr = os.Stderr 85 | bufferOut = bytes.NewBuffer(nil) 86 | bufferErr = bytes.NewBuffer(nil) 87 | bufferWarnings = nil 88 | format = Text 89 | formatSelected = false 90 | } 91 | 92 | // Result is anything more complex than a sentence that needs to be printed 93 | // for the user. 94 | type Result interface { 95 | fmt.Stringer 96 | Data() interface{} 97 | } 98 | 99 | // ErrorResult is a result embedding also an error. In case of textual output 100 | // the error will be printed on stderr. 101 | type ErrorResult interface { 102 | Result 103 | ErrorString() string 104 | } 105 | 106 | // SetOut can be used to change the out writer at runtime 107 | func SetOut(out io.Writer) { 108 | if formatSelected { 109 | panic("output format already selected") 110 | } 111 | stdOut = out 112 | } 113 | 114 | // SetErr can be used to change the err writer at runtime 115 | func SetErr(err io.Writer) { 116 | if formatSelected { 117 | panic("output format already selected") 118 | } 119 | stdErr = err 120 | } 121 | 122 | // SetFormat can be used to change the output format at runtime 123 | func SetFormat(f OutputFormat) { 124 | if formatSelected { 125 | panic("output format already selected") 126 | } 127 | format = f 128 | formatSelected = true 129 | 130 | if format == Text { 131 | feedbackOut = io.MultiWriter(bufferOut, stdOut) 132 | feedbackErr = io.MultiWriter(bufferErr, stdErr) 133 | } else { 134 | feedbackOut = bufferOut 135 | feedbackErr = bufferErr 136 | bufferWarnings = nil 137 | } 138 | } 139 | 140 | // GetFormat returns the output format currently set 141 | func GetFormat() OutputFormat { 142 | return format 143 | } 144 | 145 | // Printf behaves like fmt.Printf but writes on the out writer and adds a newline. 146 | func Printf(format string, v ...interface{}) { 147 | Print(fmt.Sprintf(format, v...)) 148 | } 149 | 150 | // Print behaves like fmt.Print but writes on the out writer and adds a newline. 151 | func Print(v string) { 152 | fmt.Fprintln(feedbackOut, v) 153 | } 154 | 155 | // Warning outputs a warning message. 156 | func Warning(msg string) { 157 | if format == Text { 158 | fmt.Fprintln(feedbackErr, msg) 159 | } else { 160 | bufferWarnings = append(bufferWarnings, msg) 161 | } 162 | } 163 | 164 | // FatalError outputs the error and exits with status exitCode. 165 | func FatalError(err error, exitCode ExitCode) { 166 | Fatal(err.Error(), exitCode) 167 | } 168 | 169 | // FatalResult outputs the result and exits with status exitCode. 170 | func FatalResult(res ErrorResult, exitCode ExitCode) { 171 | PrintResult(res) 172 | os.Exit(int(exitCode)) 173 | } 174 | 175 | // Fatal outputs the errorMsg and exits with status exitCode. 176 | func Fatal(errorMsg string, exitCode ExitCode) { 177 | if format == Text { 178 | fmt.Fprintln(stdErr, errorMsg) 179 | os.Exit(int(exitCode)) 180 | } 181 | 182 | type FatalError struct { 183 | Error string `json:"error"` 184 | Output *OutputStreamsResult `json:"output,omitempty"` 185 | } 186 | res := &FatalError{ 187 | Error: errorMsg, 188 | } 189 | if output := getOutputStreamResult(); !output.Empty() { 190 | res.Output = output 191 | } 192 | var d []byte 193 | switch format { 194 | case JSON: 195 | d, _ = json.MarshalIndent(augment(res), "", " ") 196 | case MinifiedJSON: 197 | d, _ = json.Marshal(augment(res)) 198 | default: 199 | panic("unknown output format") 200 | } 201 | fmt.Fprintln(stdErr, string(d)) 202 | os.Exit(int(exitCode)) 203 | } 204 | 205 | func augment(data interface{}) interface{} { 206 | if len(bufferWarnings) == 0 { 207 | return data 208 | } 209 | d, err := json.Marshal(data) 210 | if err != nil { 211 | return data 212 | } 213 | var res interface{} 214 | if err := json.Unmarshal(d, &res); err != nil { 215 | return data 216 | } 217 | if m, ok := res.(map[string]interface{}); ok { 218 | m["warnings"] = bufferWarnings 219 | } 220 | return res 221 | } 222 | 223 | // PrintResult is a convenient wrapper to provide feedback for complex data, 224 | // where the contents can't be just serialized to JSON but requires more 225 | // structure. 226 | func PrintResult(res Result) { 227 | var data string 228 | var dataErr string 229 | switch format { 230 | case JSON: 231 | d, err := json.MarshalIndent(augment(res.Data()), "", " ") 232 | if err != nil { 233 | Fatal(i18n.Tr("Error during JSON encoding of the output: %v", err), ErrGeneric) 234 | } 235 | data = string(d) 236 | case MinifiedJSON: 237 | d, err := json.Marshal(augment(res.Data())) 238 | if err != nil { 239 | Fatal(i18n.Tr("Error during JSON encoding of the output: %v", err), ErrGeneric) 240 | } 241 | data = string(d) 242 | case Text: 243 | data = res.String() 244 | if resErr, ok := res.(ErrorResult); ok { 245 | dataErr = resErr.ErrorString() 246 | } 247 | default: 248 | panic("unknown output format") 249 | } 250 | if data != "" { 251 | fmt.Fprintln(stdOut, data) 252 | } 253 | if dataErr != "" { 254 | fmt.Fprintln(stdErr, dataErr) 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /internal/updater/flasher.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | package updater 17 | 18 | import ( 19 | "context" 20 | "encoding/hex" 21 | "fmt" 22 | "runtime" 23 | "strconv" 24 | "strings" 25 | 26 | "github.com/arduino/go-paths-helper" 27 | "github.com/fatih/color" 28 | "github.com/shirou/gopsutil/v4/disk" 29 | 30 | "github.com/arduino/arduino-flasher-cli/cmd/feedback" 31 | "github.com/arduino/arduino-flasher-cli/cmd/i18n" 32 | "github.com/arduino/arduino-flasher-cli/internal/updater/artifacts" 33 | ) 34 | 35 | const GiB = uint64(1024 * 1024 * 1024) 36 | const DownloadDiskSpace = uint64(12) 37 | const ExtractDiskSpace = uint64(10) 38 | const yesPrompt = "yes" 39 | 40 | func Flash(ctx context.Context, imagePath *paths.Path, version string, forceYes bool, preserveUser bool, tempDir string) error { 41 | if !imagePath.Exist() { 42 | temp, err := SetTempDir("download-", tempDir) 43 | if err != nil { 44 | return fmt.Errorf("error creating a temporary directory to extract the archive: %v", err) 45 | } 46 | defer func() { _ = temp.RemoveAll() }() 47 | 48 | // Check if there is enough free disk space before downloading and extracting an image 49 | d, err := disk.Usage(temp.String()) 50 | if err != nil { 51 | return err 52 | } 53 | if d.Free/GiB < DownloadDiskSpace { 54 | return fmt.Errorf("download and extraction requires up to %d GiB of free space", DownloadDiskSpace) 55 | } 56 | 57 | tempImagePath, v, err := DownloadAndExtract(ctx, version, temp) 58 | 59 | if err != nil { 60 | return fmt.Errorf("could not download and extract the image: %v", err) 61 | } 62 | 63 | version = v 64 | imagePath = tempImagePath 65 | } else if !imagePath.IsDir() { 66 | temp, err := SetTempDir("extract-", tempDir) 67 | if err != nil { 68 | return fmt.Errorf("error creating a temporary directory to extract the archive: %v", err) 69 | } 70 | defer func() { _ = temp.RemoveAll() }() 71 | 72 | // Check if there is enough free disk space before extracting an image 73 | d, err := disk.Usage(temp.String()) 74 | if err != nil { 75 | return err 76 | } 77 | if d.Free/GiB < ExtractDiskSpace { 78 | return fmt.Errorf("extraction requires up to %d GiB of free space", ExtractDiskSpace) 79 | } 80 | 81 | err = ExtractImage(ctx, imagePath, temp) 82 | if err != nil { 83 | return fmt.Errorf("error extracting the archive: %v", err) 84 | } 85 | 86 | tempContent, err := temp.ReadDir(paths.AndFilter(paths.FilterDirectories(), paths.FilterPrefixes("arduino-unoq-debian-image-"))) 87 | if err != nil { 88 | return fmt.Errorf("could not find Debian image directory: %v", err) 89 | } 90 | 91 | imagePath = tempContent[0] 92 | } 93 | 94 | return FlashBoard(ctx, imagePath.String(), version, preserveUser) 95 | } 96 | 97 | func FlashBoard(ctx context.Context, downloadedImagePath string, version string, preserveUser bool) error { 98 | var flashDir *paths.Path 99 | for _, entry := range []string{"flash", "flash_UnoQ"} { 100 | if p := paths.New(downloadedImagePath, entry); p.Exist() { 101 | flashDir = p 102 | break 103 | } 104 | } 105 | if flashDir == nil { 106 | return fmt.Errorf("could not find the `flash` directory") 107 | } 108 | 109 | qdlDir, err := paths.MkTempDir("", "qdl-") 110 | if err != nil { 111 | return err 112 | } 113 | defer func() { _ = qdlDir.RemoveAll() }() 114 | 115 | qdlPath := qdlDir.Join("qdl") 116 | if runtime.GOOS == "windows" { 117 | qdlPath = qdlDir.Join("qdl.exe") 118 | } 119 | 120 | err = qdlPath.WriteFile(artifacts.QdlBinary) 121 | if err != nil { 122 | return err 123 | } 124 | err = qdlPath.Chmod(0755) 125 | if err != nil { 126 | return err 127 | } 128 | 129 | stdout, _, err := feedback.DirectStreams() 130 | if err != nil { 131 | return err 132 | } 133 | 134 | rawProgram := "rawprogram0.xml" 135 | if preserveUser { 136 | if errT := checkBoardGPTTable(ctx, qdlPath, flashDir); errT == nil && flashDir.Join("rawprogram0.nouser.xml").Exist() { 137 | rawProgram = "rawprogram0.nouser.xml" 138 | } else { 139 | res, err := func(target string) (bool, error) { 140 | warnStr := "Linux image " + target + " does not support user partition preservation" 141 | if errT != nil { 142 | warnStr = errT.Error() 143 | } 144 | feedback.Print(color.RedString("\nWARNING: %s. It will not be possible to preserve your data.\n", warnStr)) 145 | feedback.Printf("Do you want to proceed and flash %s on the board? (yes/no)", target) 146 | 147 | var yesInput string 148 | _, err := fmt.Scanf("%s\n", &yesInput) 149 | if err != nil { 150 | return false, err 151 | } 152 | yes := strings.ToLower(yesInput) == yesPrompt || strings.ToLower(yesInput) == "y" 153 | return yes, nil 154 | }(version) 155 | if err != nil { 156 | return err 157 | } 158 | if !res { 159 | return fmt.Errorf("flashing not confirmed by user, exiting") 160 | } 161 | } 162 | 163 | } 164 | 165 | feedback.Print(i18n.Tr("Flashing with qdl")) 166 | cmd, err := paths.NewProcess(nil, qdlPath.String(), "--allow-missing", "--storage", "emmc", "prog_firehose_ddr.elf", rawProgram, "patch0.xml") 167 | if err != nil { 168 | return err 169 | } 170 | // Setting the directory is needed because rawprogram0.xml contains relative file paths 171 | cmd.SetDir(flashDir.String()) 172 | cmd.RedirectStderrTo(stdout) 173 | cmd.RedirectStdoutTo(stdout) 174 | if err := cmd.RunWithinContext(ctx); err != nil { 175 | return err 176 | } 177 | 178 | return nil 179 | } 180 | 181 | // Checks the board GPT table and counts the number of partitions, this tells if the board supports preserving or not user's data. 182 | func checkBoardGPTTable(ctx context.Context, qdlPath, flashDir *paths.Path) error { 183 | dumpBinPath := qdlPath.Parent().Join("dump.bin") 184 | readXMLPath := qdlPath.Parent().Join("read.xml") 185 | err := readXMLPath.WriteFile(artifacts.ReadXML) 186 | if err != nil { 187 | return err 188 | } 189 | cmd, err := paths.NewProcess(nil, qdlPath.String(), "--storage", "emmc", flashDir.Join("prog_firehose_ddr.elf").String(), readXMLPath.String()) 190 | if err != nil { 191 | return err 192 | } 193 | cmd.SetDir(qdlPath.Parent().String()) 194 | if err := cmd.RunWithinContext(ctx); err != nil { 195 | return err 196 | } 197 | if !dumpBinPath.Exist() { 198 | return fmt.Errorf("it was not possible to access the current Debian image GPT table") 199 | } 200 | dump, err := dumpBinPath.ReadFile() 201 | if err != nil { 202 | return err 203 | } 204 | strDump := hex.Dump(dump) 205 | 206 | strDumpSlice := strings.Split(strDump, "\n") 207 | // the max number of partitions is stored at entry 0x50 208 | maxPartitions, err := strconv.ParseInt(strings.Split(strDumpSlice[5], " ")[2], 16, 16) 209 | if err != nil { 210 | return err 211 | } 212 | 213 | numPartitions := 0 214 | // starting from entry 0x200, there is a new partition every 0x80 bytes 215 | // TODO: check if the size of each partition is 80h or just assume it? 216 | for i := 32; numPartitions < int(maxPartitions); i += 8 { 217 | // partitions are made of non-zero bytes, if all 0s then there are no more entries 218 | if strings.Contains(strDumpSlice[i], "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") { 219 | break 220 | } 221 | numPartitions++ 222 | } 223 | 224 | if numPartitions == 73 && maxPartitions == 76 { 225 | return fmt.Errorf("the current Debian image (R0) does not support user partition preservation") 226 | } 227 | 228 | return nil 229 | } 230 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/juju/errors.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/juju/errors 3 | version: v1.0.0 4 | type: go 5 | summary: Package errors provides an easy way to annotate errors without losing the 6 | original error context. 7 | homepage: https://pkg.go.dev/github.com/juju/errors 8 | license: lgpl-3.0-only 9 | licenses: 10 | - sources: LICENSE 11 | text: | 12 | All files in this repository are licensed as follows. If you contribute 13 | to this repository, it is assumed that you license your contribution 14 | under the same license unless you state otherwise. 15 | 16 | All files Copyright (C) 2015 Canonical Ltd. unless otherwise specified in the file. 17 | 18 | This software is licensed under the LGPLv3, included below. 19 | 20 | As a special exception to the GNU Lesser General Public License version 3 21 | ("LGPL3"), the copyright holders of this Library give you permission to 22 | convey to a third party a Combined Work that links statically or dynamically 23 | to this Library without providing any Minimal Corresponding Source or 24 | Minimal Application Code as set out in 4d or providing the installation 25 | information set out in section 4e, provided that you comply with the other 26 | provisions of LGPL3 and provided that you meet, for the Application the 27 | terms and conditions of the license(s) which apply to the Application. 28 | 29 | Except as stated in this special exception, the provisions of LGPL3 will 30 | continue to comply in full to this Library. If you modify this Library, you 31 | may apply this exception to your version of this Library, but you are not 32 | obliged to do so. If you do not wish to do so, delete this exception 33 | statement from your version. This exception does not (and cannot) modify any 34 | license terms which apply to the Application, with which you must still 35 | comply. 36 | 37 | 38 | GNU LESSER GENERAL PUBLIC LICENSE 39 | Version 3, 29 June 2007 40 | 41 | Copyright (C) 2007 Free Software Foundation, Inc. 42 | Everyone is permitted to copy and distribute verbatim copies 43 | of this license document, but changing it is not allowed. 44 | 45 | 46 | This version of the GNU Lesser General Public License incorporates 47 | the terms and conditions of version 3 of the GNU General Public 48 | License, supplemented by the additional permissions listed below. 49 | 50 | 0. Additional Definitions. 51 | 52 | As used herein, "this License" refers to version 3 of the GNU Lesser 53 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 54 | General Public License. 55 | 56 | "The Library" refers to a covered work governed by this License, 57 | other than an Application or a Combined Work as defined below. 58 | 59 | An "Application" is any work that makes use of an interface provided 60 | by the Library, but which is not otherwise based on the Library. 61 | Defining a subclass of a class defined by the Library is deemed a mode 62 | of using an interface provided by the Library. 63 | 64 | A "Combined Work" is a work produced by combining or linking an 65 | Application with the Library. The particular version of the Library 66 | with which the Combined Work was made is also called the "Linked 67 | Version". 68 | 69 | The "Minimal Corresponding Source" for a Combined Work means the 70 | Corresponding Source for the Combined Work, excluding any source code 71 | for portions of the Combined Work that, considered in isolation, are 72 | based on the Application, and not on the Linked Version. 73 | 74 | The "Corresponding Application Code" for a Combined Work means the 75 | object code and/or source code for the Application, including any data 76 | and utility programs needed for reproducing the Combined Work from the 77 | Application, but excluding the System Libraries of the Combined Work. 78 | 79 | 1. Exception to Section 3 of the GNU GPL. 80 | 81 | You may convey a covered work under sections 3 and 4 of this License 82 | without being bound by section 3 of the GNU GPL. 83 | 84 | 2. Conveying Modified Versions. 85 | 86 | If you modify a copy of the Library, and, in your modifications, a 87 | facility refers to a function or data to be supplied by an Application 88 | that uses the facility (other than as an argument passed when the 89 | facility is invoked), then you may convey a copy of the modified 90 | version: 91 | 92 | a) under this License, provided that you make a good faith effort to 93 | ensure that, in the event an Application does not supply the 94 | function or data, the facility still operates, and performs 95 | whatever part of its purpose remains meaningful, or 96 | 97 | b) under the GNU GPL, with none of the additional permissions of 98 | this License applicable to that copy. 99 | 100 | 3. Object Code Incorporating Material from Library Header Files. 101 | 102 | The object code form of an Application may incorporate material from 103 | a header file that is part of the Library. You may convey such object 104 | code under terms of your choice, provided that, if the incorporated 105 | material is not limited to numerical parameters, data structure 106 | layouts and accessors, or small macros, inline functions and templates 107 | (ten or fewer lines in length), you do both of the following: 108 | 109 | a) Give prominent notice with each copy of the object code that the 110 | Library is used in it and that the Library and its use are 111 | covered by this License. 112 | 113 | b) Accompany the object code with a copy of the GNU GPL and this license 114 | document. 115 | 116 | 4. Combined Works. 117 | 118 | You may convey a Combined Work under terms of your choice that, 119 | taken together, effectively do not restrict modification of the 120 | portions of the Library contained in the Combined Work and reverse 121 | engineering for debugging such modifications, if you also do each of 122 | the following: 123 | 124 | a) Give prominent notice with each copy of the Combined Work that 125 | the Library is used in it and that the Library and its use are 126 | covered by this License. 127 | 128 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 129 | document. 130 | 131 | c) For a Combined Work that displays copyright notices during 132 | execution, include the copyright notice for the Library among 133 | these notices, as well as a reference directing the user to the 134 | copies of the GNU GPL and this license document. 135 | 136 | d) Do one of the following: 137 | 138 | 0) Convey the Minimal Corresponding Source under the terms of this 139 | License, and the Corresponding Application Code in a form 140 | suitable for, and under terms that permit, the user to 141 | recombine or relink the Application with a modified version of 142 | the Linked Version to produce a modified Combined Work, in the 143 | manner specified by section 6 of the GNU GPL for conveying 144 | Corresponding Source. 145 | 146 | 1) Use a suitable shared library mechanism for linking with the 147 | Library. A suitable mechanism is one that (a) uses at run time 148 | a copy of the Library already present on the user's computer 149 | system, and (b) will operate properly with a modified version 150 | of the Library that is interface-compatible with the Linked 151 | Version. 152 | 153 | e) Provide Installation Information, but only if you would otherwise 154 | be required to provide such information under section 6 of the 155 | GNU GPL, and only to the extent that such information is 156 | necessary to install and execute a modified version of the 157 | Combined Work produced by recombining or relinking the 158 | Application with a modified version of the Linked Version. (If 159 | you use option 4d0, the Installation Information must accompany 160 | the Minimal Corresponding Source and Corresponding Application 161 | Code. If you use option 4d1, you must provide the Installation 162 | Information in the manner specified by section 6 of the GNU GPL 163 | for conveying Corresponding Source.) 164 | 165 | 5. Combined Libraries. 166 | 167 | You may place library facilities that are a work based on the 168 | Library side by side in a single library together with other library 169 | facilities that are not Applications and are not covered by this 170 | License, and convey such a combined library under terms of your 171 | choice, if you do both of the following: 172 | 173 | a) Accompany the combined library with a copy of the same work based 174 | on the Library, uncombined with any other library facilities, 175 | conveyed under the terms of this License. 176 | 177 | b) Give prominent notice with the combined library that part of it 178 | is a work based on the Library, and explaining where to find the 179 | accompanying uncombined form of the same work. 180 | 181 | 6. Revised Versions of the GNU Lesser General Public License. 182 | 183 | The Free Software Foundation may publish revised and/or new versions 184 | of the GNU Lesser General Public License from time to time. Such new 185 | versions will be similar in spirit to the present version, but may 186 | differ in detail to address new problems or concerns. 187 | 188 | Each version is given a distinguishing version number. If the 189 | Library as you received it specifies that a certain numbered version 190 | of the GNU Lesser General Public License "or any later version" 191 | applies to it, you have the option of following the terms and 192 | conditions either of that published version or of any later version 193 | published by the Free Software Foundation. If the Library as you 194 | received it does not specify a version number of the GNU Lesser 195 | General Public License, you may choose any version of the GNU Lesser 196 | General Public License ever published by the Free Software Foundation. 197 | 198 | If the Library as you received it specifies that a proxy can decide 199 | whether future versions of the GNU Lesser General Public License shall 200 | apply, that proxy's public statement of acceptance of any version is 201 | permanent authorization for you to choose that version for the 202 | Library. 203 | notices: [] 204 | -------------------------------------------------------------------------------- /.licenses/arduino-flasher-cli/go/github.com/spf13/cobra.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: github.com/spf13/cobra 3 | version: v1.9.1 4 | type: go 5 | summary: Package cobra is a commander providing a simple interface to create powerful 6 | modern CLI interfaces. 7 | homepage: https://pkg.go.dev/github.com/spf13/cobra 8 | license: apache-2.0 9 | licenses: 10 | - sources: LICENSE.txt 11 | text: |2 12 | Apache License 13 | Version 2.0, January 2004 14 | http://www.apache.org/licenses/ 15 | 16 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 17 | 18 | 1. Definitions. 19 | 20 | "License" shall mean the terms and conditions for use, reproduction, 21 | and distribution as defined by Sections 1 through 9 of this document. 22 | 23 | "Licensor" shall mean the copyright owner or entity authorized by 24 | the copyright owner that is granting the License. 25 | 26 | "Legal Entity" shall mean the union of the acting entity and all 27 | other entities that control, are controlled by, or are under common 28 | control with that entity. For the purposes of this definition, 29 | "control" means (i) the power, direct or indirect, to cause the 30 | direction or management of such entity, whether by contract or 31 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 32 | outstanding shares, or (iii) beneficial ownership of such entity. 33 | 34 | "You" (or "Your") shall mean an individual or Legal Entity 35 | exercising permissions granted by this License. 36 | 37 | "Source" form shall mean the preferred form for making modifications, 38 | including but not limited to software source code, documentation 39 | source, and configuration files. 40 | 41 | "Object" form shall mean any form resulting from mechanical 42 | transformation or translation of a Source form, including but 43 | not limited to compiled object code, generated documentation, 44 | and conversions to other media types. 45 | 46 | "Work" shall mean the work of authorship, whether in Source or 47 | Object form, made available under the License, as indicated by a 48 | copyright notice that is included in or attached to the work 49 | (an example is provided in the Appendix below). 50 | 51 | "Derivative Works" shall mean any work, whether in Source or Object 52 | form, that is based on (or derived from) the Work and for which the 53 | editorial revisions, annotations, elaborations, or other modifications 54 | represent, as a whole, an original work of authorship. For the purposes 55 | of this License, Derivative Works shall not include works that remain 56 | separable from, or merely link (or bind by name) to the interfaces of, 57 | the Work and Derivative Works thereof. 58 | 59 | "Contribution" shall mean any work of authorship, including 60 | the original version of the Work and any modifications or additions 61 | to that Work or Derivative Works thereof, that is intentionally 62 | submitted to Licensor for inclusion in the Work by the copyright owner 63 | or by an individual or Legal Entity authorized to submit on behalf of 64 | the copyright owner. For the purposes of this definition, "submitted" 65 | means any form of electronic, verbal, or written communication sent 66 | to the Licensor or its representatives, including but not limited to 67 | communication on electronic mailing lists, source code control systems, 68 | and issue tracking systems that are managed by, or on behalf of, the 69 | Licensor for the purpose of discussing and improving the Work, but 70 | excluding communication that is conspicuously marked or otherwise 71 | designated in writing by the copyright owner as "Not a Contribution." 72 | 73 | "Contributor" shall mean Licensor and any individual or Legal Entity 74 | on behalf of whom a Contribution has been received by Licensor and 75 | subsequently incorporated within the Work. 76 | 77 | 2. Grant of Copyright License. Subject to the terms and conditions of 78 | this License, each Contributor hereby grants to You a perpetual, 79 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 80 | copyright license to reproduce, prepare Derivative Works of, 81 | publicly display, publicly perform, sublicense, and distribute the 82 | Work and such Derivative Works in Source or Object form. 83 | 84 | 3. Grant of Patent License. Subject to the terms and conditions of 85 | this License, each Contributor hereby grants to You a perpetual, 86 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 87 | (except as stated in this section) patent license to make, have made, 88 | use, offer to sell, sell, import, and otherwise transfer the Work, 89 | where such license applies only to those patent claims licensable 90 | by such Contributor that are necessarily infringed by their 91 | Contribution(s) alone or by combination of their Contribution(s) 92 | with the Work to which such Contribution(s) was submitted. If You 93 | institute patent litigation against any entity (including a 94 | cross-claim or counterclaim in a lawsuit) alleging that the Work 95 | or a Contribution incorporated within the Work constitutes direct 96 | or contributory patent infringement, then any patent licenses 97 | granted to You under this License for that Work shall terminate 98 | as of the date such litigation is filed. 99 | 100 | 4. Redistribution. You may reproduce and distribute copies of the 101 | Work or Derivative Works thereof in any medium, with or without 102 | modifications, and in Source or Object form, provided that You 103 | meet the following conditions: 104 | 105 | (a) You must give any other recipients of the Work or 106 | Derivative Works a copy of this License; and 107 | 108 | (b) You must cause any modified files to carry prominent notices 109 | stating that You changed the files; and 110 | 111 | (c) You must retain, in the Source form of any Derivative Works 112 | that You distribute, all copyright, patent, trademark, and 113 | attribution notices from the Source form of the Work, 114 | excluding those notices that do not pertain to any part of 115 | the Derivative Works; and 116 | 117 | (d) If the Work includes a "NOTICE" text file as part of its 118 | distribution, then any Derivative Works that You distribute must 119 | include a readable copy of the attribution notices contained 120 | within such NOTICE file, excluding those notices that do not 121 | pertain to any part of the Derivative Works, in at least one 122 | of the following places: within a NOTICE text file distributed 123 | as part of the Derivative Works; within the Source form or 124 | documentation, if provided along with the Derivative Works; or, 125 | within a display generated by the Derivative Works, if and 126 | wherever such third-party notices normally appear. The contents 127 | of the NOTICE file are for informational purposes only and 128 | do not modify the License. You may add Your own attribution 129 | notices within Derivative Works that You distribute, alongside 130 | or as an addendum to the NOTICE text from the Work, provided 131 | that such additional attribution notices cannot be construed 132 | as modifying the License. 133 | 134 | You may add Your own copyright statement to Your modifications and 135 | may provide additional or different license terms and conditions 136 | for use, reproduction, or distribution of Your modifications, or 137 | for any such Derivative Works as a whole, provided Your use, 138 | reproduction, and distribution of the Work otherwise complies with 139 | the conditions stated in this License. 140 | 141 | 5. Submission of Contributions. Unless You explicitly state otherwise, 142 | any Contribution intentionally submitted for inclusion in the Work 143 | by You to the Licensor shall be under the terms and conditions of 144 | this License, without any additional terms or conditions. 145 | Notwithstanding the above, nothing herein shall supersede or modify 146 | the terms of any separate license agreement you may have executed 147 | with Licensor regarding such Contributions. 148 | 149 | 6. Trademarks. This License does not grant permission to use the trade 150 | names, trademarks, service marks, or product names of the Licensor, 151 | except as required for reasonable and customary use in describing the 152 | origin of the Work and reproducing the content of the NOTICE file. 153 | 154 | 7. Disclaimer of Warranty. Unless required by applicable law or 155 | agreed to in writing, Licensor provides the Work (and each 156 | Contributor provides its Contributions) on an "AS IS" BASIS, 157 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 158 | implied, including, without limitation, any warranties or conditions 159 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 160 | PARTICULAR PURPOSE. You are solely responsible for determining the 161 | appropriateness of using or redistributing the Work and assume any 162 | risks associated with Your exercise of permissions under this License. 163 | 164 | 8. Limitation of Liability. In no event and under no legal theory, 165 | whether in tort (including negligence), contract, or otherwise, 166 | unless required by applicable law (such as deliberate and grossly 167 | negligent acts) or agreed to in writing, shall any Contributor be 168 | liable to You for damages, including any direct, indirect, special, 169 | incidental, or consequential damages of any character arising as a 170 | result of this License or out of the use or inability to use the 171 | Work (including but not limited to damages for loss of goodwill, 172 | work stoppage, computer failure or malfunction, or any and all 173 | other commercial damages or losses), even if such Contributor 174 | has been advised of the possibility of such damages. 175 | 176 | 9. Accepting Warranty or Additional Liability. While redistributing 177 | the Work or Derivative Works thereof, You may choose to offer, 178 | and charge a fee for, acceptance of support, warranty, indemnity, 179 | or other liability obligations and/or rights consistent with this 180 | License. However, in accepting such obligations, You may act only 181 | on Your own behalf and on Your sole responsibility, not on behalf 182 | of any other Contributor, and only if You agree to indemnify, 183 | defend, and hold each Contributor harmless for any liability 184 | incurred by, or claims asserted against, such Contributor by reason 185 | of your accepting any such warranty or additional liability. 186 | - sources: README.md 187 | text: Cobra is released under the Apache 2.0 license. See [LICENSE.txt](LICENSE.txt) 188 | notices: [] 189 | -------------------------------------------------------------------------------- /rpc/cc/arduino/flasher/v1/commands.pb.go: -------------------------------------------------------------------------------- 1 | // This file is part of arduino-flasher-cli. 2 | // 3 | // Copyright 2025 ARDUINO SA (http://www.arduino.cc/) 4 | // 5 | // This software is released under the GNU General Public License version 3, 6 | // which covers the main part of arduino-flasher-cli. 7 | // The terms of this license can be found at: 8 | // https://www.gnu.org/licenses/gpl-3.0.en.html 9 | // 10 | // You can be released from the requirements of the above licenses by purchasing 11 | // a commercial license. Buying such a license is mandatory if you want to 12 | // modify or otherwise use the software for commercial activities involving the 13 | // Arduino software without disclosing the source code of your own applications. 14 | // To purchase a commercial license, send an email to license@arduino.cc. 15 | 16 | // Code generated by protoc-gen-go. DO NOT EDIT. 17 | // versions: 18 | // protoc-gen-go v1.34.2 19 | // protoc (unknown) 20 | // source: cc/arduino/flasher/v1/commands.proto 21 | 22 | package flasher 23 | 24 | import ( 25 | reflect "reflect" 26 | sync "sync" 27 | 28 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 29 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 30 | ) 31 | 32 | const ( 33 | // Verify that this generated code is sufficiently up-to-date. 34 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 35 | // Verify that runtime/protoimpl is sufficiently up-to-date. 36 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 37 | ) 38 | 39 | type ListRequest struct { 40 | state protoimpl.MessageState 41 | sizeCache protoimpl.SizeCache 42 | unknownFields protoimpl.UnknownFields 43 | } 44 | 45 | func (x *ListRequest) Reset() { 46 | *x = ListRequest{} 47 | if protoimpl.UnsafeEnabled { 48 | mi := &file_cc_arduino_flasher_v1_commands_proto_msgTypes[0] 49 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 50 | ms.StoreMessageInfo(mi) 51 | } 52 | } 53 | 54 | func (x *ListRequest) String() string { 55 | return protoimpl.X.MessageStringOf(x) 56 | } 57 | 58 | func (*ListRequest) ProtoMessage() {} 59 | 60 | func (x *ListRequest) ProtoReflect() protoreflect.Message { 61 | mi := &file_cc_arduino_flasher_v1_commands_proto_msgTypes[0] 62 | if protoimpl.UnsafeEnabled && x != nil { 63 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 64 | if ms.LoadMessageInfo() == nil { 65 | ms.StoreMessageInfo(mi) 66 | } 67 | return ms 68 | } 69 | return mi.MessageOf(x) 70 | } 71 | 72 | // Deprecated: Use ListRequest.ProtoReflect.Descriptor instead. 73 | func (*ListRequest) Descriptor() ([]byte, []int) { 74 | return file_cc_arduino_flasher_v1_commands_proto_rawDescGZIP(), []int{0} 75 | } 76 | 77 | type ListResponse struct { 78 | state protoimpl.MessageState 79 | sizeCache protoimpl.SizeCache 80 | unknownFields protoimpl.UnknownFields 81 | 82 | Releases []*Release `protobuf:"bytes,1,rep,name=releases,proto3" json:"releases,omitempty"` 83 | } 84 | 85 | func (x *ListResponse) Reset() { 86 | *x = ListResponse{} 87 | if protoimpl.UnsafeEnabled { 88 | mi := &file_cc_arduino_flasher_v1_commands_proto_msgTypes[1] 89 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 90 | ms.StoreMessageInfo(mi) 91 | } 92 | } 93 | 94 | func (x *ListResponse) String() string { 95 | return protoimpl.X.MessageStringOf(x) 96 | } 97 | 98 | func (*ListResponse) ProtoMessage() {} 99 | 100 | func (x *ListResponse) ProtoReflect() protoreflect.Message { 101 | mi := &file_cc_arduino_flasher_v1_commands_proto_msgTypes[1] 102 | if protoimpl.UnsafeEnabled && x != nil { 103 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 104 | if ms.LoadMessageInfo() == nil { 105 | ms.StoreMessageInfo(mi) 106 | } 107 | return ms 108 | } 109 | return mi.MessageOf(x) 110 | } 111 | 112 | // Deprecated: Use ListResponse.ProtoReflect.Descriptor instead. 113 | func (*ListResponse) Descriptor() ([]byte, []int) { 114 | return file_cc_arduino_flasher_v1_commands_proto_rawDescGZIP(), []int{1} 115 | } 116 | 117 | func (x *ListResponse) GetReleases() []*Release { 118 | if x != nil { 119 | return x.Releases 120 | } 121 | return nil 122 | } 123 | 124 | type Release struct { 125 | state protoimpl.MessageState 126 | sizeCache protoimpl.SizeCache 127 | unknownFields protoimpl.UnknownFields 128 | 129 | BuildId string `protobuf:"bytes,1,opt,name=build_id,json=buildId,proto3" json:"build_id,omitempty"` 130 | Latest bool `protobuf:"varint,2,opt,name=latest,proto3" json:"latest,omitempty"` 131 | } 132 | 133 | func (x *Release) Reset() { 134 | *x = Release{} 135 | if protoimpl.UnsafeEnabled { 136 | mi := &file_cc_arduino_flasher_v1_commands_proto_msgTypes[2] 137 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 138 | ms.StoreMessageInfo(mi) 139 | } 140 | } 141 | 142 | func (x *Release) String() string { 143 | return protoimpl.X.MessageStringOf(x) 144 | } 145 | 146 | func (*Release) ProtoMessage() {} 147 | 148 | func (x *Release) ProtoReflect() protoreflect.Message { 149 | mi := &file_cc_arduino_flasher_v1_commands_proto_msgTypes[2] 150 | if protoimpl.UnsafeEnabled && x != nil { 151 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 152 | if ms.LoadMessageInfo() == nil { 153 | ms.StoreMessageInfo(mi) 154 | } 155 | return ms 156 | } 157 | return mi.MessageOf(x) 158 | } 159 | 160 | // Deprecated: Use Release.ProtoReflect.Descriptor instead. 161 | func (*Release) Descriptor() ([]byte, []int) { 162 | return file_cc_arduino_flasher_v1_commands_proto_rawDescGZIP(), []int{2} 163 | } 164 | 165 | func (x *Release) GetBuildId() string { 166 | if x != nil { 167 | return x.BuildId 168 | } 169 | return "" 170 | } 171 | 172 | func (x *Release) GetLatest() bool { 173 | if x != nil { 174 | return x.Latest 175 | } 176 | return false 177 | } 178 | 179 | var File_cc_arduino_flasher_v1_commands_proto protoreflect.FileDescriptor 180 | 181 | var file_cc_arduino_flasher_v1_commands_proto_rawDesc = []byte{ 182 | 0x0a, 0x24, 0x63, 0x63, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x66, 0x6c, 0x61, 183 | 0x73, 0x68, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 184 | 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 185 | 0x6e, 0x6f, 0x2e, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x22, 0x0d, 0x0a, 186 | 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4a, 0x0a, 0x0c, 187 | 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x08, 188 | 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 189 | 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x66, 0x6c, 0x61, 0x73, 190 | 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x08, 191 | 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x73, 0x22, 0x3c, 0x0a, 0x07, 0x52, 0x65, 0x6c, 0x65, 192 | 0x61, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 193 | 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x16, 194 | 0x0a, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 195 | 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x32, 0x5c, 0x0a, 0x07, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x65, 196 | 0x72, 0x12, 0x51, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x22, 0x2e, 0x63, 0x63, 0x2e, 0x61, 197 | 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x72, 0x2e, 0x76, 198 | 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 199 | 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x66, 0x6c, 0x61, 0x73, 0x68, 200 | 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 201 | 0x73, 0x65, 0x22, 0x00, 0x42, 0x4a, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 202 | 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 203 | 0x6e, 0x6f, 0x2d, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x72, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, 204 | 0x70, 0x63, 0x2f, 0x63, 0x63, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x66, 0x6c, 205 | 0x61, 0x73, 0x68, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x72, 206 | 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 207 | } 208 | 209 | var ( 210 | file_cc_arduino_flasher_v1_commands_proto_rawDescOnce sync.Once 211 | file_cc_arduino_flasher_v1_commands_proto_rawDescData = file_cc_arduino_flasher_v1_commands_proto_rawDesc 212 | ) 213 | 214 | func file_cc_arduino_flasher_v1_commands_proto_rawDescGZIP() []byte { 215 | file_cc_arduino_flasher_v1_commands_proto_rawDescOnce.Do(func() { 216 | file_cc_arduino_flasher_v1_commands_proto_rawDescData = protoimpl.X.CompressGZIP(file_cc_arduino_flasher_v1_commands_proto_rawDescData) 217 | }) 218 | return file_cc_arduino_flasher_v1_commands_proto_rawDescData 219 | } 220 | 221 | var file_cc_arduino_flasher_v1_commands_proto_msgTypes = make([]protoimpl.MessageInfo, 3) 222 | var file_cc_arduino_flasher_v1_commands_proto_goTypes = []any{ 223 | (*ListRequest)(nil), // 0: cc.arduino.flasher.v1.ListRequest 224 | (*ListResponse)(nil), // 1: cc.arduino.flasher.v1.ListResponse 225 | (*Release)(nil), // 2: cc.arduino.flasher.v1.Release 226 | } 227 | var file_cc_arduino_flasher_v1_commands_proto_depIdxs = []int32{ 228 | 2, // 0: cc.arduino.flasher.v1.ListResponse.releases:type_name -> cc.arduino.flasher.v1.Release 229 | 0, // 1: cc.arduino.flasher.v1.Flasher.List:input_type -> cc.arduino.flasher.v1.ListRequest 230 | 1, // 2: cc.arduino.flasher.v1.Flasher.List:output_type -> cc.arduino.flasher.v1.ListResponse 231 | 2, // [2:3] is the sub-list for method output_type 232 | 1, // [1:2] is the sub-list for method input_type 233 | 1, // [1:1] is the sub-list for extension type_name 234 | 1, // [1:1] is the sub-list for extension extendee 235 | 0, // [0:1] is the sub-list for field type_name 236 | } 237 | 238 | func init() { file_cc_arduino_flasher_v1_commands_proto_init() } 239 | func file_cc_arduino_flasher_v1_commands_proto_init() { 240 | if File_cc_arduino_flasher_v1_commands_proto != nil { 241 | return 242 | } 243 | if !protoimpl.UnsafeEnabled { 244 | file_cc_arduino_flasher_v1_commands_proto_msgTypes[0].Exporter = func(v any, i int) any { 245 | switch v := v.(*ListRequest); i { 246 | case 0: 247 | return &v.state 248 | case 1: 249 | return &v.sizeCache 250 | case 2: 251 | return &v.unknownFields 252 | default: 253 | return nil 254 | } 255 | } 256 | file_cc_arduino_flasher_v1_commands_proto_msgTypes[1].Exporter = func(v any, i int) any { 257 | switch v := v.(*ListResponse); i { 258 | case 0: 259 | return &v.state 260 | case 1: 261 | return &v.sizeCache 262 | case 2: 263 | return &v.unknownFields 264 | default: 265 | return nil 266 | } 267 | } 268 | file_cc_arduino_flasher_v1_commands_proto_msgTypes[2].Exporter = func(v any, i int) any { 269 | switch v := v.(*Release); i { 270 | case 0: 271 | return &v.state 272 | case 1: 273 | return &v.sizeCache 274 | case 2: 275 | return &v.unknownFields 276 | default: 277 | return nil 278 | } 279 | } 280 | } 281 | type x struct{} 282 | out := protoimpl.TypeBuilder{ 283 | File: protoimpl.DescBuilder{ 284 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 285 | RawDescriptor: file_cc_arduino_flasher_v1_commands_proto_rawDesc, 286 | NumEnums: 0, 287 | NumMessages: 3, 288 | NumExtensions: 0, 289 | NumServices: 1, 290 | }, 291 | GoTypes: file_cc_arduino_flasher_v1_commands_proto_goTypes, 292 | DependencyIndexes: file_cc_arduino_flasher_v1_commands_proto_depIdxs, 293 | MessageInfos: file_cc_arduino_flasher_v1_commands_proto_msgTypes, 294 | }.Build() 295 | File_cc_arduino_flasher_v1_commands_proto = out.File 296 | file_cc_arduino_flasher_v1_commands_proto_rawDesc = nil 297 | file_cc_arduino_flasher_v1_commands_proto_goTypes = nil 298 | file_cc_arduino_flasher_v1_commands_proto_depIdxs = nil 299 | } 300 | --------------------------------------------------------------------------------