Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/tests-rc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ jobs:

- name: Deposit to chequebook
run: |
swarm-cli cheque deposit 100000000000000000
swarm-cli cheque deposit 100000000000000000 --bee-api-url http://localhost:11633
swarm-cli cheque deposit 100000000000000000 --bee-api-url http://localhost:21633
swarm-cli cheque deposit 100000000000000000 --bee-api-url http://localhost:31633
swarm-cli cheque deposit 100000000000000000 --bee-api-url http://localhost:41633
swarm-cli cheque deposit 10
swarm-cli cheque deposit 10 --bee-api-url http://localhost:11633
swarm-cli cheque deposit 10 --bee-api-url http://localhost:21633
swarm-cli cheque deposit 10 --bee-api-url http://localhost:31633
swarm-cli cheque deposit 10 --bee-api-url http://localhost:41633

- name: Print swarm-cli status
continue-on-error: true
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ jobs:

- name: Deposit to chequebook
run: |
swarm-cli cheque deposit 100000000000000000
swarm-cli cheque deposit 100000000000000000 --bee-api-url http://localhost:11633
swarm-cli cheque deposit 100000000000000000 --bee-api-url http://localhost:21633
swarm-cli cheque deposit 100000000000000000 --bee-api-url http://localhost:31633
swarm-cli cheque deposit 100000000000000000 --bee-api-url http://localhost:41633
swarm-cli cheque deposit 10
swarm-cli cheque deposit 10 --bee-api-url http://localhost:11633
swarm-cli cheque deposit 10 --bee-api-url http://localhost:21633
swarm-cli cheque deposit 10 --bee-api-url http://localhost:31633
swarm-cli cheque deposit 10 --bee-api-url http://localhost:41633

