From e9f505ea15da14f2dffb6861d3ae585c0990a11b Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Wed, 27 Sep 2023 14:11:26 -0700 Subject: [PATCH 01/10] upgrade deps --- Gemfile.lock | 24 ++++---- frontend/demo/__tests__/demo_iframe_test.tsx | 4 +- frontend/demo/demo_iframe.tsx | 6 +- package.json | 58 ++++++++++---------- 4 files changed, 45 insertions(+), 47 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ae5d722325..da9cb367e3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -146,8 +146,8 @@ GEM faraday-retry (1.0.3) faraday_middleware (1.2.0) faraday (~> 1.0) - globalid (1.1.0) - activesupport (>= 5.0) + globalid (1.2.1) + activesupport (>= 6.1) google-apis-core (0.11.1) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) @@ -175,10 +175,9 @@ GEM google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - googleauth (1.7.0) + googleauth (1.8.1) faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) - memoist (~> 0.16) multi_json (~> 1.11) os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) @@ -215,10 +214,9 @@ GEM net-pop net-smtp marcel (1.0.2) - memoist (0.16.2) method_source (1.0.0) mini_mime (1.1.5) - minitest (5.19.0) + minitest (5.20.0) multi_json (1.15.0) multipart-post (2.3.0) mutations (0.9.1) @@ -230,7 +228,7 @@ GEM net-protocol net-protocol (0.2.1) timeout - net-smtp (0.3.3) + net-smtp (0.4.0) net-protocol nio4r (2.5.9) nokogiri (1.15.4-x86_64-linux) @@ -240,7 +238,7 @@ GEM passenger (6.0.18) rack rake (>= 0.8.1) - pg (1.5.3) + pg (1.5.4) pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) @@ -338,7 +336,7 @@ GEM railties (>= 4.0.0) secure_headers (6.5.0) set (1.0.3) - signet (0.17.0) + signet (0.18.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) @@ -355,7 +353,7 @@ GEM sorted_set (1.0.3) rbtree set (~> 1.0) - sprockets (4.2.0) + sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) sprockets-rails (3.4.2) @@ -375,7 +373,7 @@ GEM rails warden (1.2.9) rack (>= 2.0.9) - webmock (3.19.0) + webmock (3.19.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -383,7 +381,7 @@ GEM websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - zeitwerk (2.6.11) + zeitwerk (2.6.12) PLATFORMS x86_64-linux @@ -434,4 +432,4 @@ RUBY VERSION ruby 3.0.6p216 BUNDLED WITH - 2.4.18 + 2.4.19 diff --git a/frontend/demo/__tests__/demo_iframe_test.tsx b/frontend/demo/__tests__/demo_iframe_test.tsx index b18a2ca671..d201a33de8 100644 --- a/frontend/demo/__tests__/demo_iframe_test.tsx +++ b/frontend/demo/__tests__/demo_iframe_test.tsx @@ -17,7 +17,7 @@ import React from "react"; import axios from "axios"; import { shallow } from "enzyme"; import { DemoIframe, WAITING_ON_API, EASTER_EGG, MQTT_CHAN } from "../demo_iframe"; -import { MqttClient } from "mqtt"; +import { IConnackPacket } from "mqtt"; import { tourPath } from "../../help/tours"; import { Path } from "../../internal_urls"; @@ -27,7 +27,7 @@ describe("", () => { const el = shallow(); expect(el.text()).toContain("DEMO THE APP"); el.instance().connectMqtt = () => - Promise.resolve() as unknown as Promise; + Promise.resolve() as unknown as Promise; await el.instance().requestAccount(); await expect(axios.post).toHaveBeenCalled(); expect(el.state().stage).toContain(WAITING_ON_API); diff --git a/frontend/demo/demo_iframe.tsx b/frontend/demo/demo_iframe.tsx index 3865ac2bf4..cfb2a26552 100644 --- a/frontend/demo/demo_iframe.tsx +++ b/frontend/demo/demo_iframe.tsx @@ -1,4 +1,4 @@ -import { connect, MqttClient } from "mqtt"; +import { ClientSubscribeCallback, connect, IConnackPacket } from "mqtt"; import React from "react"; import { uuid } from "farmbot"; import axios from "axios"; @@ -30,11 +30,11 @@ export class DemoIframe extends React.Component<{}, State> { setError = (error?: Error) => this.setState({ error }); - connectMqtt = (): Promise => { + connectMqtt = (): Promise => { const client = connect(globalConfig.MQTT_WS, WS_CONFIG); return new Promise(resolve => { client.on("message", this.handleMessage); - client.subscribe(MQTT_CHAN, this.setError); + client.subscribe(MQTT_CHAN, this.setError as ClientSubscribeCallback); client.on("connect", resolve); }); }; diff --git a/package.json b/package.json index 964df4b597..4203bbd384 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "engines": { "browsers": "defaults", "node": "20.x", - "npm": "9.x", + "npm": "10.x", "parcel": "2.x" }, "repository": { @@ -31,32 +31,32 @@ "author": "farmbot.io", "license": "MIT", "dependencies": { - "@blueprintjs/core": "5.3.0", - "@blueprintjs/select": "5.0.10", + "@blueprintjs/core": "5.3.2", + "@blueprintjs/select": "5.0.12", "@monaco-editor/react": "4.5.2", "@parcel/transformer-sass": "2.9.3", "@parcel/transformer-typescript-tsc": "2.9.3", - "@types/lodash": "4.14.197", - "@types/markdown-it": "13.0.1", - "@types/node": "20.5.7", - "@types/promise-timeout": "1.3.0", - "@types/react": "18.2.21", - "@types/react-color": "3.0.6", - "@types/react-dom": "18.2.7", - "@types/ws": "8.5.5", - "axios": "1.5.0", + "@types/lodash": "4.14.199", + "@types/markdown-it": "13.0.2", + "@types/node": "20.7.1", + "@types/promise-timeout": "1.3.1", + "@types/react": "18.2.23", + "@types/react-color": "3.0.7", + "@types/react-dom": "18.2.8", + "@types/ws": "8.5.6", + "axios": "1.5.1", "bowser": "2.11.0", "browser-speech": "1.1.1", "events": "3.3.0", "farmbot": "15.8.0", - "i18next": "23.4.6", + "i18next": "23.5.1", "lodash": "4.17.21", - "markdown-it": "13.0.1", + "markdown-it": "13.0.2", "markdown-it-emoji": "2.0.2", "moment": "2.29.4", - "monaco-editor": "0.41.0", - "mqtt": "4.3.7", - "npm": "9.8.1", + "monaco-editor": "0.43.0", + "mqtt": "5.0.5", + "npm": "10.1.0", "parcel": "2.9.3", "process": "0.11.10", "promise-timeout": "1.3.0", @@ -71,29 +71,29 @@ "redux-thunk": "2.4.2", "takeme": "0.12.0", "typescript": "5.2.2", - "url": "0.11.1", - "xterm": "5.2.1" + "url": "0.11.3", + "xterm": "5.3.0" }, "devDependencies": { "@types/enzyme": "3.10.12", - "@types/jest": "29.5.4", - "@types/readable-stream": "4.0.2", - "@typescript-eslint/eslint-plugin": "6.5.0", - "@typescript-eslint/parser": "6.5.0", + "@types/jest": "29.5.5", + "@types/readable-stream": "4.0.3", + "@typescript-eslint/eslint-plugin": "6.7.3", + "@typescript-eslint/parser": "6.7.3", "@wojtekmaj/enzyme-adapter-react-17": "0.8.0", "coveralls": "3.1.1", "enzyme": "3.11.0", - "eslint": "8.48.0", + "eslint": "8.50.0", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-import": "2.28.1", - "eslint-plugin-jest": "27.2.3", + "eslint-plugin-jest": "27.4.0", "eslint-plugin-no-null": "1.0.2", "eslint-plugin-promise": "6.1.1", "eslint-plugin-react": "7.33.2", "eslint-plugin-react-hooks": "4.6.0", - "jest": "29.6.4", - "jest-cli": "29.6.4", - "jest-environment-jsdom": "29.6.4", + "jest": "29.7.0", + "jest-cli": "29.7.0", + "jest-environment-jsdom": "29.7.0", "jest-junit": "16.0.0", "jest-skipped-reporter": "0.0.5", "jshint": "2.13.6", @@ -101,7 +101,7 @@ "raf": "3.4.1", "react-addons-test-utils": "15.6.2", "react-test-renderer": "18.2.0", - "sass": "1.66.1", + "sass": "1.68.0", "sass-lint": "1.13.1", "ts-jest": "29.1.1", "tslint": "6.1.3" From f864a969d40646683cb8528665be2a65102cfa5b Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Wed, 27 Sep 2023 14:11:56 -0700 Subject: [PATCH 02/10] upgrade ruby (3.1.4) --- .ruby-version | 2 +- Gemfile | 2 +- Gemfile.lock | 2 +- docker_configs/api.Dockerfile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.ruby-version b/.ruby-version index 818bd47abf..0aec50e6ed 100755 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.0.6 +3.1.4 diff --git a/Gemfile b/Gemfile index c8218700ac..0dfe1adead 100755 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,5 @@ source "https://rubygems.org" -ruby "~> 3.0.6" +ruby "~> 3.1.4" gem "rails", "~> 6" gem "active_model_serializers" diff --git a/Gemfile.lock b/Gemfile.lock index da9cb367e3..8eea52c67b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -429,7 +429,7 @@ DEPENDENCIES webmock RUBY VERSION - ruby 3.0.6p216 + ruby 3.1.4p223 BUNDLED WITH 2.4.19 diff --git a/docker_configs/api.Dockerfile b/docker_configs/api.Dockerfile index ec2a4cc4ed..613ed84399 100644 --- a/docker_configs/api.Dockerfile +++ b/docker_configs/api.Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.0.6 +FROM ruby:3.1.4 RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg > /dev/null && \ sh -c '. /etc/os-release; echo $VERSION_CODENAME; echo "deb http://apt.postgresql.org/pub/repos/apt/ $VERSION_CODENAME-pgdg main" >> /etc/apt/sources.list.d/pgdg.list' && \ apt-get update -qq && apt-get install -y build-essential libpq-dev postgresql postgresql-contrib && \ From 56acb9b369a1a36ff8f505c773ce67f193710372 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Wed, 27 Sep 2023 14:24:39 -0700 Subject: [PATCH 03/10] remove extra ci setup steps --- .circleci/config.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2985bfc608..5eb39b83c1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,9 +25,6 @@ commands: - run: name: Build and Install Deps command: | - sudo mkdir -p /usr/local/lib/docker/cli-plugins - sudo curl -SL "https://github.com/docker/compose/releases/download/v2.4.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/lib/docker/cli-plugins/docker-compose - sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose mv .circleci/circle_envs .env echo -e '\ndocker_volumes/db/pg_wal/*' >> .dockerignore sudo docker compose run web gem install bundler From 9c35b525482fd3a302c2962d061770b052e12c4a Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Fri, 29 Sep 2023 16:02:34 -0700 Subject: [PATCH 04/10] update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2197abb1b8..d6ba393f6c 100755 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ .vscode *.log *.pem +passenger.*.pid *.tsbuildinfo *.pid.lock *scratchpad* From e0f2ea2b56aabe5a2a523bf729d109d3c4f86901 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Fri, 29 Sep 2023 16:02:48 -0700 Subject: [PATCH 05/10] update nodejs install --- docker_configs/api.Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docker_configs/api.Dockerfile b/docker_configs/api.Dockerfile index 613ed84399..4943a34858 100644 --- a/docker_configs/api.Dockerfile +++ b/docker_configs/api.Dockerfile @@ -2,7 +2,10 @@ FROM ruby:3.1.4 RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg > /dev/null && \ sh -c '. /etc/os-release; echo $VERSION_CODENAME; echo "deb http://apt.postgresql.org/pub/repos/apt/ $VERSION_CODENAME-pgdg main" >> /etc/apt/sources.list.d/pgdg.list' && \ apt-get update -qq && apt-get install -y build-essential libpq-dev postgresql postgresql-contrib && \ - curl -sL https://deb.nodesource.com/setup_20.x | bash - && \ + mkdir -p /etc/apt/keyrings && \ + curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ + sh -c 'echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >> /etc/apt/sources.list.d/nodesource.list' && \ + apt-get update -qq && \ sh -c 'echo "\nPackage: *\nPin: origin deb.nodesource.com\nPin-Priority: 700\n" >> /etc/apt/preferences' && \ apt-get install -y nodejs && \ mkdir /farmbot; From aca50f024f03af90560d47751cbfcb0fb8bbd8a5 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Fri, 29 Sep 2023 16:03:30 -0700 Subject: [PATCH 06/10] upgrade rabbitmq --- docker_configs/rabbitmq.Dockerfile | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker_configs/rabbitmq.Dockerfile b/docker_configs/rabbitmq.Dockerfile index 29e2b98580..fb5b4a4362 100755 --- a/docker_configs/rabbitmq.Dockerfile +++ b/docker_configs/rabbitmq.Dockerfile @@ -1,4 +1,4 @@ -FROM rabbitmq:3.7.6 +FROM rabbitmq:3.12.6 RUN rabbitmq-plugins enable --offline \ rabbitmq_auth_backend_http \ rabbitmq_management \ diff --git a/package.json b/package.json index 4203bbd384..2bd1d45fbf 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "bowser": "2.11.0", "browser-speech": "1.1.1", "events": "3.3.0", - "farmbot": "15.8.0", + "farmbot": "15.8.1", "i18next": "23.5.1", "lodash": "4.17.21", "markdown-it": "13.0.2", From 2afed35fbde634168867a66eba38faacf87129f3 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Thu, 5 Oct 2023 10:59:12 -0700 Subject: [PATCH 07/10] fix ota_hour_utc calculation --- app/models/device.rb | 2 +- .../__tests__/ota_time_selector_test.tsx | 13 ++++++++++++ .../fbos_settings/ota_time_selector.tsx | 13 +++++++----- spec/models/device_spec.rb | 20 +++++++++---------- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/app/models/device.rb b/app/models/device.rb index 0c6b4cfa57..fefaad4843 100644 --- a/app/models/device.rb +++ b/app/models/device.rb @@ -217,7 +217,7 @@ def self.connection_warning(username) def self.get_utc_ota_hour(timezone, local_ota_hour) utc_offset = Time.now.in_time_zone(timezone).utc_offset / 60 / 60 - (local_ota_hour + utc_offset) % 24 + (local_ota_hour - utc_offset) % 24 end # PROBLEM: The device table has an `ota_hour` column. The diff --git a/frontend/settings/fbos_settings/__tests__/ota_time_selector_test.tsx b/frontend/settings/fbos_settings/__tests__/ota_time_selector_test.tsx index fd0bf84ed5..63264fbe38 100644 --- a/frontend/settings/fbos_settings/__tests__/ota_time_selector_test.tsx +++ b/frontend/settings/fbos_settings/__tests__/ota_time_selector_test.tsx @@ -11,6 +11,7 @@ import React from "react"; import { shallow, mount } from "enzyme"; import { OtaTimeSelector, OtaTimeSelectorRow, DDI_ASAP, + localHourToUtcHour, utcHourToLocalHour, } from "../ota_time_selector"; import { FBSelect } from "../../../ui"; import { fakeDevice } from "../../../__test_support__/resource_index_builder"; @@ -19,6 +20,18 @@ import { fakeTimeSettings } from "../../../__test_support__/fake_time_settings"; import { edit } from "../../../api/crud"; import { updateConfig } from "../../../devices/actions"; +describe("localHourToUtcHour()", () => { + it("converts hour", () => { + expect(localHourToUtcHour(10, -2)).toEqual(12); + }); +}); + +describe("utcHourToLocalHour()", () => { + it("converts hour", () => { + expect(utcHourToLocalHour(12, -2)).toEqual(10); + }); +}); + describe("", () => { const fakeProps = (): OtaTimeSelectorProps => ({ timeSettings: fakeTimeSettings(), diff --git a/frontend/settings/fbos_settings/ota_time_selector.tsx b/frontend/settings/fbos_settings/ota_time_selector.tsx index aa215b77c9..c169555410 100644 --- a/frontend/settings/fbos_settings/ota_time_selector.tsx +++ b/frontend/settings/fbos_settings/ota_time_selector.tsx @@ -10,9 +10,12 @@ import { isNumber, range } from "lodash"; import { getModifiedClassNameSpecifyDefault } from "../default_values"; import { updateConfig } from "../../devices/actions"; -const hourToUtcHour = - (hour: number | undefined, offset: number): number | undefined => - !isNumber(hour) ? undefined : (hour + offset) % 24; +export const localHourToUtcHour = + (hour: number | undefined, offset: number, direction = 1): number | undefined => + !isNumber(hour) ? undefined : (hour - (direction * offset)) % 24; + +export const utcHourToLocalHour = (hour: number | undefined, offset: number) => + localHourToUtcHour(hour, offset, -1); export const DDI_ASAP = (): DropDownItem => ({ label: t("As soon as possible"), value: "", isNull: true }); @@ -28,7 +31,7 @@ const formatHour = (hour: number | undefined, hour24: boolean) => export const OtaTimeSelector = (props: OtaTimeSelectorProps) => { const { device, dispatch, timeSettings } = props; const { utcOffset, hour24 } = timeSettings; - const localHour = hourToUtcHour(device.body.ota_hour_utc, -utcOffset) ?? + const localHour = utcHourToLocalHour(device.body.ota_hour_utc, utcOffset) ?? device.body.ota_hour; const osAutoUpdate = props.sourceFbosConfig("os_auto_update"); const selected = () => { @@ -49,7 +52,7 @@ export const OtaTimeSelector = (props: OtaTimeSelectorProps) => { const newLocalHour = ddi ? parseInt("" + ddi.value) : undefined; dispatch(edit(device, { ota_hour: newLocalHour, - ota_hour_utc: hourToUtcHour(newLocalHour, utcOffset), + ota_hour_utc: localHourToUtcHour(newLocalHour, utcOffset), })); dispatch(save(device.uuid)); }} diff --git a/spec/models/device_spec.rb b/spec/models/device_spec.rb index f8671f8356..926197885e 100644 --- a/spec/models/device_spec.rb +++ b/spec/models/device_spec.rb @@ -6,15 +6,15 @@ # [timezone, local_ota_hour, expected] conversions = [ # DST-free Timezones for easy testing: - ["Africa/Addis_Ababa", 6, 9], - ["Africa/Kampala", 22, 1], - ["Africa/Lagos", 15, 16], - ["Asia/Makassar", 2, 10], - ["Asia/Omsk", 11, 17], - ["Asia/Qatar", 0, 3], - ["Asia/Seoul", 18, 3], - ["Australia/Perth", 21, 5], - ["Etc/GMT+4", 20, 16], + ["Africa/Addis_Ababa", 6, 3], + ["Africa/Kampala", 22, 19], + ["Africa/Lagos", 15, 14], + ["Asia/Makassar", 2, 18], + ["Asia/Omsk", 11, 5], + ["Asia/Qatar", 0, 21], + ["Asia/Seoul", 18, 9], + ["Australia/Perth", 21, 13], + ["Etc/GMT+4", 20, 0], ] it "converts legacy ota_hour to ota_hour_utc" do @@ -28,7 +28,7 @@ d = Device.new(timezone: "US/Arizona", ota_hour: 4) expect(d.ota_hour_utc).to eq(nil) d.validate - expect(d.ota_hour_utc).to eq(21) + expect(d.ota_hour_utc).to eq(11) end it "creates a token" do From 2a3aa4b91a5ea1ee27e7b6d53c101ceb64db9426 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Thu, 5 Oct 2023 11:07:04 -0700 Subject: [PATCH 08/10] upgrade deps --- Gemfile.lock | 2 +- package.json | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8eea52c67b..451616eb05 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -221,7 +221,7 @@ GEM multipart-post (2.3.0) mutations (0.9.1) activesupport - net-imap (0.3.7) + net-imap (0.4.0) date net-protocol net-pop (0.1.2) diff --git a/package.json b/package.json index 2bd1d45fbf..4d571a21de 100644 --- a/package.json +++ b/package.json @@ -31,18 +31,18 @@ "author": "farmbot.io", "license": "MIT", "dependencies": { - "@blueprintjs/core": "5.3.2", - "@blueprintjs/select": "5.0.12", + "@blueprintjs/core": "5.3.3", + "@blueprintjs/select": "5.0.13", "@monaco-editor/react": "4.5.2", "@parcel/transformer-sass": "2.9.3", "@parcel/transformer-typescript-tsc": "2.9.3", "@types/lodash": "4.14.199", "@types/markdown-it": "13.0.2", - "@types/node": "20.7.1", + "@types/node": "20.8.2", "@types/promise-timeout": "1.3.1", - "@types/react": "18.2.23", + "@types/react": "18.2.25", "@types/react-color": "3.0.7", - "@types/react-dom": "18.2.8", + "@types/react-dom": "18.2.10", "@types/ws": "8.5.6", "axios": "1.5.1", "bowser": "2.11.0", @@ -55,8 +55,8 @@ "markdown-it-emoji": "2.0.2", "moment": "2.29.4", "monaco-editor": "0.43.0", - "mqtt": "5.0.5", - "npm": "10.1.0", + "mqtt": "5.1.0", + "npm": "10.2.0", "parcel": "2.9.3", "process": "0.11.10", "promise-timeout": "1.3.0", @@ -65,7 +65,7 @@ "react": "18.2.0", "react-color": "2.19.3", "react-dom": "18.2.0", - "react-redux": "8.1.2", + "react-redux": "8.1.3", "redux": "4.2.1", "redux-immutable-state-invariant": "2.1.0", "redux-thunk": "2.4.2", @@ -78,15 +78,15 @@ "@types/enzyme": "3.10.12", "@types/jest": "29.5.5", "@types/readable-stream": "4.0.3", - "@typescript-eslint/eslint-plugin": "6.7.3", - "@typescript-eslint/parser": "6.7.3", + "@typescript-eslint/eslint-plugin": "6.7.4", + "@typescript-eslint/parser": "6.7.4", "@wojtekmaj/enzyme-adapter-react-17": "0.8.0", "coveralls": "3.1.1", "enzyme": "3.11.0", "eslint": "8.50.0", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-import": "2.28.1", - "eslint-plugin-jest": "27.4.0", + "eslint-plugin-jest": "27.4.2", "eslint-plugin-no-null": "1.0.2", "eslint-plugin-promise": "6.1.1", "eslint-plugin-react": "7.33.2", From 812761cf992a660ef0cd53d996da4f5a7149be36 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Thu, 5 Oct 2023 11:39:16 -0700 Subject: [PATCH 09/10] change url and file open calls --- app/controllers/api/ais_controller.rb | 2 +- app/models/image.rb | 2 +- app/models/release.rb | 2 +- lib/tasks/api.rake | 4 +-- lib/tasks/coverage.rake | 6 ++-- lib/tasks/fe.rake | 4 +-- lib/tasks/releases.rake | 4 +-- spec/controllers/api/ai/ai_controller_spec.rb | 29 +++++-------------- spec/models/release_spec.rb | 8 ++++- 9 files changed, 27 insertions(+), 34 deletions(-) diff --git a/app/controllers/api/ais_controller.rb b/app/controllers/api/ais_controller.rb index 0251697457..22a56642da 100644 --- a/app/controllers/api/ais_controller.rb +++ b/app/controllers/api/ais_controller.rb @@ -232,7 +232,7 @@ def page_url(page_name) def get_page_data(page_name) url = page_url(page_name) begin - URI.open(url).read + URI.parse(url).open.read rescue SocketError => exception puts "AI Lua docs fetch error: #{exception.message}" unless Rails.env.test? end diff --git a/app/models/image.rb b/app/models/image.rb index 1f9ffe157b..22405d9a40 100644 --- a/app/models/image.rb +++ b/app/models/image.rb @@ -43,7 +43,7 @@ def set_defaults has_one_attached :attachment def set_attachment_by_url(url) - io = URI.open(url) + io = URI.parse(url).open fname = "image_#{self.id}" params = { io: io, filename: fname } attachment.attach(**params) diff --git a/app/models/release.rb b/app/models/release.rb index 31360963ed..dbb2bcddff 100644 --- a/app/models/release.rb +++ b/app/models/release.rb @@ -22,7 +22,7 @@ class Release < ApplicationRecord def self.transload(url, gcs = Google::Cloud::Storage.new) file_name = url.split("/").last tempdir = "#{Rails.root.join("tmp").to_s}/#{file_name}" - download = URI.open(url) + download = URI.parse(url).open IO.copy_stream(download, tempdir) bucket = gcs.bucket(ENV.fetch("GCS_BUCKET")) file = bucket.upload_file tempdir, "releases/#{file_name}" diff --git a/lib/tasks/api.rake b/lib/tasks/api.rake index 31567c6c62..a9ee31c872 100644 --- a/lib/tasks/api.rake +++ b/lib/tasks/api.rake @@ -136,8 +136,8 @@ namespace :api do # 60 days is the current policy. cutoff = 60.days.ago # Download release data from github - string_page_1 = URI.open("#{RELEASES_URL}?per_page=100&page=1").read - string_page_2 = URI.open("#{RELEASES_URL}?per_page=100&page=2").read + string_page_1 = URI.parse("#{RELEASES_URL}?per_page=100&page=1").open.read + string_page_2 = URI.parse("#{RELEASES_URL}?per_page=100&page=2").open.read data = JSON.parse(string_page_1).push(*JSON.parse(string_page_2)) .map { |x| x.slice(VERSION, TIMESTAMP, PRERELEASE) } # Only grab keys that matter .reject { |x| x.fetch(VERSION).include?("-") } # Remove RC/Beta releases diff --git a/lib/tasks/coverage.rake b/lib/tasks/coverage.rake index 04e399c428..4925f4d80c 100644 --- a/lib/tasks/coverage.rake +++ b/lib/tasks/coverage.rake @@ -15,7 +15,7 @@ FRACTION_DELIM = "/" # Fetch JSON over HTTP. Rails probably already has a helper for this :shrug: def open_json(url) begin - JSON.parse(URI.open(url).read) + JSON.parse(URI.parse(url).open.read) rescue *[OpenURI::HTTPError, SocketError] => exception puts exception.message return {} @@ -131,7 +131,7 @@ end def get_json_coverage_results() results = { lines: { covered: 0, total: 0 }, branches: { covered: 0, total: 0 } } begin - data = open_json(JSON_COVERAGE_FILE_PATH) + data = JSON.parse(File.open(JSON_COVERAGE_FILE_PATH).read) rescue Errno::ENOENT return results end @@ -191,7 +191,7 @@ namespace :coverage do begin # Fetch current build coverage data from the HTML summary. statements, branches, functions, lines = - Nokogiri::HTML(URI.open(COVERAGE_FILE_PATH)) + Nokogiri::HTML(File.open(COVERAGE_FILE_PATH)) .css(CSS_SELECTOR) .map(&:text) .map { |x| x.split(FRACTION_DELIM).map(&:to_f) } diff --git a/lib/tasks/fe.rake b/lib/tasks/fe.rake index 0d7f637f4a..7ef02130b1 100644 --- a/lib/tasks/fe.rake +++ b/lib/tasks/fe.rake @@ -11,12 +11,12 @@ EXCLUDE = [ # Load package.json as JSON. def load_package_json() - return JSON.parse(URI.open(PACKAGE_JSON_FILE).read) + return JSON.parse(File.open(PACKAGE_JSON_FILE).read) end # Save JSON to package.json. def save_package_json(json) - URI.open(PACKAGE_JSON_FILE, "w") { |file| + File.open(PACKAGE_JSON_FILE, "w") { |file| file.write(JSON.pretty_generate(json)) file.puts } diff --git a/lib/tasks/releases.rake b/lib/tasks/releases.rake index 8eb0c88856..4dddfd4678 100644 --- a/lib/tasks/releases.rake +++ b/lib/tasks/releases.rake @@ -17,7 +17,7 @@ namespace :releases do module ReleaseTask def self.download_metadata(tag_name) real_url = "https://api.github.com/repos/farmbot/farmbot_os/releases/tags/#{tag_name}" - JSON.parse(URI.open(real_url).read, symbolize_names: true) + JSON.parse(URI.parse(real_url).open.read, symbolize_names: true) end def self.select_version(choices) @@ -31,7 +31,7 @@ namespace :releases do def self.get_release_list uri = "https://api.github.com/repos/farmbot/farmbot_os/releases" - file = URI.open(uri) + file = URI.parse(uri).open raw_json = file.read json = JSON.parse(raw_json, symbolize_names: true).pluck(:tag_name) json.first(9).sort.reverse diff --git a/spec/controllers/api/ai/ai_controller_spec.rb b/spec/controllers/api/ai/ai_controller_spec.rb index aa6fa7d22f..c8c324c023 100644 --- a/spec/controllers/api/ai/ai_controller_spec.rb +++ b/spec/controllers/api/ai/ai_controller_spec.rb @@ -5,12 +5,6 @@ let(:user) { FactoryBot.create(:user) } let(:sequence) { FakeSequence.create(device: user.device) } - class MockGet - def read - "---\n---# section\ncontent```lua\n```" - end - end - def chunk(content, done=nil) "data: {\"id\":\"id\",\"object\":\"chat.completion.chunk\"," \ "\"created\":12345,\"model\":\"gpt-4\",\"choices\":[{\"delta\":{" \ @@ -27,7 +21,9 @@ def chunk(content, done=nil) context_key: "lua", sequence_id: nil, } - expect(URI).to receive(:open).exactly(15).times.and_return(MockGet.new()) + + stub_request(:get, /raw.githubusercontent.com/).to_return( + body: "---\n---# section\ncontent```lua\n```") stub_request(:post, "https://api.openai.com/v1/chat/completions").to_return( body: chunk("return") + chunk("done", done="stop")) @@ -44,7 +40,6 @@ def chunk(content, done=nil) context_key: "color", sequence_id: sequence.id, } - expect(URI).to receive(:open).exactly(0).times stub_request(:post, "https://api.openai.com/v1/chat/completions").to_return( body: chunk("red")) @@ -63,7 +58,8 @@ def chunk(content, done=nil) context_key: "lua", sequence_id: nil, } - expect(URI).to receive(:open).exactly(15).times.and_return(MockGet.new()) + stub_request(:get, /raw.githubusercontent.com/).to_return( + body: "---\n---# section\ncontent```lua\n```") stub_request(:post, "https://api.openai.com/v1/chat/completions").to_timeout @@ -79,12 +75,7 @@ def chunk(content, done=nil) sequence_id: nil, } - class MockGetError - def read - raise SocketError - end - end - expect(URI).to receive(:open).exactly(1).times.and_return(MockGetError.new()) + stub_request(:get, /raw.githubusercontent.com/).to_raise(SocketError) stub_request(:post, "https://api.openai.com/v1/chat/completions").to_timeout @@ -100,12 +91,8 @@ def read sequence_id: nil, } - class MockGetEmpty - def read - "---\n---# nothing for now\n" - end - end - expect(URI).to receive(:open).at_least(1).times.and_return(MockGetEmpty.new()) + stub_request(:get, /raw.githubusercontent.com/).to_return( + body: "---\n---# nothing for now\n") stub_request(:post, "https://api.openai.com/v1/chat/completions").to_return( body: chunk("red")) diff --git a/spec/models/release_spec.rb b/spec/models/release_spec.rb index dfc5a1ecb6..77803f3fcd 100644 --- a/spec/models/release_spec.rb +++ b/spec/models/release_spec.rb @@ -38,6 +38,12 @@ expect(Release.latest_image(platform: "rpi")).to eq(expected2) end + class MockParsed + def open + "fake_fw_file" + end + end + # Not a fan of this test due to the high number of stubs # and doubles. This is a mostly internal method, so I will # leave it as is for now.. @@ -48,7 +54,7 @@ fake_bucket = "fake-bucket-name" fake_final_url = "http://gcs/new_location.fw" - expect(URI).to receive(:open).with(starting_url).and_return(fake_file) + expect(URI).to receive(:parse).with(starting_url).and_return(MockParsed.new()) expect(IO).to receive(:copy_stream).with(fake_file, fake_local_path) gcs_file = double("fake GCS File obj", url: fake_final_url) bucket = double(Google::Cloud::Storage::Bucket, upload_file: gcs_file) From 444ad76f1504de0f4aadc1e20c7af56dd79ab672 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Tue, 10 Oct 2023 11:17:40 -0700 Subject: [PATCH 10/10] upgrade deps --- Gemfile.lock | 10 +++++----- package.json | 24 ++++++++++++------------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 451616eb05..de6fe155f0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -45,9 +45,9 @@ GEM erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - active_model_serializers (0.10.13) - actionpack (>= 4.1, < 7.1) - activemodel (>= 4.1, < 7.1) + active_model_serializers (0.10.14) + actionpack (>= 4.1) + activemodel (>= 4.1) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) activejob (6.1.7.6) @@ -205,7 +205,7 @@ GEM activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.21.3) + loofah (2.21.4) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -221,7 +221,7 @@ GEM multipart-post (2.3.0) mutations (0.9.1) activesupport - net-imap (0.4.0) + net-imap (0.4.1) date net-protocol net-pop (0.1.2) diff --git a/package.json b/package.json index 4d571a21de..ab30af16e1 100644 --- a/package.json +++ b/package.json @@ -31,18 +31,18 @@ "author": "farmbot.io", "license": "MIT", "dependencies": { - "@blueprintjs/core": "5.3.3", - "@blueprintjs/select": "5.0.13", - "@monaco-editor/react": "4.5.2", + "@blueprintjs/core": "5.4.0", + "@blueprintjs/select": "5.0.14", + "@monaco-editor/react": "4.6.0", "@parcel/transformer-sass": "2.9.3", "@parcel/transformer-typescript-tsc": "2.9.3", "@types/lodash": "4.14.199", "@types/markdown-it": "13.0.2", - "@types/node": "20.8.2", + "@types/node": "20.8.4", "@types/promise-timeout": "1.3.1", - "@types/react": "18.2.25", + "@types/react": "18.2.27", "@types/react-color": "3.0.7", - "@types/react-dom": "18.2.10", + "@types/react-dom": "18.2.12", "@types/ws": "8.5.6", "axios": "1.5.1", "bowser": "2.11.0", @@ -54,8 +54,8 @@ "markdown-it": "13.0.2", "markdown-it-emoji": "2.0.2", "moment": "2.29.4", - "monaco-editor": "0.43.0", - "mqtt": "5.1.0", + "monaco-editor": "0.44.0", + "mqtt": "5.1.2", "npm": "10.2.0", "parcel": "2.9.3", "process": "0.11.10", @@ -78,12 +78,12 @@ "@types/enzyme": "3.10.12", "@types/jest": "29.5.5", "@types/readable-stream": "4.0.3", - "@typescript-eslint/eslint-plugin": "6.7.4", - "@typescript-eslint/parser": "6.7.4", + "@typescript-eslint/eslint-plugin": "6.7.5", + "@typescript-eslint/parser": "6.7.5", "@wojtekmaj/enzyme-adapter-react-17": "0.8.0", "coveralls": "3.1.1", "enzyme": "3.11.0", - "eslint": "8.50.0", + "eslint": "8.51.0", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-import": "2.28.1", "eslint-plugin-jest": "27.4.2", @@ -101,7 +101,7 @@ "raf": "3.4.1", "react-addons-test-utils": "15.6.2", "react-test-renderer": "18.2.0", - "sass": "1.68.0", + "sass": "1.69.1", "sass-lint": "1.13.1", "ts-jest": "29.1.1", "tslint": "6.1.3"