diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index da9a2924e..79e35830c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -20,6 +20,7 @@ about: Create a report to help us improve - Browser [e.g. chrome, safari]: - Browser Version: - Agent Version [e.g. 1.0.0]: + - CPU architecture [e.g. amd64] ## Additional context diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 93c33c505..ea51c4276 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,16 +5,52 @@ on: tags: - "[0-9]+.[0-9]+.[0-9]+*" +env: + TARGET: "/CreateAgent/Stable" + OLD_TARGET: "/CreateBridge/" # compatibility with older releases (we can't change config.ini) + VERSION_TARGET: "arduino-create-static/agent-metadata/" + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_REGION: "us-east-1" # or https://github.com/aws/aws-cli/issues/5623 + KEYCHAIN: "sign.keychain" + INSTALLER_CERT_MAC_PATH: "/tmp/ArduinoCerts2020.p12" + AC_USERNAME: ${{ secrets.AC_USERNAME }} # used by gon + AC_PASSWORD: ${{ secrets.AC_PASSWORD }} # used by gon + jobs: # The build job is responsible for: configuring the environment, testing and compiling process build: strategy: matrix: - operating-system: [ubuntu-18.04, windows-2019, macos-10.15] + os: [ubuntu-18.04, windows-2019, macos-10.15] + arch: [-amd64] + include: + - os: windows-2019 + arch: -386 + ext: ".exe" + - os: windows-2019 + ext: ".exe" + + defaults: + run: + shell: bash - runs-on: ${{ matrix.operating-system }} + runs-on: ${{ matrix.os }} steps: + - name: Set env vars + run: | + echo "TAG_VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV + echo $(go env GOPATH)/bin >> $GITHUB_PATH + + - name: Identify Prerelease + # This is a workaround while waiting for create-release action to implement auto pre-release based on tag + id: prerelease + run: | + curl -L -s https://github.com/fsaintjacques/semver-tool/archive/3.1.0.zip -o /tmp/3.1.0.zip + unzip -p /tmp/3.1.0.zip semver-tool-3.1.0/src/semver >/tmp/semver && chmod +x /tmp/semver + if [[ $(/tmp/semver get prerel ${GITHUB_REF/refs\/tags\//}) ]]; then echo "::set-output name=IS_PRE::true"; fi + - name: Disable EOL conversions run: git config --global core.autocrlf false @@ -24,12 +60,12 @@ jobs: - name: Install Go uses: actions/setup-go@v2 with: - go-version: "1.15" + go-version: "1.14" # dependencies used for compiling the GUI - name: Install Dependencies (Linux) run: sudo apt update && sudo apt install -y --no-install-recommends build-essential libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev - if: matrix.operating-system == 'ubuntu-18.04' + if: matrix.os == 'ubuntu-18.04' - name: Install Go deps # Since 10/23/2019 pwsh is the default shell @@ -38,10 +74,10 @@ jobs: run: | go get github.com/golangci/govet go get golang.org/x/lint/golint - shell: bash + go get -u github.com/sanbornm/go-selfupdate/... - name: Install Taskfile - uses: arduino/actions/setup-taskfile@master + uses: arduino/setup-task@v1 with: version: '3.x' repo-token: ${{ secrets.GITHUB_TOKEN }} @@ -49,45 +85,61 @@ jobs: - name: Check the code is good run: task check - - name: Run unit tests - run: task test-unit - - name: Build the Agent for linux - run: task build - if: matrix.operating-system == 'ubuntu-18.04' + run: task go:build + if: matrix.os == 'ubuntu-18.04' # build the agent without GUI support (no tray icon) - name: Build the Agent-cli - run: task build-cli - if: matrix.operating-system == 'ubuntu-18.04' + run: task go:build-cli + if: matrix.os == 'ubuntu-18.04' # the manifest is required by windows GUI apps, otherwise the binary will crash with: "Unable to create main window: TTM_ADDTOOL failed" (for reference https://github.com/lxn/walk/issues/28) - # rsrc will produce *.syso files that should get automatically recognized by go build command and linked into an executable. - - name: Embed manifest in win binary - run: | - go get github.com/akavel/rsrc - rsrc -arch 386 -manifest manifest.xml - if: matrix.operating-system == 'windows-2019' + # rsrc will produce a *.syso file that should get automatically recognized by go build command and linked into an executable. + - name: Download tool to embed manifest in win binary + run: go get github.com/akavel/rsrc + if: matrix.os == 'windows-2019' # building the agent for win requires a different task because of an extra flag - name: Build the Agent for win32 env: GOARCH: 386 # 32bit architecture (for support) GO386: 387 # support old instruction sets without MMX (used in the Pentium 4) (will be deprecated in GO > 1.15 https://golang.org/doc/go1.15) - run: task build-win32 - if: matrix.operating-system == 'windows-2019' + run: task go:build-win + if: matrix.os == 'windows-2019' && matrix.arch == '-386' + + - name: Build the Agent for win64 + run: task go:build-win # GOARCH=amd64 by default on the runners + if: matrix.os == 'windows-2019' && matrix.arch == '-amd64' - name: Build the Agent for macos env: - MACOSX_DEPLOYMENT_TARGET: 10.9 # minimum supported version for mac - run: task build - if: matrix.operating-system == 'macos-10.15' + MACOSX_DEPLOYMENT_TARGET: 10.11 # minimum supported version for mac + CGO_CFLAGS: -mmacosx-version-min=10.11 + CGO_LDFLAGS: -mmacosx-version-min=10.11 + run: task go:build + if: matrix.os == 'macos-10.15' + + # this will create `public/` dir with compressed full bin (/-.gz) and a json file + - name: Create autoupdate files + run: go-selfupdate arduino-create-agent${{ matrix.ext }} ${TAG_VERSION} + if: matrix.arch != '-386' && steps.prerelease.outputs.IS_PRE != 'true' + + - name: Create autoupdate files for win32 + run: go-selfupdate -platform windows${{ matrix.arch }} arduino-create-agent${{ matrix.ext }} ${TAG_VERSION} + if: matrix.arch == '-386' && matrix.os == 'windows-2019' && steps.prerelease.outputs.IS_PRE != 'true' + + - name: Upload autoupdate files to Arduino downloads servers + run: | + aws s3 sync public/ s3://${{ secrets.DOWNLOADS_BUCKET }}${{ env.TARGET }} + aws s3 sync public/ s3://${{ secrets.DOWNLOADS_BUCKET }}${{ env.OLD_TARGET }} + if: steps.prerelease.outputs.IS_PRE != 'true' # config.ini is required by the executable when it's run - name: Upload artifacts uses: actions/upload-artifact@v2 with: - name: arduino-create-agent-${{ matrix.operating-system }} + name: arduino-create-agent-${{ matrix.os }}${{ matrix.arch }} path: | arduino-create-agent* config.ini @@ -96,27 +148,21 @@ jobs: # The code-sign-mac-executable job will download the macos artifact from the previous job, sign e notarize the binary and re-upload it. code-sign-mac-executable: needs: build - runs-on: macos-10.15 - env: - RUNS_ON: macos-10.15 # used to parametrize filenames + strategy: + matrix: # to allow support for future architectures + os: [macos-10.15] + arch: [-amd64] - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - repository: 'bcmi-labs/arduino-create-agent-installer' # the repo which contains gon.config.hcl - token: ${{ secrets.ARDUINO_CREATE_AGENT_CI_PAT }} + runs-on: ${{ matrix.os }} + steps: - name: Download artifact uses: actions/download-artifact@v2 with: - name: arduino-create-agent-${{ env.RUNS_ON }} - path: arduino-create-agent-${{ env.RUNS_ON }} + name: arduino-create-agent-${{ matrix.os }}${{ matrix.arch }} + path: arduino-create-agent - name: Import Code-Signing Certificates - env: - KEYCHAIN: "sign.keychain" - INSTALLER_CERT_MAC_PATH: "/tmp/ArduinoCerts2020.p12" run: | echo "${{ secrets.INSTALLER_CERT_MAC_P12 }}" | base64 --decode > ${{ env.INSTALLER_CERT_MAC_PATH }} security create-keychain -p ${{ secrets.KEYCHAIN_PASSWORD }} ${{ env.KEYCHAIN }} @@ -130,22 +176,36 @@ jobs: wget -q https://github.com/mitchellh/gon/releases/download/v0.2.3/gon_macos.zip unzip gon_macos.zip -d /usr/local/bin + - name: Write gon config to file + # gon does not allow env variables in config file (https://github.com/mitchellh/gon/issues/20) + run: | + cat > gon.config.hcl <> $GITHUB_ENV - - - name: Set installer env vars - run: | - echo INSTALLER_VARS="project.outputDirectory=$PWD project.version=${VERSION%.*} workspace=$PWD realname=Arduino_Create_Bridge" >> $GITHUB_ENV - - name: Checkout uses: actions/checkout@v2 with: @@ -213,92 +269,109 @@ jobs: - name: Download artifact uses: actions/download-artifact@v2 with: - name: arduino-create-agent-${{ matrix.operating-system }} + name: arduino-create-agent-${{ matrix.os }}${{ matrix.arch }} path: ${{ matrix.executable-path }} # path expected by installbuilder # zip artifacts do not mantain executable permission - name: Make executable run: chmod -v +x ${{ matrix.executable-path }}arduino-create-agent* - if: matrix.operating-system == 'ubuntu-18.04' || matrix.operating-system == 'macos-10.15' + if: matrix.os == 'ubuntu-18.04' || matrix.os == 'macos-10.15' + + - name: Rename executable to Arduino_Create_Agent + run: mv -v ${{ matrix.executable-path }}arduino-create-agent${{ matrix.extension }} ${{ matrix.executable-path }}Arduino_Create_Agent${{ matrix.extension }} + + - name: Rename executable to Arduino_Create_Agent_cli + run: mv -v ${{ matrix.executable-path }}arduino-create-agent_cli${{ matrix.extension }} ${{ matrix.executable-path }}Arduino_Create_Agent_cli${{ matrix.extension }} + if: matrix.os == 'ubuntu-18.04' + + - name: get year + run: echo "YEAR=$(date "+%Y")" >> $GITHUB_ENV + if: matrix.os == 'macos-10.15' - - name: Rename executable to Arduino_Create_Bridge - run: mv -v ${{ matrix.executable-path }}arduino-create-agent${{ matrix.extension }} ${{ matrix.executable-path }}Arduino_Create_Bridge${{ matrix.extension }} + - name: Generate Info.plist for MacOS + run: | + cat > skel/ArduinoCreateAgent.app/Contents/Info.plist <CFBundlePackageTypeAPPLCFBundleInfoDictionaryVersion6.0 + + CFBundleIconFile AppIcon.icns + + CFBundleName Arduino Create Agent + CFBundleExecutable Arduino_Create_Agent + CFBundleIdentifier create.arduino.cc - - name: Rename executable to Arduino_Create_Bridge_cli - run: mv -v ${{ matrix.executable-path }}arduino-create-agent_cli${{ matrix.extension }} ${{ matrix.executable-path }}Arduino_Create_Bridge_cli${{ matrix.extension }} - if: matrix.operating-system == 'ubuntu-18.04' + CFBundleVersion ${GITHUB_REF##*/} + NSHumanReadableCopyright Β© Copyright ${{ env.YEAR }} Arduino LLC + CFBundleShortVersionString ${GITHUB_REF##*/} + LSUIElement + + NSPrincipalClassNSApplication + NSMainNibFileMainMenu + + + EOF + if: matrix.os == 'macos-10.15' - name: Save InstallBuilder license to file run: echo "${{ secrets.INSTALLER_LICENSE }}" > /tmp/license.xml - name: Save Win signing certificate to file run: echo "${{ secrets.INSTALLER_CERT_WINDOWS_PFX }}" | base64 --decode > ${{ env.INSTALLER_CERT_WINDOWS_PFX}} - if: matrix.operating-system == 'windows-2019' + if: matrix.os == 'windows-2019' - name: Save macos signing certificate to file run: echo "${{ secrets.INSTALLER_CERT_MAC_P12 }}" | base64 --decode > ${{ env.INSTALLER_CERT_MAC_P12 }} - if: matrix.operating-system == 'macos-10.15' + if: matrix.os == 'macos-10.15' # win(edge),mac(safari) -> CERT_INSTALL and win,mac:(ff,chrome) -> CHOICE_CERT_INSTALL # installbuilder reads the env vars with certs paths and use it to sign the installer. - name: Launch Bitrock installbuilder-20 with CERT_INSTALL && CHOICE_CERT_INSTALL run: | - ${{ env.INSTALLBUILDER_PATH }} build installer.xml ${{ matrix.install-builder-name }} --verbose --license /tmp/license.xml --setvars ${INSTALLER_VARS} ${{ env.CERT_INSTALL }} - mv -v ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-CI${{matrix.installer-extension}} ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-${{matrix.browser}}${{matrix.installer-extension}} - ${{ env.INSTALLBUILDER_PATH }} build installer.xml ${{ matrix.install-builder-name }} --verbose --license /tmp/license.xml --setvars ${INSTALLER_VARS} ${{ env.CHOICE_CERT_INSTALL }} - cp -vr ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-CC${{matrix.installer-extension}} ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-chrome${{matrix.installer-extension}} - mv -v ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-CC${{matrix.installer-extension}} ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-firefox${{matrix.installer-extension}} - rm -r ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-C* - if: matrix.operating-system == 'windows-2019' || matrix.operating-system == 'macos-10.15' + ${{ env.INSTALLBUILDER_PATH }} build installer.xml ${{ matrix.install-builder-name }} --verbose --license /tmp/license.xml --setvars ${{ env.INSTALLER_VARS }} ${{ env.CERT_INSTALL }} + mv -v ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-CI${{matrix.installer-extension}} ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}${{ matrix.arch }}-installer-${{matrix.browser}}${{matrix.installer-extension}} + ${{ env.INSTALLBUILDER_PATH }} build installer.xml ${{ matrix.install-builder-name }} --verbose --license /tmp/license.xml --setvars ${{ env.INSTALLER_VARS }} ${{ env.CHOICE_CERT_INSTALL }} + cp -vr ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-CC${{matrix.installer-extension}} ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}${{ matrix.arch }}-installer-chrome${{matrix.installer-extension}} + mv -v ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-CC${{matrix.installer-extension}} ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}${{ matrix.arch }}-installer-firefox${{matrix.installer-extension}} + rm -r ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-C* + if: matrix.os == 'windows-2019' || matrix.os == 'macos-10.15' # linux - name: Launch Bitrock installbuilder-20 with NO_CERT_INSTALL run: | - ${{ env.INSTALLBUILDER_PATH }} build installer.xml ${{ matrix.install-builder-name }} --verbose --license /tmp/license.xml --setvars ${INSTALLER_VARS} ${{ env.NO_CERT_INSTALL }} - cp -v ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-CS.run ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-chrome.run - mv -v ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-CS.run ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-firefox.run - cp -v ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-CS.tar.gz ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-chrome.tar.gz - mv -v ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-CS.tar.gz ArduinoCreateAgent-${VERSION%.*}-${{ matrix.install-builder-name }}-installer-firefox.tar.gz - if: matrix.operating-system == 'ubuntu-18.04' + ${{ env.INSTALLBUILDER_PATH }} build installer.xml linux-x64 --verbose --license /tmp/license.xml --setvars ${{ env.INSTALLER_VARS }} ${{ env.NO_CERT_INSTALL }} + cp -v ArduinoCreateAgent-${GITHUB_REF##*/}-linux-x64-installer-CS.run ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}${{ matrix.arch }}-installer-chrome.run + mv -v ArduinoCreateAgent-${GITHUB_REF##*/}-linux-x64-installer-CS.run ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}${{ matrix.arch }}-installer-firefox.run + cp -v ArduinoCreateAgent-${GITHUB_REF##*/}-linux-x64-installer-CS.tar.gz ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}${{ matrix.arch }}-installer-chrome.tar.gz + mv -v ArduinoCreateAgent-${GITHUB_REF##*/}-linux-x64-installer-CS.tar.gz ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}${{ matrix.arch }}-installer-firefox.tar.gz + if: matrix.os == 'ubuntu-18.04' - name: Upload artifacts uses: actions/upload-artifact@v2 with: - name: ArduinoCreateAgent-${{ matrix.install-builder-name }} + name: ArduinoCreateAgent-${{ matrix.install-builder-name }}${{ matrix.arch }} path: ArduinoCreateAgent* if-no-files-found: error # This job will sign and notarize mac installers code-sign-mac-installers: needs: package - runs-on: macos-10.15 - strategy: matrix: browser: [safari, firefox, chrome] + arch: [-amd64] + runs-on: macos-10.15 steps: - - name: Download artifact uses: actions/download-artifact@v2 with: - name: ArduinoCreateAgent-osx + name: ArduinoCreateAgent-osx${{ matrix.arch }} path: ArduinoCreateAgent-osx - # workaround to strip bugfix number from semver (only to make 1.1 release) I will change this in the future - - name: Set version env vars - # VERSION will be available only in the next step - run: | - echo "VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV - # zip artifacts do not mantain executable permission - name: Make executable - run: chmod -v +x ArduinoCreateAgent-osx/ArduinoCreateAgent-${VERSION%.*}-osx-installer-${{ matrix.browser }}.app/Contents/MacOS/* + run: chmod -v +x ArduinoCreateAgent-osx/ArduinoCreateAgent-${GITHUB_REF##*/}-osx${{ matrix.arch }}-installer-${{ matrix.browser }}.app/Contents/MacOS/* - name: Import Code-Signing Certificates - env: - KEYCHAIN: "sign.keychain" - INSTALLER_CERT_MAC_PATH: "/tmp/ArduinoCerts2020.p12" run: | echo "${{ secrets.INSTALLER_CERT_MAC_P12 }}" | base64 --decode > ${{ env.INSTALLER_CERT_MAC_PATH }} security create-keychain -p ${{ secrets.KEYCHAIN_PASSWORD }} ${{ env.KEYCHAIN }} @@ -316,7 +389,7 @@ jobs: # gon does not allow env variables in config file (https://github.com/mitchellh/gon/issues/20) run: | cat > gon.config_installer.hcl </tmp/semver && chmod +x /tmp/semver if [[ $(/tmp/semver get prerel ${GITHUB_REF/refs\/tags\//}) ]]; then echo "::set-output name=IS_PRE::true"; fi @@ -374,11 +444,45 @@ jobs: - name: prepare artifacts for the release run: | mkdir release - chmod -v +x ArduinoCreateAgent-linux-x64/*.run - mv -v ArduinoCreateAgent-linux-x64/* release/ - cat ArduinoCreateAgent-osx/*.tar | tar -xvf - -i -C release/ + chmod -v +x ArduinoCreateAgent-linux-amd64/*.run + mv -v ArduinoCreateAgent-linux-amd64/* release/ + cat ArduinoCreateAgent-osx-amd64/*.tar | tar -xvf - -i -C release/ rm -v release/._ArduinoCreateAgent*.dmg - mv -v ArduinoCreateAgent-windows/* release/ + mv -v ArduinoCreateAgent-windows*/* release/ + + - name: VirusTotal Scan + id: virustotal_step + uses: crazy-max/ghaction-virustotal@v2 + with: + vt_api_key: ${{ secrets.VIRUSTOTAL_API_KEY }} + update_release_body: false # `true` won't work because trigger type is not release + files: | + release/*.exe + arduino-create-agent-windows-2019-386/arduino-create-agent.exe + arduino-create-agent-windows-2019-amd64/arduino-create-agent.exe + + - name: Create changelog + uses: arduino/create-changelog@v1 + with: + tag-regex: '^[0-9]+\.[0-9]+\.[0-9]+.*$' + filter-regex: '^\[(skip|changelog)[ ,-](skip|changelog)\].*' + case-insensitive-regex: true + changelog-file-path: "CHANGELOG.md" + + - name: Organize release body message #use sed to clean and format the output markdown style + id: release_body + run: | + body=$(cat CHANGELOG.md) + body="${body//'%'/'%25'}" + body="${body//$'\n'/'%0A'}" + body="${body//$'\r'/'%0D'}" + vt_title_pre="
\nVirusTotal analysis πŸ›‘\n\n" + vt_links="$(echo ${{ steps.virustotal_step.outputs.analysis}} | sed 's/release\///g' | sed 's/,/\n/g' | sed 's/^/- [/' | sed 's/=/](/' | sed 's/$/)/')" + vt_title_post="\n
" + vt_title_pre="${vt_title_pre//'\n'/'%0A'}" + vt_links="${vt_links//$'\n'/'%0A'}" # replace \n with a special character -> generates a single lines, \n will be reintroduced later + vt_title_post="${vt_title_post//'\n'/'%0A'}" + echo "::set-output name=RBODY::$body'%0A'$vt_title_pre$vt_links$vt_title_post" - name: Create Github Release uses: actions/create-release@v1 @@ -387,7 +491,7 @@ jobs: with: tag_name: ${{ github.ref }} release_name: ${{ github.ref }} - body: "" + body: ${{ steps.release_body.outputs.RBODY}} draft: false prerelease: ${{ steps.prerelease.outputs.IS_PRE }} @@ -400,5 +504,11 @@ jobs: file: release/* - name: Upload release files on Arduino downloads servers - run: aws s3 sync release/ s3://${{ secrets.DOWNLOADS_BUCKET }}${{ env.PLUGIN_TARGET }} --include "*" + run: aws s3 sync release/ s3://${{ secrets.DOWNLOADS_BUCKET }}${{ env.TARGET }} + if: steps.prerelease.outputs.IS_PRE != 'true' + + - name: Update version file (used by frontend to trigger autoupdate and create filename) + run: | + echo {\"Version\": \"${GITHUB_REF##*/}\"} > /tmp/agent-version.json + aws s3 cp /tmp/agent-version.json s3://${{ env.VERSION_TARGET }} if: steps.prerelease.outputs.IS_PRE != 'true' diff --git a/.github/workflows/test-go-integration-task.yml b/.github/workflows/test-go-integration-task.yml new file mode 100644 index 000000000..9502a756b --- /dev/null +++ b/.github/workflows/test-go-integration-task.yml @@ -0,0 +1,106 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/test-go-integration-task.md +name: Test Integration + +env: + # See: https://github.com/actions/setup-go/tree/v2#readme + GO_VERSION: "1.14" + # See: https://github.com/actions/setup-python/tree/v2#available-versions-of-python + PYTHON_VERSION: "3.9" + +# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows +on: + create: + push: + paths: + - ".github/workflows/test-go-integration-task.ya?ml" + - "Taskfile.ya?ml" + - "**.go" + - "go.mod" + - "go.sum" + - "poetry.lock" + - "pyproject.toml" + - "tests/**" + pull_request: + paths: + - ".github/workflows/test-go-integration-task.ya?ml" + - "Taskfile.ya?ml" + - "**.go" + - "go.mod" + - "go.sum" + - "poetry.lock" + - "pyproject.toml" + - "tests/**" + workflow_dispatch: + repository_dispatch: + +jobs: + run-determination: + runs-on: ubuntu-latest + outputs: + result: ${{ steps.determination.outputs.result }} + steps: + - name: Determine if the rest of the workflow should run + id: determination + run: | + RELEASE_BRANCH_REGEX="refs/heads/[0-9]+.[0-9]+.x" + # The `create` event trigger doesn't support `branches` filters, so it's necessary to use Bash instead. + if [[ \ + "${{ github.event_name }}" != "create" || \ + "${{ github.ref }}" =~ $RELEASE_BRANCH_REGEX \ + ]]; then + # Run the other jobs. + RESULT="true" + else + # There is no need to run the other jobs. + RESULT="false" + fi + + echo "::set-output name=result::$RESULT" + + test: + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + + strategy: + matrix: + operating-system: + - ubuntu-latest + - windows-latest + - macos-latest + + runs-on: ${{ matrix.operating-system }} + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install Python + uses: actions/setup-python@v2 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install Poetry + run: pip install poetry + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + # build the agent without GUI support (no tray icon) for integration testing + - name: Build the Agent-cli + run: task go:build-cli + if: matrix.operating-system != 'windows-latest' + + - name: Build the Agent-cli for win + run: task go:build-win-cli + if: matrix.operating-system == 'windows-latest' + + - name: Run integration tests + run: task go:test-integration diff --git a/.github/workflows/test-go-task.yml b/.github/workflows/test-go-task.yml new file mode 100644 index 000000000..c88772d36 --- /dev/null +++ b/.github/workflows/test-go-task.yml @@ -0,0 +1,110 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/test-go-task.md +name: Test Go + +env: + # See: https://github.com/actions/setup-go/tree/v2#readme + GO_VERSION: "1.14" + +# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows +on: + create: + push: + paths: + - ".github/workflows/test-go-task.ya?ml" + - "codecov.ya?ml" + - "**/go.mod" + - "**/go.sum" + - "Taskfile.ya?ml" + - "**.go" + - "**/testdata/**" + pull_request: + paths: + - ".github/workflows/test-go-task.ya?ml" + - "codecov.ya?ml" + - "**/go.mod" + - "**/go.sum" + - "Taskfile.ya?ml" + - "**.go" + - "**/testdata/**" + workflow_dispatch: + repository_dispatch: + +jobs: + run-determination: + runs-on: ubuntu-latest + outputs: + result: ${{ steps.determination.outputs.result }} + steps: + - name: Determine if the rest of the workflow should run + id: determination + run: | + RELEASE_BRANCH_REGEX="refs/heads/[0-9]+.[0-9]+.x" + # The `create` event trigger doesn't support `branches` filters, so it's necessary to use Bash instead. + if [[ \ + "${{ github.event_name }}" != "create" || \ + "${{ github.ref }}" =~ $RELEASE_BRANCH_REGEX \ + ]]; then + # Run the other jobs. + RESULT="true" + else + # There is no need to run the other jobs. + RESULT="false" + fi + + echo "::set-output name=result::$RESULT" + + test: + name: test (${{ matrix.module.path }} - ${{ matrix.operating-system }}) + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + + strategy: + fail-fast: false + + matrix: + operating-system: + - ubuntu-latest + - windows-latest + - macos-latest + module: + - path: ./ + codecov-flags: unit + + runs-on: ${{ matrix.operating-system }} + + steps: + # By default, actions/checkout converts the repo's LF line endings to CRLF on the Windows runner. + - name: Disable EOL conversions + run: git config --global core.autocrlf false + + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + # https://github.com/getlantern/systray#linux + - name: Install Dependencies (Linux) + run: sudo apt update && sudo apt install -y --no-install-recommends build-essential libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev + if: matrix.operating-system == 'ubuntu-latest' + + - name: Run tests + env: + GO_MODULE_PATH: ${{ matrix.module.path }} + run: task go:test + + - name: Send unit tests coverage to Codecov + if: runner.os == 'Linux' + uses: codecov/codecov-action@v2 + with: + file: ${{ matrix.module.path }}coverage_unit.txt + flags: ${{ matrix.module.codecov-flags }} + fail_ci_if_error: ${{ github.repository == 'arduino/arduino-create-agent' }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 4d711e6e7..000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: test - -on: - pull_request: - -jobs: - test-matrix: - strategy: - matrix: - operating-system: [ubuntu-18.04, windows-2019, macos-10.15] - - runs-on: ${{ matrix.operating-system }} - - steps: - - name: Disable EOL conversions - run: git config --global core.autocrlf false - - - name: Checkout - uses: actions/checkout@v2 - - - name: Install Go - uses: actions/setup-go@v2 - with: - go-version: "1.15" - - # dependencies used for compiling the GUI - - name: Install Dependencies (Linux) - run: sudo apt update && sudo apt install -y --no-install-recommends build-essential libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev - if: matrix.operating-system == 'ubuntu-18.04' - - - name: Install Go deps - # Since 10/23/2019 pwsh is the default shell - # on Windows, but pwsh fails to install protoc-gen-go so - # we force bash as default shell for all OSes in this task - run: | - go get github.com/golangci/govet - go get golang.org/x/lint/golint - shell: bash - - - name: Install Taskfile - uses: arduino/actions/setup-taskfile@master - with: - version: '3.x' - repo-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Check the code is good - run: task check - - - name: Run unit tests - run: task test-unit - - - name: Build the Agent - run: task build - if: matrix.operating-system != 'windows-2019' - - # build the agent without GUI support (no tray icon) - - name: Build the Agent-cli - run: task build-cli - if: matrix.operating-system == 'ubuntu-18.04' - - # the manifest is required by windows GUI apps, otherwise the binary will crash with: "Unable to create main window: TTM_ADDTOOL failed" (for reference https://github.com/lxn/walk/issues/28) - # rsrc will produce *.syso files that should get automatically recognized by go build command and linked into an executable. - - name: Embed manifest in win binary - run: | - go get github.com/akavel/rsrc - rsrc -arch 386 -manifest manifest.xml - if: matrix.operating-system == 'windows-2019' - - # building the agent for win requires a different task because of an extra flag - - name: Build the Agent for win32 - env: - GOARCH: 386 # 32bit architecture (for support) - GO386: 387 # support old instruction sets without MMX (used in the Pentium 4) (will be deprecated in GO > 1.15 https://golang.org/doc/go1.15) - run: task build-win32 - if: matrix.operating-system == 'windows-2019' diff --git a/.gitignore b/.gitignore index cd1c063ca..ea46fe4ee 100644 --- a/.gitignore +++ b/.gitignore @@ -7,9 +7,14 @@ rsrc.syso snapshot/* public/ artifacts* +logs/ # IDEs config .idea +.vscode # macOS .DS_Store + +# Python +__pycache__ diff --git a/README.md b/README.md index c7ac2fc82..73369ec7d 100644 --- a/README.md +++ b/README.md @@ -1,455 +1,49 @@ [![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-blue.svg)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) +[![Test Go status](https://github.com/arduino/arduino-create-agent/actions/workflows/test-go-task.yml/badge.svg)](https://github.com/arduino/arduino-create-agent/actions/workflows/test-go-task.yml) +[![Codecov](https://codecov.io/gh/arduino/arduino-create-agent/branch/main/graph/badge.svg)](https://codecov.io/gh/arduino/arduino-create-agent) +[![Test Integration status](https://github.com/arduino/arduino-create-agent/actions/workflows/test-go-integration-task.yml/badge.svg)](https://github.com/arduino/arduino-create-agent/actions/workflows/test-go-integration-task.yml) arduino-create-agent ==================== +The Arduino Create Agent is a single binary that will sit on the traybar and work in the background. It allows you to use the [Arduino Create applications](https://create.arduino.cc) to seamlessly upload code to any USB connected Arduino board (or YΓΊn in LAN) directly from the browser. -## GOA 2 refactoring -The agent is currently transitioning to the v2 of the GOA framework for API management, please refer to the following -[documentation](https://github.com/goadesign/goa/tree/v2) in order to install tools and libraries - - -i.e. to regenerate code from design use: -```bash -goa gen github.com/arduino/arduino-create-agent/design -``` - -## Installation -Get the latest version of the Agent for all supported platforms: - -### Windows -* [Windows with Edge](https://downloads.arduino.cc/CreateBridgeStable/ArduinoCreateAgent-1.1-windows-installer-edge.exe) -* [Windows with Chrome](https://downloads.arduino.cc/CreateBridgeStable/ArduinoCreateAgent-1.1-windows-installer-chrome.exe) -* [Windows with Firefox](https://downloads.arduino.cc/CreateBridgeStable/ArduinoCreateAgent-1.1-windows-installer-firefox.exe) - -### MacOSX -* [MacOSX with Safari](https://downloads.arduino.cc/CreateBridgeStable/ArduinoCreateAgent-1.1-osx-installer-safari.dmg) -* [MacOSX with Chrome](https://downloads.arduino.cc/CreateBridgeStable/ArduinoCreateAgent-1.1-osx-installer-chrome.dmg) -* [MacOSX with Firefox](https://downloads.arduino.cc/CreateBridgeStable/ArduinoCreateAgent-1.1-osx-installer-firefox.dmg) - -### Linux -* [Linux x64 with Chrome](https://downloads.arduino.cc/CreateBridgeStable/ArduinoCreateAgent-1.1-linux-x64-installer-chrome.tar.gz) -* [Linux x64 with Firefox](https://downloads.arduino.cc/CreateBridgeStable/ArduinoCreateAgent-1.1-linux-x64-installer-firefox.tar.gz) - -arduino-create-agent is a fork of @[johnlauer](https://github.com/johnlauer)'s [serial-port-json-server](https://github.com/johnlauer/serial-port-json-server) (which we really want to thank for his kindness and great work) - -The history has been rewritten to keep the repo small (thus removing all binaries committed in the past) - - - -## Using multiple configurations - -The agent supports multiple configuration files. When multiple configurations are found by the agent, the tray icon menu is expanded to contain the different configurations: - -![Agent multiple configuration tray icon](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/linux/tray-icon-multiple-profiles.png) - -The default `config.ini` file contains common configurations, every other config file inherit from it. - -To create multiple configuration files: -- stop the agent: tray bar icon -> pause then tray bar icon -> kill -- find the `config.ini` file that is present in the `arduino-create-agent` installation folder -- copy `config.ini` or create a new ini file (e.g. `example.ini`) with content: - ```ini - name = your configuration name - ``` - add in this file other configuration options (you can override inherited values from `config.ini`) -- restart the agent -- click the tray bar icon and select the new configuration - -**Tip**: you can also use the multiple configurations feature to create a new configuration with the proxy settings. This way you can have multiple proxies configured and disable proxy configuration with ease. - -## When behind a proxy - -The agent supports working behind a proxy, but manual configuration is required (there is no support for automatic proxy discovery). - -To add proxy configuration: -- stop the agent: tray bar icon -> pause then tray bar icon -> kill -- find the `config.ini` file that is present in the `arduino-create-agent` installation folder -- copy `config.ini` to a new file (e.g. `proxy.ini`) with content: - ```ini - name = Proxy Enabled - [env] - http_proxy=your.proxy.here - https_proxy=your.https.proxyhere - ``` -- please note spaces are not allowed before and after the string `http_proxy` -- restart the agent -- select the proper Proxy profile as in the image -- your agent will now work behind a proxy - -![Agent multiple configuration tray icon](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/linux/tray-icon-multiple-profiles.png) - - -## Disable Autostart - -### Windows -1. Type "Task Manager in the Windows Search Bar" - -![Type "Task Manager in the Windows Search Bar"](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/windows/01.png) -2. Select the Startup tab - -![Select the Startup tab](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/windows/02.png) -3. Select the autostart file - -![Select the autostart file](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/windows/03.png) -4. Disable it - -![Disable it](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/windows/04.png) - -### Mac OSX -1. Open Finder, click on Go menu, select 'Go to Folder' - -![Open Finder, click on Go menu, select 'Go to Folder'](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/mac/01.png) -2. Type the directory containing the autolauncher file, change with your Mac username, by default the directory is /Users/username/Library/LaunchAgents - -![Type the directory containing the autolauncher file, change with your Mac username, by default the directory is /Users/username/Library/LaunchAgents](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/mac/02.png) -3. Select the ArduinoCreateAgent.plist file - -![Select the ArduinoCreateAgent.plist file](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/mac/03.png) -4. Right click on the file name and select 'Move to Trash' - -![Right click on the file name and select 'Move to Trash'](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/mac/04.png) - ---- -The command line way: -``` -$ launchctl unload ~/Library/LaunchAgents/ArduinoCreateAgent.plist -``` - -### Linux -1. Show hidden files - -![Show hidden files](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/linux/01.png) -2. Select the .config dir in your home - -![Select the .config dir in your home](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/linux/02.png) -3. Select the autostart dir - -![Select the autostart dir](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/linux/03.png) -4. Move the file to the trash - -![Move the file to the trash](https://raw.githubusercontent.com/arduino/arduino-create-agent/devel/images/linux/04.png) - ---- -The command line way: - -Just remove the autostart file in your desktop manager, in Ubuntu is: -``` -$ rm $HOME/.config/autostart/arduino-create-agent.desktop -``` -To start manually the agent you can open the file at: -``` -$ nohup $HOME/ArduinoCreateAgent-1.1/Arduino_Create_Bridge & -``` -or in the location selected during the installation - -# Contributing - -Please use the current latest version: - -### Windows -* [Windows with Edge dev](https://downloads.arduino.cc/CreateBridge/staging/ArduinoCreateAgent-1.0-windows-installer-edge.exe) -* [Windows with Chrome dev](https://downloads.arduino.cc/CreateBridge/staging/ArduinoCreateAgent-1.0-windows-installer.exe) -* [Windows with Firefox dev](https://downloads.arduino.cc/CreateBridge/staging/ArduinoCreateAgent-1.0-windows-installer-firefox.exe) - -### MacOSX -* [MacOSX with Safari dev](https://downloads.arduino.cc/CreateBridge/staging/ArduinoCreateAgent-1.0-osx-installer-safari.dmg) -* [MacOSX with Chrome dev](https://downloads.arduino.cc/CreateBridge/staging/ArduinoCreateAgent-1.0-osx-installer-chrome.dmg) -* [MacOSX with Firefox dev](https://downloads.arduino.cc/CreateBridge/staging/ArduinoCreateAgent-1.0-osx-installer-firefox.dmg) - -### Linux -* [Linux x64 with Chrome dev](https://downloads.arduino.cc/CreateBridge/staging/ArduinoCreateAgent-1.0-linux-x64-installer-chrome.run) -* [Linux x64 with Firefox dev](https://downloads.arduino.cc/CreateBridge/staging/ArduinoCreateAgent-1.0-linux-x64-installer-firefox.run) - - -## How to use it -The arduino create agent is a single binary that reads from a configuration file. Upon launching it will sit on the traybar and work in the background. - -It will listen to http and websocket connections on a range of ports from `8990` to `9000`. - -### Discover the port -You should make GET request to the `/info` endpoint on the possible ports, until you find a reply: - - $ curl http://127.0.0.1:8990/info - curl: (7) Failed to connect to 127.0.0.1 port 8990: Connection refused - $ curl http://127.0.0.1:8991/info -  - $ curl http://127.0.0.1:8992/info - {"http":"http://127.0.0.1:8992","https":"https://127.0.0.1:8991","version":"1.0.36","ws":"ws://127.0.0.1:8992","wss":"wss://127.0.0.1:8991"} - -The reply will contain a json with info about the version and the http and https endpoints to use - -### Open a websocket -Most of the commands can be performed with websocket instructions. We use a library called [socket.io](https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js) to handle the messages. -Once you have the websocket endpoint you need you can: - -```javascript -var socket = io(endpoint); -socket.on('connect', function () { - socket.emit('command', yourCommand); - - socket.on('command', function () { - // Your code to handle messages - }) -} -``` - -### Use the debug console -By clicking on the tray icon and going to the debug console you can try most of the websocket commands. The first command you should type in is: - - log on - -### List the boards -To get a json list of the connected boards you can issue the command: - - list - -You will receive an object of all the boards connected with USB or over the network: - -```json -{ - "Ports":[ - { - "Name":"/dev/ttyACM0", - "SerialNumber":"", - "DeviceClass":"", - "IsOpen":false, - "IsPrimary":false, - "Baud":0, - "BufferAlgorithm":"", - "Ver":"1.0.36", - "NetworkPort":false, - "VendorID":"0x2341", - "ProductID":"0x8036" - } - ], - "Network":false -}{ - "Ports":[ - { - "Name":"192.168.1.101", - "SerialNumber":"", - "DeviceClass":"", - "IsOpen":false, - "IsPrimary":false, - "Baud":0, - "BufferAlgorithm":"", - "Ver":"1.0.36", - "NetworkPort":true, - "VendorID":"board=Arduino Y\\195\\186n Shield distro_version=0.1", - "ProductID":"Shield" - } - ], - "Network":true -} -``` - -### Open/Close ports - -To read input from a board connected to USB you must first open the port with the command - - open /dev/ttyACM0 9600 - -where you should replace /dev/ttyACM0 with the actual port and 9600 with the baud. - -You will receive a message like: - -```json -{ - "Cmd":"Open", - "Desc":"Got register/open on port.", - "Port":"/dev/ttyACM0", - "IsPrimary":true, - "Baud":9600, - "BufferType":"" -} -``` - -or - -```json -{ - "Cmd":"OpenFail", - "Desc":"Error opening port. Serial port busy", - "Port":"/dev/ttyACM0", - "Baud":9600 -} -``` - -You can then close the port with - - close /dev/ttyACM0 - -You will receive a message like: - -```json -{ - "Cmd":"Close", - "Desc":"Got unregister/close on port.", - "Port":"/dev/ttyACM0", - "Baud":9600 -} -``` - -or - - -```json -{ - "Error":"We could not find the serial port /dev/ttyACM0 that you were trying to close." -} -``` - -### Receiving and sending data - -While a port is open you can send input with - - send /dev/ttyACM0 hello - -with a reply like - -```json -{"Cmd":"Queued","QCnt":1,"Ids":[""],"D":["hello"],"Port":"/dev/ttyACM0"} -{"Cmd":"Write","QCnt":0,"Id":"","P":"/dev/ttyACM0"} -{"Cmd":"CompleteFake","Id":"","P":"/dev/ttyACM0"} +## Architecture ``` - -You can receive output from the serial port by listening to messages like this: - -```json -{ - "D":"output string\r\n" -} -``` - -### Download a tool -You can download a tool on the computer with a command like - - downloadtool avrdude 6.0.1-arduino5 replace - -receiving a reply like - -```json -{ - "DownloadStatus": "Success", - "Msg":"Map Updated" -} ++-------------------------------+ +| | +| Browser | +| | Web socket +----------------------+ flashes +---------------+ +| +---------------------------+ |<-------------->| +------------>| | +| | | | | Arduino Create Agent | | Arduino Board | +| | Arduino Create Web Editor | +--------------->| |<------------+ | +| | | | REST API +----------------------+ serial +---------------+ +| +---------------------------+ | ++-------------------------------+ ``` -The syntax of the command is: - - downloadtool {{name}} {{version}} {{behaviour}} - -where `version` can be a version number of the string "latest", and `behaviour` can be -"keep" (which skips the download if the tool already exists) and "replace" (which will download it again). - -### Upload -You can upload a binary sketch to a board connected to a port with a POST request to be made at the http endpoint. - -The payload is a json object that looks like this: - -```json -{ - "board":"arduino:avr:leonardo", - "port":"/dev/ttyACM1", - "commandline":"\"{runtime.tools.avrdude.path}/bin/avrdude\" \"-C{runtime.tools.avrdude.path}/etc/avrdude.conf\" -v -patmega32u4 -cavr109 -P{serial.port} -b57600 -D \"-Uflash:w:{build.path}/{build.project_name}.hex:i\"", - "signature":"97db97ced2c", - "hex":"OjEwMDAwMDAwMEM5NEU1MDAwQzk0MEQwMTBDOTQwRDAxMEM5NDBEMDE2MQ0KOjEwMDAxMDAwMEM5NDBEMDEwQzk0M", - "filename":"Blink.ino.hex", - "extrafiles": [], - "extra":{ - "auth":{ - "username":null, - "password":null, - "private_key":null, - "port":null - }, - "wait_for_upload_port":true, - "use_1200bps_touch":true, - "network":false, - } -} -``` - -- commandline is the command to execute to perform the upload. This is, for example, avrdude on a Leonardo. - -- hex contains the sketch binary encoded in base64 (could decode in Intel hex or raw binary) - -- signature is the signature of the commandline signed with the private key that matches the public key contained in the config.ini of the arduino-create-agent - -The results of the upload will be delivered via websocket with messages that look like: - -```json -{"Msg":"avrdude: verifying ...","ProgrammerStatus":"Busy"} -{"Msg":"avrdude done. Thank you.","ProgrammerStatus":"Busy"} -{"Flash":"Ok","ProgrammerStatus":"Done"} -``` - -### Javacript client library - -You can install the [arduino-create-agent-js-client](https://github.com/arduino/arduino-create-agent-js-client) in your client application - ---- - -## Development - -Please remember that for compile the project, you need go version >= 1.10.x (older versions are not supported for compile) - -To clone the repository, run the following command: -``` -go get github.com/arduino/arduino-create-agent -``` - -This will clone the repository into your [Go workspace](https://golang.org/doc/code.html#Workspaces) or create a new workspace, if one doesn't exist. You can set `$GOPATH` to define where your Go workspace is located. - -Now you can go to the project directory and compile it: -``` -cd $GOPATH/src/github.com/arduino/arduino-create-agent -go build -``` - -This will create the `arduino-create-agent` binary. - -Other prerequisites are: -* libappindicator (Linux only on Ubuntu `sudo apt-get install libappindicator1 libappindicator3-0.1-cil libappindicator3-0.1-cil-dev libappindicator3-1 libappindicator3-dev libgtk-3-0 libgtk-3-dev`) -* [go-selfupdate] (https://github.com/sanbornm/go-selfupdate) if you want to test automatic updates - -### Windows -Since we are using the https://github.com/lxn/walk library, we need to ship a manifest.xml file, otherwise the error would be: - -``` -panic: Unable to create main window: TTM_ADDTOOL failed -``` - -To do it make sure to install the required tool: - -``` -$ go get github.com/akavel/rsrc -``` - -and build it with - -``` -$ rsrc -arch=386 -manifest=manifest.xml -$ go build -``` - -Keep in mind that the presence of rsrc.syso file will break other builds, for example +## Installation +Get the [latest version](https://github.com/arduino/arduino-create-agent/releases) of the Agent for all supported platforms or complete the [Getting Started](https://create.arduino.cc/getting-started/plugin/welcome). -``` -$ GOOS=linux go build -# github.com/arduino/arduino-create-agent -/usr/lib/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1 -/usr/sbin/ld: i386 architecture of input file `/tmp/go-link-084341451/000000.o' is incompatible with i386:x86-64 output -collect2: error: ld returned 1 exit status -``` +## Apple M1 support +At the moment the new Apple Silicon Macs released in November 2020, like the new [MacBook Pro 13"](https://www.apple.com/macbook-pro-13/), [MacBook Air](https://www.apple.com/macbook-air/) and [Mac mini](https://www.apple.com/mac-mini/) models with the [Apple M1](https://www.apple.com/mac/m1/) chip are currently NOT supported by the Create Agent. -## Submitting an issue +## Documentation +The documentation has been moved to the [wiki](https://github.com/arduino/arduino-create-agent/wiki) page. There you can find: +- [Advanced usage](https://github.com/arduino/arduino-create-agent/wiki/Advanced-usage): explaining how to use multiple configurations and how to use the agent with a proxy. +- [Agent Beta Program](https://github.com/arduino/arduino-create-agent/wiki/Agent-Beta-Program) +- [Developement](https://github.com/arduino/arduino-create-agent/wiki/Developement): containing useful info to help in development +- [Disable Autostart](https://github.com/arduino/arduino-create-agent/wiki/Disable-Autostart) +- [How to compile on Raspberry Pi](https://github.com/arduino/arduino-create-agent/wiki/How-to-compile-on-Raspberry-Pi) +- [How to use crashreport functionality](https://github.com/arduino/arduino-create-agent/wiki/How-to-use-crashreport-functionality) +- [How to use the agent](https://github.com/arduino/arduino-create-agent/wiki/How-to-use-the-agent) -Please attach the output of the commands running at the debug console if useful. +## Contributing +### Submitting an issue -## Submitting a pull request +When submitting a new issue please search for duplicates before creating a new one. Help us by providing useful context and information. Please attach the output of the commands running at the debug console or attach [crash reports](https://github.com/arduino/arduino-create-agent/wiki/How-to-use-crashreport-functionality) if useful. +### Submitting a pull request We are glad you want to contribute with code: that's the best way to help this software. Your contribution is adding or modifying existing behaviour, please always refer to an existing issue or open a new one before contributing. We are trying to use [Test Driven Development](https://en.wikipedia.org/wiki/Test-driven_development) in the near future: please add one or more tests that prove that your contribution is good and is working as expected, it will help us a lot. @@ -460,6 +54,12 @@ Also, for your contribution to be accepted, every one of your commits must be "S By signing off your commits, you agree to the following agreement, also known as [Developer Certificate of Origin](http://developercertificate.org/): it assures everyone that the code you're submitting is yours or that you have rights to submit it. +## Authors and acknowledgment +arduino-create-agent is a fork of @[johnlauer](https://github.com/johnlauer)'s [serial-port-json-server](https://github.com/johnlauer/serial-port-json-server) (which we really want to thank for his kindness and great work) + +The history has been rewritten to keep the repo small (thus removing all binaries committed in the past) + +## License ``` Developer Certificate of Origin Version 1.1 @@ -498,8 +98,3 @@ By making a contribution to this project, I certify that: maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. ``` - - -## Creating a release -Just create a new release on GitHub, and our drone server will build and upload -the compiled binaries for every architecture in a zip file in the release itself. diff --git a/Taskfile.yml b/Taskfile.yml index fed3fdee7..c1f70e5ec 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,31 +1,76 @@ -version: "2" +version: '3' tasks: + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/go-task/Taskfile.yml + go:build: + desc: Build the project, to use a specific version use `task build TAG_VERSION=x.x.x` + dir: "{{.DEFAULT_GO_MODULE_PATH}}" + cmds: + - go build -v -i {{default "" .ADDITIONAL_FLAGS}} -o {{default "arduino-create-agent" .APP_NAME}} -ldflags '-X main.version={{default .TAG_TEST .TAG_VERSION}} -X main.git_revision={{.COMMIT}} {{default "" .WIN_FLAGS}}' + vars: + COMMIT: + sh: git log -n 1 --format=%h + + go:build-cli: + desc: Build the project without tray icon support + cmds: + - task: go:build + vars: + APP_NAME: arduino-create-agent_cli + ADDITIONAL_FLAGS: -tags cli - build: - desc: Build the project + go:build-win: + desc: Build the project for win, to build 32bit `export GOARCH=386` and for 64 bit `export GOARCH=amd64` before `task build-win` cmds: - - go build -v -i {{.LDFLAGS}} + - rsrc -arch {{.GOARCH}} -manifest manifest.xml # GOARCH shoud be either amd64 or 386 + - task: go:build + vars: + APP_NAME: arduino-create-agent.exe + WIN_FLAGS: -H=windowsgui + - rm *.syso # rm file to avoid compilation problems on other platforms - build-cli: - desc: Build the project without tray support + go:build-win-cli: + desc: Build the project fow win without tray icon support cmds: - - go build -v -i -tags cli -o {{.APP_NAME}}_cli {{.LDFLAGS}} + - task: go:build + vars: + APP_NAME: arduino-create-agent_cli.exe + ADDITIONAL_FLAGS: -tags cli - build-win32: - desc: Build the project for win 32 bit + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/test-go-task/Taskfile.yml + go:test: + desc: Run unit tests + dir: "{{default .DEFAULT_GO_MODULE_PATH .GO_MODULE_PATH}}" cmds: - - go build -v -i {{.WIN_LDFLAGS}} + - | + go test \ + -v \ + -short \ + -run '{{default ".*" .GO_TEST_REGEX}}' \ + {{default "-timeout 10m -coverpkg=./... -covermode=atomic" .GO_TEST_FLAGS}} \ + -coverprofile=coverage_unit.txt \ + {{default .DEFAULT_GO_PACKAGES .GO_PACKAGES}} - test: - desc: Run the full testsuite, `legacy` will be skipped + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/test-go-integration-task/Taskfile.yml + go:test-integration: + desc: Run integration tests + deps: + # - task: go:build # we build it in the CI and not in the task because _cli version is required and build procedure is different on win + - task: poetry:install-deps cmds: - - task: test-unit + - poetry run pytest tests - test-unit: - desc: Run unit tests only + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/poetry-task/Taskfile.yml + poetry:install-deps: + desc: Install dependencies managed by Poetry cmds: - - go test -short -run '{{ default ".*" .TEST_REGEX }}' {{ default "-v" .GOFLAGS }} -coverprofile=coverage_unit.txt {{ default .DEFAULT_TARGETS .TARGETS }} {{.TEST_LDFLAGS}} + - poetry install --no-root + + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/poetry-task/Taskfile.yml + poetry:update-deps: + desc: Update all dependencies managed by Poetry to their newest versions + cmds: + - poetry update check: desc: Check fmt and lint @@ -43,38 +88,19 @@ tasks: # - task: python:check # - task: docs:check # - task: config:check - + vars: + TAG_TEST: "0.0.0-dev" + GOARCH: + sh: go env GOARCH # all modules of this project except for "gen/..." module DEFAULT_TARGETS: sh: echo `go list ./... | grep -v 'arduino-create-agent/gen/' | tr '\n' ' '` - # build vars - APP_NAME: arduino-create-agent - WIN_FLAGS: -H=windowsgui - COMMIT: - sh: echo ${TRAVIS_COMMIT:-`git log -n 1 --format=%h`} - TAG: - sh: echo `git describe --tags --abbrev=0` - LDFLAGS: > - -ldflags '-X main.version={{.TAG}} - -X main.git_revision={{.COMMIT}}' - WIN_LDFLAGS: > - -ldflags '-X main.version={{.TAG}} - -X main.git_revision={{.COMMIT}} - {{.WIN_FLAGS}}' - # test vars - GOFLAGS: "-timeout 10m -v -coverpkg=./... -covermode=atomic" - TEST_VERSIONSTRING: "0.0.0-alpha" - TEST_COMMIT: "deadbeef" - TEST_LDFLAGS: > - -ldflags '-X main.version={{.TEST_VERSIONSTRING}} - -X main.git_revision={{.TEST_COMMIT}}' + DEFAULT_GO_MODULE_PATH: ./ + DEFAULT_GO_PACKAGES: + sh: | + echo $(cd {{default .DEFAULT_GO_MODULE_PATH .GO_MODULE_PATH}} && go list ./... | tr '\n' ' ' || echo '"ERROR: Unable to discover Go packages"') # check-lint vars GOLINTBIN: sh: go list -f {{"{{"}}".Target{{"}}"}}" golang.org/x/lint/golint GOLINTFLAGS: "-min_confidence 0.8 -set_exit_status" - # # docs versioning - # DOCS_VERSION: dev - # DOCS_ALIAS: "" - # DOCS_REMOTE: "origin" - PRETTIER: prettier@2.0.5 diff --git a/bufferflow.go b/bufferflow.go index 42ee9e9b4..07d34698b 100644 --- a/bufferflow.go +++ b/bufferflow.go @@ -1,49 +1,7 @@ package main -import ( -//"log" -//"time" -) - -var availableBufferAlgorithms = []string{"default", "timed", "timedraw"} - -type BufferMsg struct { - Cmd string - Port string - TriggeringResponse string - //Desc string - //Desc string -} - type Bufferflow interface { Init() - BlockUntilReady(cmd string, id string) (bool, bool) // implement this method - //JustQueue(cmd string, id string) bool // implement this method - OnIncomingData(data string) // implement this method - ClearOutSemaphore() // implement this method - BreakApartCommands(cmd string) []string // implement this method - Pause() // implement this method - Unpause() // implement this method - SeeIfSpecificCommandsShouldSkipBuffer(cmd string) bool // implement this method - SeeIfSpecificCommandsShouldPauseBuffer(cmd string) bool // implement this method - SeeIfSpecificCommandsShouldUnpauseBuffer(cmd string) bool // implement this method - SeeIfSpecificCommandsShouldWipeBuffer(cmd string) bool // implement this method - SeeIfSpecificCommandsReturnNoResponse(cmd string) bool // implement this method - ReleaseLock() // implement this method - IsBufferGloballySendingBackIncomingData() bool // implement this method - Close() // implement this method -} - -/*data packets returned to client*/ -type DataCmdComplete struct { - Cmd string - Id string - P string - BufSize int `json:"-"` - D string `json:"-"` -} - -type DataPerLine struct { - P string - D string + OnIncomingData(data string) // implement this method + Close() // implement this method } diff --git a/bufferflow_default.go b/bufferflow_default.go index 7f37ac3d2..2d6d6d281 100644 --- a/bufferflow_default.go +++ b/bufferflow_default.go @@ -1,71 +1,52 @@ package main import ( + "encoding/json" + log "github.com/sirupsen/logrus" ) type BufferflowDefault struct { - Name string - Port string + port string + output chan<- []byte + input chan string + done chan bool } -var () +func NewBufferflowDefault(port string, output chan<- []byte) *BufferflowDefault { + return &BufferflowDefault{ + port: port, + output: output, + input: make(chan string), + done: make(chan bool), + } +} func (b *BufferflowDefault) Init() { log.Println("Initting default buffer flow (which means no buffering)") + go b.consumeInput() } -func (b *BufferflowDefault) BlockUntilReady(cmd string, id string) (bool, bool) { - //log.Printf("BlockUntilReady() start\n") - return true, false +func (b *BufferflowDefault) consumeInput() { +Loop: + for { + select { + case data := <-b.input: + m := SpPortMessage{b.port, data} + message, _ := json.Marshal(m) + b.output <- message + case <-b.done: + break Loop //this is required, a simple break statement would only exit the innermost switch statement + } + } + close(b.input) // close the input channel at the end of the computation } func (b *BufferflowDefault) OnIncomingData(data string) { - //log.Printf("OnIncomingData() start. data:%v\n", data) -} - -// Clean out b.sem so it can truly block -func (b *BufferflowDefault) ClearOutSemaphore() { -} - -func (b *BufferflowDefault) BreakApartCommands(cmd string) []string { - return []string{cmd} -} - -func (b *BufferflowDefault) Pause() { - return -} - -func (b *BufferflowDefault) Unpause() { - return -} - -func (b *BufferflowDefault) SeeIfSpecificCommandsShouldSkipBuffer(cmd string) bool { - return false -} - -func (b *BufferflowDefault) SeeIfSpecificCommandsShouldPauseBuffer(cmd string) bool { - return false -} - -func (b *BufferflowDefault) SeeIfSpecificCommandsShouldUnpauseBuffer(cmd string) bool { - return false -} - -func (b *BufferflowDefault) SeeIfSpecificCommandsShouldWipeBuffer(cmd string) bool { - return false -} - -func (b *BufferflowDefault) SeeIfSpecificCommandsReturnNoResponse(cmd string) bool { - return false -} - -func (b *BufferflowDefault) ReleaseLock() { -} - -func (b *BufferflowDefault) IsBufferGloballySendingBackIncomingData() bool { - return false + b.input <- data } func (b *BufferflowDefault) Close() { + b.done <- true + close(b.done) } diff --git a/bufferflow_timed.go b/bufferflow_timed.go index c4a7b6117..b89427f37 100644 --- a/bufferflow_timed.go +++ b/bufferflow_timed.go @@ -8,104 +8,61 @@ import ( ) type BufferflowTimed struct { - Name string - Port string - Output chan []byte - Input chan string - done chan bool - ticker *time.Ticker + port string + output chan<- []byte + input chan string + done chan bool + ticker *time.Ticker + sPort string + bufferedOutput string } -var ( - bufferedOutput string -) +func NewBufferflowTimed(port string, output chan<- []byte) *BufferflowTimed { + return &BufferflowTimed{ + port: port, + output: output, + input: make(chan string), + done: make(chan bool), + ticker: time.NewTicker(16 * time.Millisecond), + sPort: "", + bufferedOutput: "", + } +} func (b *BufferflowTimed) Init() { log.Println("Initting timed buffer flow (output once every 16ms)") - bufferedOutput = "" - - go func() { - b.ticker = time.NewTicker(16 * time.Millisecond) - b.done = make(chan bool) - Loop: - for { - select { - case data := <-b.Input: - bufferedOutput = bufferedOutput + data - case <-b.ticker.C: - if bufferedOutput != "" { - m := SpPortMessage{bufferedOutput} - buf, _ := json.Marshal(m) - // data is now encoded in base64 format - // need a decoder on the other side - b.Output <- []byte(buf) - bufferedOutput = "" - } - case <-b.done: - break Loop + go b.consumeInput() +} + +func (b *BufferflowTimed) consumeInput() { +Loop: + for { + select { + case data := <-b.input: // use the buffer and append data to it + b.bufferedOutput = b.bufferedOutput + data + b.sPort = b.port + case <-b.ticker.C: // after 16ms send the buffered output message + if b.bufferedOutput != "" { + m := SpPortMessage{b.sPort, b.bufferedOutput} + buf, _ := json.Marshal(m) + b.output <- buf + // reset the buffer and the port + b.bufferedOutput = "" + b.sPort = "" } + case <-b.done: + break Loop //this is required, a simple break statement would only exit the innermost switch statement } - - close(b.Input) - close(b.done) - - }() - -} - -func (b *BufferflowTimed) BlockUntilReady(cmd string, id string) (bool, bool) { - //log.Printf("BlockUntilReady() start\n") - return true, false + } + close(b.input) } func (b *BufferflowTimed) OnIncomingData(data string) { - b.Input <- data -} - -// Clean out b.sem so it can truly block -func (b *BufferflowTimed) ClearOutSemaphore() { -} - -func (b *BufferflowTimed) BreakApartCommands(cmd string) []string { - return []string{cmd} -} - -func (b *BufferflowTimed) Pause() { - return -} - -func (b *BufferflowTimed) Unpause() { - return -} - -func (b *BufferflowTimed) SeeIfSpecificCommandsShouldSkipBuffer(cmd string) bool { - return false -} - -func (b *BufferflowTimed) SeeIfSpecificCommandsShouldPauseBuffer(cmd string) bool { - return false -} - -func (b *BufferflowTimed) SeeIfSpecificCommandsShouldUnpauseBuffer(cmd string) bool { - return false -} - -func (b *BufferflowTimed) SeeIfSpecificCommandsShouldWipeBuffer(cmd string) bool { - return false -} - -func (b *BufferflowTimed) SeeIfSpecificCommandsReturnNoResponse(cmd string) bool { - return false -} - -func (b *BufferflowTimed) ReleaseLock() { -} - -func (b *BufferflowTimed) IsBufferGloballySendingBackIncomingData() bool { - return true + b.input <- data } func (b *BufferflowTimed) Close() { b.ticker.Stop() b.done <- true + close(b.done) } diff --git a/bufferflow_timedraw.go b/bufferflow_timedraw.go index 0c3acf7b8..ab238bfe8 100644 --- a/bufferflow_timedraw.go +++ b/bufferflow_timedraw.go @@ -8,95 +8,62 @@ import ( ) type BufferflowTimedRaw struct { - Name string - Port string - Output chan []byte - Input chan string - ticker *time.Ticker + port string + output chan<- []byte + input chan string + done chan bool + ticker *time.Ticker + bufferedOutputRaw []byte + sPortRaw string } -var ( - bufferedOutputRaw []byte -) +func NewBufferflowTimedRaw(port string, output chan<- []byte) *BufferflowTimedRaw { + return &BufferflowTimedRaw{ + port: port, + output: output, + input: make(chan string), + done: make(chan bool), + ticker: time.NewTicker(16 * time.Millisecond), + bufferedOutputRaw: nil, + sPortRaw: "", + } +} func (b *BufferflowTimedRaw) Init() { - log.Println("Initting timed buffer flow (output once every 16ms)") - - go func() { - for data := range b.Input { - bufferedOutputRaw = append(bufferedOutputRaw, []byte(data)...) - } - }() - - go func() { - b.ticker = time.NewTicker(16 * time.Millisecond) - for _ = range b.ticker.C { - if len(bufferedOutputRaw) != 0 { - m := SpPortMessageRaw{bufferedOutputRaw} + log.Println("Initting timed buffer raw flow (output once every 16ms)") + go b.consumeInput() +} + +func (b *BufferflowTimedRaw) consumeInput() { +Loop: + for { + select { + case data := <-b.input: // use the buffer and append data to it + b.bufferedOutputRaw = append(b.bufferedOutputRaw, []byte(data)...) + b.sPortRaw = b.port + case <-b.ticker.C: // after 16ms send the buffered output message + if b.bufferedOutputRaw != nil { + m := SpPortMessageRaw{b.sPortRaw, b.bufferedOutputRaw} buf, _ := json.Marshal(m) - // data is now encoded in base64 format - // need a decoder on the other side - b.Output <- []byte(buf) - bufferedOutputRaw = nil + // since bufferedOutputRaw is a []byte is base64-encoded by json.Marshal() function automatically + b.output <- buf + // reset the buffer and the port + b.bufferedOutputRaw = nil + b.sPortRaw = "" } + case <-b.done: + break Loop //this is required, a simple break statement would only exit the innermost switch statement } - }() - -} - -func (b *BufferflowTimedRaw) BlockUntilReady(cmd string, id string) (bool, bool) { - //log.Printf("BlockUntilReady() start\n") - return true, false + } + close(b.input) } func (b *BufferflowTimedRaw) OnIncomingData(data string) { - b.Input <- data -} - -// Clean out b.sem so it can truly block -func (b *BufferflowTimedRaw) ClearOutSemaphore() { -} - -func (b *BufferflowTimedRaw) BreakApartCommands(cmd string) []string { - return []string{cmd} -} - -func (b *BufferflowTimedRaw) Pause() { - return -} - -func (b *BufferflowTimedRaw) Unpause() { - return -} - -func (b *BufferflowTimedRaw) SeeIfSpecificCommandsShouldSkipBuffer(cmd string) bool { - return false -} - -func (b *BufferflowTimedRaw) SeeIfSpecificCommandsShouldPauseBuffer(cmd string) bool { - return false -} - -func (b *BufferflowTimedRaw) SeeIfSpecificCommandsShouldUnpauseBuffer(cmd string) bool { - return false -} - -func (b *BufferflowTimedRaw) SeeIfSpecificCommandsShouldWipeBuffer(cmd string) bool { - return false -} - -func (b *BufferflowTimedRaw) SeeIfSpecificCommandsReturnNoResponse(cmd string) bool { - return false -} - -func (b *BufferflowTimedRaw) ReleaseLock() { -} - -func (b *BufferflowTimedRaw) IsBufferGloballySendingBackIncomingData() bool { - return true + b.input <- data } func (b *BufferflowTimedRaw) Close() { b.ticker.Stop() - close(b.Input) + b.done <- true + close(b.done) } diff --git a/config.ini b/config.ini index 1223279fa..960e5f3d3 100644 --- a/config.ini +++ b/config.ini @@ -2,7 +2,8 @@ gc = std # Type of garbage collection. std = Normal garbage collection allowing hostname = unknown-hostname # Override the hostname we get from the OS regex = usb|acm|com # Regular expression to filter serial port list v = true # show debug logging -appName = CreateBridge +appName = CreateAgent/Stable updateUrl = https://downloads.arduino.cc/ origins = https://local.arduino.cc:8000 #httpProxy = http://your.proxy:port # Proxy server for HTTP requests +crashreport = false # enable crashreport logging \ No newline at end of file diff --git a/design/docs.go b/design/docs.go deleted file mode 100644 index d86fd9065..000000000 --- a/design/docs.go +++ /dev/null @@ -1,10 +0,0 @@ -package design - -import . "goa.design/goa/dsl" - -var _ = Service("docs", func() { - HTTP(func() { - Path("/docs") - }) - Files("/pkgs", "docs/pkgs.html") -}) diff --git a/docs/pkgs.html b/docs/pkgs.html deleted file mode 100644 index c505805f5..000000000 --- a/docs/pkgs.html +++ /dev/null @@ -1,123 +0,0 @@ - - - - - Interactive docs for pkgs api - - - -

pkgs api manage the indexes and tools installed on the system.

- -

Indexes

-

An index file contains the info about a core and its tools. You can see an example at https://downloads.arduino.cc/packages/package_index.json

- -

index files are saved (with an urlencoded filename) in the folder ~/.arduino-create/indexes

- -

List Indexes

-

You can list the indexes installed in the system with this simple GET

-
-
- - -

Add Indexes

-

You can add a new index with a POST request

-
-
- - -

You can now check if the new package_index was downloaded by repeating List Indexes.

- -

Remove Indexes

-

You can add a new index with a POST request

-
-
- - -

You can now check if the new package_index was removed by repeating List Indexes.

- - -

Tools

-

A tool is an executable that can be used to program a board.

- -

tools are saved in the folder ~/.arduino-create with a structure like {packager}/{name}/{version}

- -

List Available Tools

-

You can list the available tools that could be installed from an index with this simple GET. (Remember to add - indexes)

-
-
- - -

List Installed Tools

-

You can list the tools installed in the system with this simple GET

-
-
- - - -

Install a tool from an index file

-

You can install one of the available tools with a PUT request

-
-
- - - -

Remove an installed tool

-

You can remove one of the installed tools with a DELETE request

-
-
- - - - - - - \ No newline at end of file diff --git a/docs/tools.md b/docs/tools.md index 35be570c9..93ac8e3f8 100644 --- a/docs/tools.md +++ b/docs/tools.md @@ -10,7 +10,8 @@ ```go type Tools struct { Directory string - IndexURL string + IndexURL string + LastRefresh time.Time Logger log.StdLogger } ``` @@ -20,6 +21,7 @@ to download a tool from the arduino servers. - *Directory* contains the location where the tools are downloaded. - *IndexURL* contains the url where the tools description is contained. +- *LastRefresh* contains the last update time - *Logger* is a StdLogger used for reporting debug and info messages - *installed* contains a map of the tools and their exact location diff --git a/go.mod b/go.mod index 424f9da0c..246faa3a0 100644 --- a/go.mod +++ b/go.mod @@ -3,68 +3,48 @@ module github.com/arduino/arduino-create-agent go 1.14 require ( - github.com/akavel/rsrc v0.9.0 // indirect + github.com/andela/gin-cors v0.0.0-20160928171741-e8c3436a37e2 + github.com/arduino/arduino-cli v0.0.0-20210422154105-5aa424818026 github.com/blang/semver v3.5.1+incompatible - github.com/codeclysm/extract v2.0.0+incompatible - github.com/creack/goselect v0.0.0-20180501195510-58854f77ee8d - github.com/davecgh/go-spew v1.1.1 - github.com/davidmz/go-pageant v1.0.1 - github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 + github.com/codeclysm/extract/v3 v3.0.2 + github.com/davidmz/go-pageant v1.0.1 // indirect + github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 // indirect github.com/dimfeld/httptreemux v5.0.1+incompatible // indirect - github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 - github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 - github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 - github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 - github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 - github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f - github.com/getlantern/systray v0.0.0-20200109124156-9abdfb6448b3 - github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 - github.com/gin-gonic/gin v1.3.0 - github.com/go-ini/ini v1.39.0 - github.com/go-ole/go-ole v1.2.1 - github.com/go-stack/stack v1.8.0 - github.com/golang/protobuf v0.0.0-20170601230230-5a0f697c9ed9 - github.com/googollee/go-engine.io v0.0.0-20180829091931-e2f255711dcb + github.com/getlantern/systray v1.1.0 + github.com/gin-gonic/gin v1.7.7 + github.com/go-ini/ini v1.62.0 + github.com/golang/protobuf v1.4.3 // indirect + github.com/google/gxui v0.0.0-20151028112939-f85e0a97b3a4 // indirect + github.com/googollee/go-engine.io v0.0.0-20180829091931-e2f255711dcb // indirect github.com/googollee/go-socket.io v0.0.0-20181101151912-c8aeb1ed9b49 - github.com/gorilla/websocket v1.4.0 - github.com/itsjamie/gin-cors v0.0.0-20160420130702-97b4a9da7933 - github.com/json-iterator/go v0.0.0-20170829155851-36b14963da70 - github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5 + github.com/h2non/filetype v1.1.0 // indirect + github.com/json-iterator/go v1.1.10 // indirect + github.com/juju/errors v0.0.0-20200330140219-3fe23663418f // indirect github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 - github.com/konsorten/go-windows-terminal-sequences v1.0.1 github.com/kr/binarydist v0.1.0 - github.com/kr/fs v0.1.0 - github.com/lxn/walk v0.0.0-20191128110447-55ccb3a9f5c1 - github.com/lxn/win v0.0.0-20191128105842-2da648fda5b4 - github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d - github.com/mattn/go-isatty v0.0.2-0.20170307163044-57fdcb988a5c - github.com/mattn/go-shellwords v1.0.3 - github.com/miekg/dns v1.0.15 - github.com/mitchellh/go-homedir v1.0.0 + github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d // indirect + github.com/manveru/gobdd v0.0.0-20131210092515-f1a17fdd710b // indirect + github.com/mattn/go-shellwords v1.0.12 + github.com/miekg/dns v1.1.35 // indirect + github.com/mitchellh/go-homedir v1.1.0 + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect github.com/oleksandr/bonjour v0.0.0-20160508152359-5dcf00d8b228 - github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c - github.com/pkg/errors v0.8.0 - github.com/pkg/sftp v1.8.3 - github.com/pmezard/go-difflib v1.0.0 - github.com/sergi/go-diff v1.0.0 + github.com/pkg/errors v0.9.1 + github.com/pkg/sftp v1.12.0 // indirect github.com/sfreiberg/simplessh v0.0.0-20180301191542-495cbb862a9c - github.com/sirupsen/logrus v1.2.0 + github.com/sirupsen/logrus v1.8.1 github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c - github.com/stretchr/testify v1.3.0 - github.com/ugorji/go v0.0.0-20170215201144-c88ee250d022 + github.com/stretchr/testify v1.7.0 + github.com/ugorji/go v1.2.3 // indirect github.com/xrash/smetrics v0.0.0-20170218160415-a3153f7040e9 - github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea + github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea // indirect go.bug.st/downloader v0.0.0-20181116113543-9b8976a44d87 - go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45 + go.bug.st/serial v1.3.0 goa.design/goa v1.0.1-0.20190116060309-40843d63b0e4 - golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 - golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect - golang.org/x/net v0.0.0-20190620200207-3b0461eec859 - golang.org/x/sys v0.0.0-20200107162124-548cf772de50 - golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7 - gopkg.in/Knetic/govaluate.v3 v3.0.0 - gopkg.in/go-playground/validator.v8 v8.18.1 - gopkg.in/h2non/filetype.v1 v1.0.5 + golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392 + golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c gopkg.in/inconshreveable/go-update.v0 v0.0.0-20150814200126-d8b0b1d421aa - gopkg.in/yaml.v2 v2.2.2 + gopkg.in/ini.v1 v1.62.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index beaf8046a..e2981e160 100644 --- a/go.sum +++ b/go.sum @@ -1,151 +1,449 @@ -github.com/akavel/rsrc v0.9.0 h1:HwUDC0+tMFWqN4D5G+o5siGD4oVsC3jn6zM8ocjc3nY= -github.com/akavel/rsrc v0.9.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/andela/gin-cors v0.0.0-20160928171741-e8c3436a37e2 h1:CEix/eilscZqWgZKpY1VU0VTxOv+jV6NVgJEZ/hMBVs= +github.com/andela/gin-cors v0.0.0-20160928171741-e8c3436a37e2/go.mod h1:qLg54VlozD6sRu86y3SzM1iybe6G2eaoZGKuGdxSsdc= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/arduino/arduino-cli v0.0.0-20210422154105-5aa424818026 h1:YzxiXS2tBkotw65inAy9hYkXEHcCmszj9mRNQXNEEnU= +github.com/arduino/arduino-cli v0.0.0-20210422154105-5aa424818026/go.mod h1:5dWroFPvaWuBNVuYMV0X8osqIhyUG5otRgJlRHN831E= +github.com/arduino/board-discovery v0.0.0-20180823133458-1ba29327fb0c/go.mod h1:HK7SpkEax/3P+0w78iRQx1sz1vCDYYw9RXwHjQTB5i8= +github.com/arduino/go-paths-helper v1.0.1/go.mod h1:HpxtKph+g238EJHq4geEPv9p+gl3v5YYu35Yb+w31Ck= +github.com/arduino/go-paths-helper v1.2.0/go.mod h1:HpxtKph+g238EJHq4geEPv9p+gl3v5YYu35Yb+w31Ck= +github.com/arduino/go-paths-helper v1.4.0 h1:ilnseAdxmN1bFnLxxXHRtcdmt9jBf3O4jtYfWfqule4= +github.com/arduino/go-paths-helper v1.4.0/go.mod h1:V82BWgAAp4IbmlybxQdk9Bpkz8M4Qyx+RAFKaG9NuvU= +github.com/arduino/go-properties-orderedmap v1.3.0/go.mod h1:DKjD2VXY/NZmlingh4lSFMEYCVubfeArCsGPGDwb2yk= +github.com/arduino/go-timeutils v0.0.0-20171220113728-d1dd9e313b1b/go.mod h1:uwGy5PpN4lqW97FiLnbcx+xx8jly5YuPMJWfVwwjJiQ= +github.com/arduino/go-win32-utils v0.0.0-20180330194947-ed041402e83b/go.mod h1:iIPnclBMYm1g32Q5kXoqng4jLhMStReIP7ZxaoUC2y8= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/codeclysm/extract v2.0.0+incompatible h1:+b4WsD7YuZ5u3iW5T5TWbO764zUyEpQZSH5tZbjAxXQ= -github.com/codeclysm/extract v2.0.0+incompatible/go.mod h1:2nhFMPHiU9At61hz+12bfrlpXSUrOnK+wR+KlGO4Uks= -github.com/creack/goselect v0.0.0-20180501195510-58854f77ee8d h1:6o8WW5zZ+Ny9sbk69epnAPmBzrBaRnvci+l4+pqleeY= -github.com/creack/goselect v0.0.0-20180501195510-58854f77ee8d/go.mod h1:gHrIcH/9UZDn2qgeTUeW5K9eZsVYCH6/60J/FHysWyE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cmaglie/go.rice v1.0.3/go.mod h1:AF3bOWkvdOpp8/S3UL8qbQ4N7DiISIbJtj54GWFPAsc= +github.com/cmaglie/pb v1.0.27/go.mod h1:GilkKZMXYjBA4NxItWFfO+lwkp59PLHQ+IOW/b/kmZI= +github.com/codeclysm/cc v1.2.2/go.mod h1:XtW4ArCNgQwFphcRGG9+sPX5WM1J6/u0gMy5ZdV3obA= +github.com/codeclysm/extract/v3 v3.0.2 h1:sB4LcE3Php7LkhZwN0n2p8GCwZe92PEQutdbGURf5xc= +github.com/codeclysm/extract/v3 v3.0.2/go.mod h1:NKsw+hqua9H+Rlwy/w/3Qgt9jDonYEgB6wJu+25eOKw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/goselect v0.1.1/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY= +github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0= +github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davidmz/go-pageant v1.0.1 h1:kzCt64aTc557QYvy5VBSN1pVWO/tNAcqzwlpUsZ8IEE= github.com/davidmz/go-pageant v1.0.1/go.mod h1:WWOKE/93DhgsPq15jaipH4fVY+MLKKWH4Yku5Ei92rE= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 h1:MGKhKyiYrvMDZsmLR/+RGffQSXwEkXgfLSA08qDn9AI= github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598/go.mod h1:0FpDmbrt36utu8jEmeU05dPC9AB5tsLYVVi+ZHfyuwI= github.com/dimfeld/httptreemux v5.0.1+incompatible h1:Qj3gVcDNoOthBAqftuD596rm4wg/adLLz5xh5CmpiCA= github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0= -github.com/getlantern/context v0.0.0-20181106182922-539649cc3118/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fluxio/iohelpers v0.0.0-20160419043813-3a4dd67a94d2/go.mod h1:c7sGIpDbBo0JZZ1tKyC1p5smWf8QcUjK4bFtZjHAecg= +github.com/fluxio/multierror v0.0.0-20160419044231-9c68d39025e5/go.mod h1:BEUDl7FG1cc76sM0J0x8dqr6RhiL4uqvk6oFkwuNyuM= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4= github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY= -github.com/getlantern/errors v0.0.0-20180829142810-e24b7f4ff7c7/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A= github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 h1:6uJ+sZ/e03gkbqZ0kUG6mfKoqDb4XMAzMIwlajq19So= github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A= -github.com/getlantern/golog v0.0.0-20170508214112-cca714f7feb5/go.mod h1:Vwx1Cg64gCdIalad44uvQsKZw6LsVczIKZrUBStEjVw= github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 h1:guBYzEaLz0Vfc/jv0czrr2z7qyzTOGC9hiQ0VC+hKjk= github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7/go.mod h1:zx/1xUUeYPy3Pcmet8OSXLbF47l+3y6hIPpyLWoR9oc= -github.com/getlantern/hex v0.0.0-20160523043825-083fba3033ad/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o= github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0= github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o= -github.com/getlantern/hidden v0.0.0-20160523043807-d52a649ab33a/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA= github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc= github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA= -github.com/getlantern/ops v0.0.0-20170904182230-37353306c908/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA= github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= -github.com/getlantern/systray v0.0.0-20200109124156-9abdfb6448b3 h1:2MdGh70ni2gKLWFkuWU3DBQ5N1I+Mso9dGwfxG8xONc= -github.com/getlantern/systray v0.0.0-20200109124156-9abdfb6448b3/go.mod h1:4yRvwNSBNJtSOi3dRLNxhG40wXg9nEwdDjX2IrGZJo8= -github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 h1:AzN37oI0cOS+cougNAV9szl6CVoj2RYwzS3DpUQNtlY= -github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs= -github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= -github.com/go-ini/ini v1.39.0 h1:/CyW/jTlZLjuzy52jc1XnhJm6IUKEuunpJFpecywNeI= -github.com/go-ini/ini v1.39.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/getlantern/systray v1.1.0 h1:U0wCEqseLi2ok1fE6b88gJklzriavPJixZysZPkZd/Y= +github.com/getlantern/systray v1.1.0/go.mod h1:AecygODWIsBquJCJFop8MEQcJbWFfw/1yWbVabNgpCM= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= +github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-ini/ini v1.62.0 h1:7VJT/ZXjzqSrvtraFp4ONq80hTcRQth1c9ZnQ3uNQvU= +github.com/go-ini/ini v1.62.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/golang/protobuf v0.0.0-20170601230230-5a0f697c9ed9 h1:6w6GCsh1LARYT2JCCS9B+cHIzp/zNoKCrEQrReZZ2p8= -github.com/golang/protobuf v0.0.0-20170601230230-5a0f697c9ed9/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gxui v0.0.0-20151028112939-f85e0a97b3a4 h1:OL2d27ueTKnlQJoqLW2fc9pWYulFnJYLWzomGV7HqZo= +github.com/google/gxui v0.0.0-20151028112939-f85e0a97b3a4/go.mod h1:Pw1H1OjSNHiqeuxAduB1BKYXIwFtsyrY47nEqSgEiCM= github.com/googollee/go-engine.io v0.0.0-20180829091931-e2f255711dcb h1:n22Aukg/TjoypWc37dbKIpCsz0VMFPD36HQk1WKvg3A= github.com/googollee/go-engine.io v0.0.0-20180829091931-e2f255711dcb/go.mod h1:MBpz1MS3P4HtRcBpQU4HcjvWXZ9q+JWacMEh2/BFYbg= github.com/googollee/go-socket.io v0.0.0-20181101151912-c8aeb1ed9b49 h1:vKXGRzlhWE9TUVhLqAOcgQbfYvReAnsvQQIcnvWMfcg= github.com/googollee/go-socket.io v0.0.0-20181101151912-c8aeb1ed9b49/go.mod h1:ftBGBMhSYToR5oV4ImIPKvAIsNaTkLC+tTvoNafqxlQ= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/itsjamie/gin-cors v0.0.0-20160420130702-97b4a9da7933 h1:USSH71GEMLF/yxfkbDMvmklaimVh9cXbBVcQZ4AgJPE= -github.com/itsjamie/gin-cors v0.0.0-20160420130702-97b4a9da7933/go.mod h1:AYdLvrSBFloDBNt7Y8xkQ6gmhCODGl8CPikjyIOnNzA= -github.com/json-iterator/go v0.0.0-20170829155851-36b14963da70/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5 h1:rhqTjzJlm7EbkELJDKMTU7udov+Se0xZkWmugr6zGok= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/h2non/filetype v1.0.6/go.mod h1:isekKqOuhMj+s/7r3rIeTErIRy4Rub5uBWHfvMusLMU= +github.com/h2non/filetype v1.0.8/go.mod h1:isekKqOuhMj+s/7r3rIeTErIRy4Rub5uBWHfvMusLMU= +github.com/h2non/filetype v1.1.0 h1:Or/gjocJrJRNK/Cri/TDEKFjAR+cfG6eK65NGYB6gBA= +github.com/h2non/filetype v1.1.0/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/clock v0.0.0-20180524022203-d293bb356ca4/go.mod h1:nD0vlnrUjcjJhqN5WuCWZyzfd5AHZAC9/ajvbSx69xA= +github.com/juju/errors v0.0.0-20150916125642-1b5e39b83d18/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/errors v0.0.0-20200330140219-3fe23663418f h1:MCOvExGLpaSIzLYB4iQXEHP4jYVU6vmzLNQPdMVrxnM= +github.com/juju/errors v0.0.0-20200330140219-3fe23663418f/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20170605014607-8232ab8918d9/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 h1:UUHMLvzt/31azWTN/ifGWef4WUqvXk0iRqdhdy/2uzI= +github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/retry v0.0.0-20160928201858-1998d01ba1c3/go.mod h1:OohPQGsr4pnxwD5YljhQ+TZnuVRYpa5irjugL1Yuif4= +github.com/juju/testing v0.0.0-20200510222523-6c8c298c77a0 h1:+WWUkhnTjV6RNOxkcwk79qrjeyHEHvBzlneueBsatX4= +github.com/juju/testing v0.0.0-20200510222523-6c8c298c77a0/go.mod h1:hpGvhGHPVbNBraRLZEhoQwFLMrjK8PSlO4D3nDjKYXo= +github.com/juju/utils v0.0.0-20180808125547-9dfc6dbfb02b/go.mod h1:6/KLg8Wz/y2KVGWEpkK9vMNGkOnu4k/cqs8Z1fKjTOk= +github.com/juju/version v0.0.0-20161031051906-1f41e27e54f2/go.mod h1:kE8gK5X0CImdr7qpSKl3xB2PmpySSmfj7zVbkZFs81U= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro= github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/binarydist v0.1.0 h1:6kAoLA9FMMnNGSehX0s1PdjbEaACznAv/W219j2uvyo= github.com/kr/binarydist v0.1.0/go.mod h1:DY7S//GCoz1BCd0B0EVrinCKAZN3pXe+MDaIZbXQVgM= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/lxn/walk v0.0.0-20191113135339-bf589de20b3c/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= -github.com/lxn/walk v0.0.0-20191128110447-55ccb3a9f5c1/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= -github.com/lxn/win v0.0.0-20191106123917-121afc750dd3/go.mod h1:ouWl4wViUNh8tPSIwxTVMuS014WakR1hqvBc2I0bMoA= -github.com/lxn/win v0.0.0-20191128105842-2da648fda5b4/go.mod h1:ouWl4wViUNh8tPSIwxTVMuS014WakR1hqvBc2I0bMoA= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leonelquinteros/gotext v1.4.0/go.mod h1:yZGXREmoGTtBvZHNcc+Yfug49G/2spuF/i/Qlsvz1Us= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d h1:Zj+PHjnhRYWBK6RqCDBcAhLXoi3TzC27Zad/Vn+gnVQ= github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d/go.mod h1:WZy8Q5coAB1zhY9AOBJP0O6J4BuDfbupUDavKY+I3+s= -github.com/mattn/go-isatty v0.0.2-0.20170307163044-57fdcb988a5c h1:vNDTotKSxm/15mLGhBXjdU6q6Ncrx0HlVEd8ToAsGTw= -github.com/mattn/go-isatty v0.0.2-0.20170307163044-57fdcb988a5c/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-shellwords v1.0.3 h1:K/VxK7SZ+cvuPgFSLKi5QPI9Vr/ipOf4C1gN+ntueUk= -github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/miekg/dns v1.0.15 h1:9+UupePBQCG6zf1q/bGmTO1vumoG13jsrbWOSX1W6Tw= -github.com/miekg/dns v1.0.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/manveru/gobdd v0.0.0-20131210092515-f1a17fdd710b h1:3E44bLeN8uKYdfQqVQycPnaVviZdBLbizFhU49mtbe4= +github.com/manveru/gobdd v0.0.0-20131210092515-f1a17fdd710b/go.mod h1:Bj8LjjP0ReT1eKt5QlKjwgi5AFm5mI6O1A2G4ChI0Ag= +github.com/marcinbor85/gohex v0.0.0-20210308104911-55fb1c624d84/go.mod h1:Pb6XcsXyropB9LNHhnqaknG/vEwYztLkQzVCHv8sQ3M= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= +github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mdlayher/genetlink v0.0.0-20190313224034-60417448a851/go.mod h1:EsbsAEUEs15qC1cosAwxgCWV0Qhd8TmkxnA9Kw1Vhl4= +github.com/mdlayher/netlink v0.0.0-20190313131330-258ea9dff42c/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= +github.com/mdlayher/taskstats v0.0.0-20190313225729-7cbba52ee072/go.mod h1:sGdS7A6CAETR53zkdjGkgoFlh1vSm7MtX+i8XfEsTMA= +github.com/miekg/dns v1.0.5/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.35 h1:oTfOaDH+mZkdcgdIjH6yBajRGtIwcwcaR+rt23ZSrJs= +github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nkovacs/streamquote v1.0.0/go.mod h1:BN+NaZ2CmdKqUuTUXUEm9j95B2TRbpOWpxbJYzzgUsc= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oleksandr/bonjour v0.0.0-20160508152359-5dcf00d8b228 h1:Cvfd2dOlXIPTeEkOT/h8PyK4phBngOM4at9/jlgy7d4= github.com/oleksandr/bonjour v0.0.0-20160508152359-5dcf00d8b228/go.mod h1:MGuVJ1+5TX1SCoO2Sx0eAnjpdRytYla2uC1YIZfkC9c= -github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= -github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= +github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.8.3 h1:9jSe2SxTM8/3bXZjtqnkgTBW+lA8db0knZJyns7gpBA= -github.com/pkg/sftp v1.8.3/go.mod h1:NxmoDg/QLVWluQDUYG7XBZTLUpKeFa8e3aMf1BfjyHk= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.12.0 h1:/f3b24xrDhkhddlaobPe2JgBqfdt+gC/NYl0QY9IOuI= +github.com/pkg/sftp v1.12.0/go.mod h1:fUqqXB5vEgVCZ131L+9say31RAri6aF6KDViawhxKK8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmylund/sortutil v0.0.0-20120526081524-abeda66eb583/go.mod h1:sFPiU/UgDcsQVu3vkqpZLCXWFwUoQRpHGu9ATihPAl0= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/segmentio/fasthash v0.0.0-20180216231524-a72b379d632e/go.mod h1:tm/wZFQ8e24NYaBGIlnO2WGCAi67re4HHuOm0sftE/M= +github.com/segmentio/objconv v1.0.1/go.mod h1:auayaH5k3137Cl4SoXTgrzQcuQDmvuVtZgS0fb1Ahys= +github.com/segmentio/stats/v4 v4.5.3/go.mod h1:LsaahUJR7iiSs8mnkvQvdQ/RLHAS5adGLxuntg0ydGo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sfreiberg/simplessh v0.0.0-20180301191542-495cbb862a9c h1:7Q+2oF0uBoLEV+j13E3/xUkPkI7f+sFNPZOPo2jmrWk= github.com/sfreiberg/simplessh v0.0.0-20180301191542-495cbb862a9c/go.mod h1:sB7d6wQapoRM+qx5MgQYB6JVHtel4YHRr0NXXCkXiwQ= -github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c h1:fyKiXKO1/I/B6Y2U8T7WdQGWzwehOuGIrljPtt7YTTI= github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.0.1-0.20200710201246-675ae5f5a98c/go.mod h1:aeNIJzz/GSSVlS+gpCpQWZ83BKbsoW57mr90+YthtkQ= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= +github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/ugorji/go v0.0.0-20170215201144-c88ee250d022 h1:wIYK3i9zY6ZBcWw4GFvoPVwtb45iEm8KyOVmDhSLvsE= -github.com/ugorji/go v0.0.0-20170215201144-c88ee250d022/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.2.3 h1:WbFSXLxDFKVN69Sk8t+XHGzVCD7R8UoAATR8NqZgTbk= +github.com/ugorji/go v1.2.3/go.mod h1:5l8GZ8hZvmL4uMdy+mhCO1LjswGRYco9Q3HfuisB21A= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.3 h1:/mVYEV+Jo3IZKeA5gBngN0AvNnQltEDkR+eQikkWQu0= +github.com/ugorji/go/codec v1.2.3/go.mod h1:5FxzDJIgeiWJZslYHPj+LS1dq1ZBQVelZFnjsFGI/Uc= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20170218160415-a3153f7040e9 h1:w8V9v0qVympSF6GjdjIyeqR7+EVhAF9CBQmkmW7Zw0w= github.com/xrash/smetrics v0.0.0-20170218160415-a3153f7040e9/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea h1:CyhwejzVGvZ3Q2PSbQ4NRRYn+ZWv5eS1vlaEusT+bAI= github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea/go.mod h1:eNr558nEUjP8acGw8FFjTeWvSgU1stO7FAO6eknhHe4= +go.bug.st/cleanup v1.0.0/go.mod h1:EqVmTg2IBk4znLbPD28xne3abjsJftMdqqJEjhn70bk= go.bug.st/downloader v0.0.0-20181116113543-9b8976a44d87 h1:8W/hwyrc25HrXxbtG8Ghiwgq/hDB8KCh7hKMf78gp90= go.bug.st/downloader v0.0.0-20181116113543-9b8976a44d87/go.mod h1:OUL7bexo6Ir+BRE5E7Cs3qUvO6ZgJL5Hjk/qwiy6Ze0= -go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45 h1:mACY1anK6HNCZtm/DK2Rf2ZPHggVqeB0+7rY9Gl6wyI= +go.bug.st/downloader/v2 v2.1.1/go.mod h1:VZW2V1iGKV8rJL2ZEGIDzzBeKowYv34AedJz13RzVII= +go.bug.st/relaxed-semver v0.0.0-20190922224835-391e10178d18/go.mod h1:Cx1VqMtEhE9pIkEyUj3LVVVPkv89dgW8aCKrRPDR/uE= +go.bug.st/serial v1.1.2/go.mod h1:VmYBeyJWp5BnJ0tw2NUJHZdJTGl2ecBGABHlzRK1knY= +go.bug.st/serial v1.3.0 h1:liPN6f/Xk0qaUByg0H2LOSns+2RuAuNXmXZyQOLVwVE= +go.bug.st/serial v1.3.0/go.mod h1:8TT7u/SwwNIpJ8QaG4s+HTjFt9ReXs2cdOU7ZEk50Dk= go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45/go.mod h1:dRSl/CVCTf56CkXgJMDOdSwNfo2g1orOGE/gBGdvjZw= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= goa.design/goa v1.0.1-0.20190116060309-40843d63b0e4 h1:+qjyw15FIXxmcA/QmrDrofQPLMAav6X2v+UYH/pQq8A= goa.design/goa v1.0.1-0.20190116060309-40843d63b0e4/go.mod h1:NnzBwdNktihbNek+pPiFMQP9PPFsUt8MMPPyo9opDSo= +golang.org/x/crypto v0.0.0-20180214000028-650f4a345ab4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869 h1:kkXA53yGe04D0adEYJwEVQjeBppL01Exg+fnMjfUraU= -golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392 h1:xYJJ3S178yv++9zXV/hnr29plCAGO9vAFG9dorqaFQc= +golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U= +golang.org/x/net v0.0.0-20180406214816-61147c48b25b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200107162124-548cf772de50 h1:YvQ10rzcqWXLlJZ3XCUoO25savxmscf4+SC+ZqiCHhA= -golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190116231616-b258f6da2383/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7 h1:EBZoQjiKKPaLbPrbpssUfuHtwM6KV/vb4U85g/cigFY= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/go-playground/validator.v8 v8.18.1 h1:F8SLY5Vqesjs1nI1EL4qmF1PQZ1sitsmq0rPYXLyfGU= -gopkg.in/go-playground/validator.v8 v8.18.1/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/h2non/filetype.v1 v1.0.5 h1:CC1jjJjoEhNVbMhXYalmGBhOBK2V70Q1N850wt/98/Y= -gopkg.in/h2non/filetype.v1 v1.0.5/go.mod h1:M0yem4rwSX5lLVrkEuRRp2/NinFMD5vgJ4DlAhZcfNo= +gopkg.in/check.v1 v1.0.0-20160105164936-4f90aeace3a2/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/inconshreveable/go-update.v0 v0.0.0-20150814200126-d8b0b1d421aa h1:drvf2JoUL1fz3ttkGNkw+rf3kZa2//7XkYGpSO4NHNA= gopkg.in/inconshreveable/go-update.v0 v0.0.0-20150814200126-d8b0b1d421aa/go.mod h1:tuNm0ntQ7IH9VSA39XxzLMpee5c2DwgIbjD4x3ydo8Y= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20160818015218-f2b6f6c918c4/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= +gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170712054546-1be3d31502d6/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/home.html b/home.html index 8021c83f4..7551a48dc 100644 --- a/home.html +++ b/home.html @@ -1,5 +1,6 @@ + - + Arduino Create Agent Debug Console @@ -17,19 +18,38 @@ var MESSAGES_MAX_COUNT = 2000; function appendLog(msg) { - var startsWithBracked = msg.indexOf('{') == 0; + let jsonMsg = {}; + let portListing = false; + try { + jsonMsg = JSON.parse(msg); + portsListing = jsonMsg.Ports; + } catch { + // no valid json + } + var startsWithList = msg.indexOf('list') == 0; - if (listenabled.checked || (typeof msg === 'string' && !startsWithBracked && !startsWithList)) { - messages.push(msg); - if (messages.length > MESSAGES_MAX_COUNT) { - messages.shift(); - } - log.innerHTML = messages.join('
'); - if (autoscroll.checked) { - log.scrollTop = log.scrollHeight - log.clientHeight; - } - } + if (listenabled.checked || (!portsListing && !startsWithList)) { + let printMsg = msg; + if (jsonMsg.Ports) { + const validKeys = ['Name', 'SerialNumber', 'IsOpen', 'VendorID', 'ProductID']; + if (jsonMsg.Network) { + printMsg = "Network Ports:
"+JSON.stringify(jsonMsg.Ports, validKeys, 2); + } else { + printMsg = "Serial Ports:
"+JSON.stringify(jsonMsg.Ports, validKeys, 2); + } + } else if (Object.keys(jsonMsg).length !== 0) { + printMsg = JSON.stringify(jsonMsg, undefined, 2); + } + messages.push(printMsg); + if (messages.length > MESSAGES_MAX_COUNT) { + messages.shift(); + } + log.innerHTML = messages.join('

'); + if (autoscroll.checked) { + log.scrollTop = log.scrollHeight - log.clientHeight; + } + } } $('#form').submit(function(e) { @@ -47,6 +67,7 @@ var link = document.createElement('a'); link.setAttribute('download', 'agent-log.txt'); var text = log.innerHTML.replace(/
/g, '\n'); + text = text.replace(/|<\/b>/g, ''); link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); link.click(); }); @@ -92,7 +113,7 @@ #container { display: flex; flex-direction: column; - height: 100%; + height: 100vh; width: 100%; } @@ -100,6 +121,7 @@ flex-grow: 1; font-family: "Roboto Mono", "Courier", "Lucida Grande", Verdana, sans-serif; background-color: #DAE3E3; + height: calc(100vh - 61px); margin: 15px 15px 10px; padding: 8px 10px; overflow-y: auto; @@ -182,16 +204,15 @@ font-size: 1em; outline: none; } -
-
This is some random text This is some random textThis is some random textThis is some random textThis is some random textThis is some random textThis is some random text
This is some random text
This is some random text
+