- name: Print swarm-cli status
continue-on-error: true
Expand Down
2 changes: 2 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export default async (): Promise<Config.InitialOptions> => {
*/
const console = new CommandLog(VerbosityLevel.Normal)

process.env.SKIP_VERSION_CHECK = 'true'

if (!process.env.SKIP_WORKER) {
process.env.WORKER_PSS_ADDRESS = (await getPssAddress('http://localhost:11633')).toCompressedHex()
}
Expand Down
4 changes: 4 additions & 0 deletions src/command/root-command/command-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ export class CommandConfig {
return process.env.SWARM_CLI_HISTORY_FILE_PATH || join(this.configFolderPath, 'upload-history.json')
}

public getVersionCheckFilePath(): string {
return process.env.SWARM_CLI_VERSION_CHECK_FILE_PATH || join(this.configFolderPath, 'version-check.json')
}

public setHistoryEnabled(enabled: boolean): void {
this.config.historyEnabled = enabled
this.saveConfig()
Expand Down
17 changes: 17 additions & 0 deletions src/command/root-command/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { parseHeaders } from '../../utils'
import { ConfigOption } from '../../utils/types/config-option'
import { CONFIG_OPTIONS, CommandConfig } from './command-config'
import { CommandLog, VerbosityLevel } from './command-log'
import { checkForUpdates, getLatestVersionCheck } from '../../service/version_checker'
import PackageJson from '../../../package.json'
import { warningText } from '../../utils/text'

export class RootCommand {
@ExternalOption('bee-api-url')
Expand Down Expand Up @@ -79,6 +82,20 @@ export class RootCommand {
this.verbosity = VerbosityLevel.Verbose
}
this.console = new CommandLog(this.verbosity)

if (!this.quiet) {
const latestVersionCheck = getLatestVersionCheck(this.commandConfig)

if (latestVersionCheck === null) {
checkForUpdates(this.commandConfig)
} else if (latestVersionCheck.latestVersion !== PackageJson.version) {
this.console.log(
warningText(
`A new version of swarm-cli is available: ${latestVersionCheck.latestVersion}. You are using version ${PackageJson.version}. Please update to get the latest features and fixes.`,
),
)
}
}
}

private maybeSetFromConfig(option: ConfigOption): void {
Expand Down
64 changes: 64 additions & 0 deletions src/service/version_checker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { existsSync, readFileSync, writeFileSync } from 'fs'
import PackageJson from '../../package.json'
import { CommandConfig } from '../command/root-command/command-config'
import fetch from 'node-fetch'
import { Dates } from 'cafe-utility'

const LATEST_RELEASE_URL = 'https://api.github.com/repos/ethersphere/swarm-cli/releases/latest'

type VersionCheckData = {
latestVersion: string
expiresAt: number
}

export async function checkForUpdates(config: CommandConfig) {
if (process.env.SKIP_VERSION_CHECK === 'true') {
return
}

const filePath = config.getVersionCheckFilePath()

try {
const response = await fetch(LATEST_RELEASE_URL)

if (!response.ok) {
return
}

const data = (await response.json()) as { tag_name: string }
const latestVersion = data.tag_name.replace(/^v/, '')
const versionCheckData = {
latestVersion,
expiresAt: Date.now() + Dates.days(1),
}

if (latestVersion !== PackageJson.version) {
writeFileSync(filePath, JSON.stringify(versionCheckData))
}
} catch {
return
}
}

export function getLatestVersionCheck(config: CommandConfig): VersionCheckData | null {
const filePath = config.getVersionCheckFilePath()

if (!existsSync(filePath)) {
return null
}

try {
const data = JSON.parse(readFileSync(filePath).toString()) as VersionCheckData

if (Date.now() > data.expiresAt) {
return null
}

return {
latestVersion: data.latestVersion,
expiresAt: data.expiresAt,
}
} catch {
return null
}
}
30 changes: 30 additions & 0 deletions test/command/version-warning.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import fetch, { Response } from 'node-fetch'
import PackageJson from '../../package.json'
import { describeCommand, invokeTestCli } from '../utility'
import { existsSync, unlinkSync } from 'fs'

jest.mock('node-fetch')
const mockedFetch = fetch as jest.MockedFunction<typeof fetch>

describeCommand('Test Outdated Version Warning', ({ hasMessageContaining }) => {
afterEach(() => {
if (existsSync('./test/testconfig/version-check.json')) {
unlinkSync('./test/testconfig/version-check.json')
}
})
it('should print warning when version is outdated', async () => {
process.env.SKIP_VERSION_CHECK = 'false'
mockedFetch.mockResolvedValue({
ok: true,
json: () => Promise.resolve({ tag_name: 'v999.0.0' }),
} as unknown as Response)
await invokeTestCli(['status'])
await invokeTestCli(['status'])
expect(
hasMessageContaining(
`A new version of swarm-cli is available: 999.0.0. You are using version ${PackageJson.version}. Please update to get the latest features and fixes.`,
),
).toBe(true)
process.env.SKIP_VERSION_CHECK = 'true'
})
})
7 changes: 4 additions & 3 deletions test/coverage/coverage-summary.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{"total": {"lines":{"total":2863,"covered":2186,"skipped":0,"pct":76.35},"statements":{"total":2884,"covered":2200,"skipped":0,"pct":76.28},"functions":{"total":343,"covered":271,"skipped":0,"pct":79},"branches":{"total":621,"covered":353,"skipped":0,"pct":56.84},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}
{"total": {"lines":{"total":2902,"covered":2221,"skipped":0,"pct":76.53},"statements":{"total":2923,"covered":2235,"skipped":0,"pct":76.46},"functions":{"total":346,"covered":274,"skipped":0,"pct":79.19},"branches":{"total":632,"covered":361,"skipped":0,"pct":57.12},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}
,"/home/runner/work/swarm-cli/swarm-cli/src/application.ts": {"lines":{"total":2,"covered":0,"skipped":0,"pct":0},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":2,"covered":0,"skipped":0,"pct":0},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
,"/home/runner/work/swarm-cli/swarm-cli/src/config.ts": {"lines":{"total":33,"covered":32,"skipped":0,"pct":96.96},"functions":{"total":1,"covered":0,"skipped":0,"pct":0},"statements":{"total":33,"covered":32,"skipped":0,"pct":96.96},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
,"/home/runner/work/swarm-cli/swarm-cli/src/curl.ts": {"lines":{"total":24,"covered":24,"skipped":0,"pct":100},"functions":{"total":7,"covered":7,"skipped":0,"pct":100},"statements":{"total":25,"covered":25,"skipped":0,"pct":100},"branches":{"total":13,"covered":12,"skipped":0,"pct":92.3}}
Expand Down Expand Up @@ -63,9 +63,9 @@
,"/home/runner/work/swarm-cli/swarm-cli/src/command/pss/receive.ts": {"lines":{"total":24,"covered":18,"skipped":0,"pct":75},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":24,"covered":18,"skipped":0,"pct":75},"branches":{"total":6,"covered":2,"skipped":0,"pct":33.33}}
,"/home/runner/work/swarm-cli/swarm-cli/src/command/pss/send.ts": {"lines":{"total":34,"covered":29,"skipped":0,"pct":85.29},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":34,"covered":29,"skipped":0,"pct":85.29},"branches":{"total":5,"covered":2,"skipped":0,"pct":40}}
,"/home/runner/work/swarm-cli/swarm-cli/src/command/pss/subscribe.ts": {"lines":{"total":18,"covered":8,"skipped":0,"pct":44.44},"functions":{"total":5,"covered":1,"skipped":0,"pct":20},"statements":{"total":18,"covered":8,"skipped":0,"pct":44.44},"branches":{"total":4,"covered":0,"skipped":0,"pct":0}}
,"/home/runner/work/swarm-cli/swarm-cli/src/command/root-command/command-config.ts": {"lines":{"total":39,"covered":33,"skipped":0,"pct":84.61},"functions":{"total":8,"covered":8,"skipped":0,"pct":100},"statements":{"total":42,"covered":35,"skipped":0,"pct":83.33},"branches":{"total":11,"covered":6,"skipped":0,"pct":54.54}}
,"/home/runner/work/swarm-cli/swarm-cli/src/command/root-command/command-config.ts": {"lines":{"total":40,"covered":34,"skipped":0,"pct":85},"functions":{"total":9,"covered":9,"skipped":0,"pct":100},"statements":{"total":43,"covered":36,"skipped":0,"pct":83.72},"branches":{"total":13,"covered":7,"skipped":0,"pct":53.84}}
,"/home/runner/work/swarm-cli/swarm-cli/src/command/root-command/command-log.ts": {"lines":{"total":78,"covered":60,"skipped":0,"pct":76.92},"functions":{"total":9,"covered":6,"skipped":0,"pct":66.66},"statements":{"total":78,"covered":60,"skipped":0,"pct":76.92},"branches":{"total":11,"covered":7,"skipped":0,"pct":63.63}}
,"/home/runner/work/swarm-cli/swarm-cli/src/command/root-command/index.ts": {"lines":{"total":44,"covered":40,"skipped":0,"pct":90.9},"functions":{"total":4,"covered":4,"skipped":0,"pct":100},"statements":{"total":44,"covered":40,"skipped":0,"pct":90.9},"branches":{"total":9,"covered":5,"skipped":0,"pct":55.55}}
,"/home/runner/work/swarm-cli/swarm-cli/src/command/root-command/index.ts": {"lines":{"total":53,"covered":49,"skipped":0,"pct":92.45},"functions":{"total":4,"covered":4,"skipped":0,"pct":100},"statements":{"total":53,"covered":49,"skipped":0,"pct":92.45},"branches":{"total":13,"covered":9,"skipped":0,"pct":69.23}}
,"/home/runner/work/swarm-cli/swarm-cli/src/command/root-command/printer.ts": {"lines":{"total":9,"covered":9,"skipped":0,"pct":100},"functions":{"total":6,"covered":6,"skipped":0,"pct":100},"statements":{"total":9,"covered":9,"skipped":0,"pct":100},"branches":{"total":1,"covered":1,"skipped":0,"pct":100}}
,"/home/runner/work/swarm-cli/swarm-cli/src/command/stake/deposit.ts": {"lines":{"total":40,"covered":31,"skipped":0,"pct":77.5},"functions":{"total":3,"covered":3,"skipped":0,"pct":100},"statements":{"total":40,"covered":31,"skipped":0,"pct":77.5},"branches":{"total":17,"covered":11,"skipped":0,"pct":64.7}}
,"/home/runner/work/swarm-cli/swarm-cli/src/command/stake/index.ts": {"lines":{"total":8,"covered":8,"skipped":0,"pct":100},"functions":{"total":1,"covered":1,"skipped":0,"pct":100},"statements":{"total":8,"covered":8,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
Expand All @@ -92,6 +92,7 @@
,"/home/runner/work/swarm-cli/swarm-cli/src/command/wallet/status.ts": {"lines":{"total":11,"covered":11,"skipped":0,"pct":100},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":11,"covered":11,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
,"/home/runner/work/swarm-cli/swarm-cli/src/command/wallet/withdraw-bzz.ts": {"lines":{"total":21,"covered":19,"skipped":0,"pct":90.47},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":21,"covered":19,"skipped":0,"pct":90.47},"branches":{"total":6,"covered":3,"skipped":0,"pct":50}}
,"/home/runner/work/swarm-cli/swarm-cli/src/command/wallet/withdraw-dai.ts": {"lines":{"total":21,"covered":19,"skipped":0,"pct":90.47},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":21,"covered":19,"skipped":0,"pct":90.47},"branches":{"total":6,"covered":3,"skipped":0,"pct":50}}
,"/home/runner/work/swarm-cli/swarm-cli/src/service/version_checker.ts": {"lines":{"total":29,"covered":25,"skipped":0,"pct":86.2},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":29,"covered":25,"skipped":0,"pct":86.2},"branches":{"total":5,"covered":3,"skipped":0,"pct":60}}
,"/home/runner/work/swarm-cli/swarm-cli/src/service/history/index.ts": {"lines":{"total":21,"covered":19,"skipped":0,"pct":90.47},"functions":{"total":5,"covered":5,"skipped":0,"pct":100},"statements":{"total":22,"covered":20,"skipped":0,"pct":90.9},"branches":{"total":1,"covered":1,"skipped":0,"pct":100}}
,"/home/runner/work/swarm-cli/swarm-cli/src/service/identity/index.ts": {"lines":{"total":36,"covered":32,"skipped":0,"pct":88.88},"functions":{"total":7,"covered":7,"skipped":0,"pct":100},"statements":{"total":36,"covered":32,"skipped":0,"pct":88.88},"branches":{"total":9,"covered":6,"skipped":0,"pct":66.66}}
,"/home/runner/work/swarm-cli/swarm-cli/src/service/identity/types/identity.ts": {"lines":{"total":4,"covered":4,"skipped":0,"pct":100},"functions":{"total":1,"covered":1,"skipped":0,"pct":100},"statements":{"total":4,"covered":4,"skipped":0,"pct":100},"branches":{"total":2,"covered":2,"skipped":0,"pct":100}}
Expand Down
1 change: 1 addition & 0 deletions test/utility/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export function describeCommand(
configFileName ? `${configFileName}-upload-history.json` : 'upload-history.json',
)
process.env.SWARM_CLI_HISTORY_FILE_PATH = historyFilePath
process.env.SWARM_CLI_VERSION_CHECK_FILE_PATH = join(configFolderPath, 'version-check.json')

//if own config is needed
if (configFileName) {
Expand Down