From c83d049c7632dd4b48668baa7e952e61dfefe258 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Mon, 13 Feb 2023 14:50:10 -0800 Subject: [PATCH 01/18] =?UTF-8?q?First=20crack=20at=20=E2=80=9Clatest-nigh?= =?UTF-8?q?tly=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/main.yml | 2 +- index.js | 28 +++++++++++++++++++++++++++- test/setup-dafny-action.js | 8 ++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 320eb21..f1b6439 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,7 +15,7 @@ jobs: fail-fast: false matrix: os: [macos-latest, ubuntu-latest, windows-latest] - dafny: [3.0.0, 3.7.3, 3.8.1, nightly-2022-09-23-2bc0042] + dafny: [3.0.0, 3.7.3, 3.8.1, nightly-2022-09-23-2bc0042, nightly-latest] # Windows 2.3.0 requires mono include: - os: macos-latest diff --git a/index.js b/index.js index e25eca7..2517c43 100644 --- a/index.js +++ b/index.js @@ -36,12 +36,38 @@ async function installDotnetTool(toolName, version) { exports.dafnyURL = dafnyURL; exports.getDistribution = getDistribution; -function dafnyURL(version, distribution) { +async function dafnyURL(version, distribution) { const versionPath = version.startsWith("nightly") ? "nightly" : `v${version}`; + if (version == "nightly-latest") { + version = await latestNightlyVersion() + } const root = "https://github.com/dafny-lang/dafny/releases/download"; return `${root}/${versionPath}/dafny-${version == "2.3.0" ? "2.3.0.10506" : version}-x64-${distribution}.zip`; } +async function latestNightlyVersion() { + // Shamelessly copied from dafny-lang/ide-vscode + // I'd prefer to use the GitHub API to list the assets under the "nightly" release, + // but @actions/github requires authentication. + // This method has the advantage of relying on more rigourous dotnet tool metadata at least. + const { stdout } = await execFileAsync("dotnet", [ 'tool', 'search', 'Dafny', '--detail', '--prerelease' ]) + const entries = stdout.split('----------------').map(entry => entry.split('\n').filter(e => e !== '')) + const dafnyEntry = entries.filter(entry => entry[0] === 'dafny')[0] + const versionsIndex = dafnyEntry.findIndex(v => v.startsWith('Versions:')) + const versions = dafnyEntry.slice(versionsIndex + 1).map(versionLine => versionLine.trimStart().split(' ')[0]) + + const nightlies = versions.filter(l => l.includes('nightly')) + const dates = nightlies.map((n, index) => { + const split = n.split('-'); + return { index, date: split[2] + split[3] + split[4] } + }); + dates.sort((a, b) => a.date < b.date ? 1 : -1) + toolVersion = nightlies[dates[0].index] + + core.info(`Using latest nightly version: ${toolVersion}`); + return toolVersion +} + function getDistribution(platform, version) { return platform === "darwin" // Osx ? version == "2.3.0" ? "osx-10.14.1" : "osx-10.14.2" diff --git a/test/setup-dafny-action.js b/test/setup-dafny-action.js index 2abe00d..0790b93 100644 --- a/test/setup-dafny-action.js +++ b/test/setup-dafny-action.js @@ -16,6 +16,14 @@ describe("dafnyURL", () => { ); }); + // TODO: Really we want to say "latest 3.x nightly" so that we don't automatically pick up major version bumps + it("latest nightly usage", () => { + const test = dafnyURL("latest-nightly", "ubuntu-16.04"); + expect(test).to.match( + /^https:\/\/github.com\/dafny-lang\/dafny\/releases\/download\/nightly\/dafny-nightly-/ + ); + }); + it("version 2.3.0", () => { const test = dafnyURL("2.3.0", "win"); // https://github.com/dafny-lang/dafny/releases/download/v2.3.0/dafny-2.3.0.10506-x64-osx-10.14.1.zip From 7fff98609007d8ad3e88777d9d3f142b83e9b5a7 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Mon, 13 Feb 2023 15:04:42 -0800 Subject: [PATCH 02/18] Fixes (turns out running npm test first helps :) --- .github/workflows/main.yml | 2 +- index.js | 2 +- test/setup-dafny-action.js | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f1b6439..5799018 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,7 +15,7 @@ jobs: fail-fast: false matrix: os: [macos-latest, ubuntu-latest, windows-latest] - dafny: [3.0.0, 3.7.3, 3.8.1, nightly-2022-09-23-2bc0042, nightly-latest] + dafny: [3.0.0, 3.7.3, 3.8.1, nightly-2023-02-13-14bc57f, nightly-latest] # Windows 2.3.0 requires mono include: - os: macos-latest diff --git a/index.js b/index.js index 2517c43..a527e9d 100644 --- a/index.js +++ b/index.js @@ -50,7 +50,7 @@ async function latestNightlyVersion() { // I'd prefer to use the GitHub API to list the assets under the "nightly" release, // but @actions/github requires authentication. // This method has the advantage of relying on more rigourous dotnet tool metadata at least. - const { stdout } = await execFileAsync("dotnet", [ 'tool', 'search', 'Dafny', '--detail', '--prerelease' ]) + const { exitCode, stdout, stderr } = await exec.getExecOutput("dotnet", [ 'tool', 'search', 'Dafny', '--detail', '--prerelease' ], {silent: true}) const entries = stdout.split('----------------').map(entry => entry.split('\n').filter(e => e !== '')) const dafnyEntry = entries.filter(entry => entry[0] === 'dafny')[0] const versionsIndex = dafnyEntry.findIndex(v => v.startsWith('Versions:')) diff --git a/test/setup-dafny-action.js b/test/setup-dafny-action.js index 0790b93..9073c96 100644 --- a/test/setup-dafny-action.js +++ b/test/setup-dafny-action.js @@ -2,30 +2,30 @@ const { dafnyURL, getDistribution } = require("../index"); const { expect } = require("chai"); describe("dafnyURL", () => { - it("basic usage", () => { - const test = dafnyURL("3.8.1", "win"); + it("basic usage", async () => { + const test = await dafnyURL("3.8.1", "win"); expect(test).to.equal( "https://github.com/dafny-lang/dafny/releases/download/v3.8.1/dafny-3.8.1-x64-win.zip" ); }); - it("nightly usage", () => { - const test = dafnyURL("nightly-2022-09-23-2bc0042", "ubuntu-16.04"); + it("nightly usage", async () => { + const test = await dafnyURL("nightly-2022-09-23-2bc0042", "ubuntu-16.04"); expect(test).to.equal( "https://github.com/dafny-lang/dafny/releases/download/nightly/dafny-nightly-2022-09-23-2bc0042-x64-ubuntu-16.04.zip" ); }); // TODO: Really we want to say "latest 3.x nightly" so that we don't automatically pick up major version bumps - it("latest nightly usage", () => { - const test = dafnyURL("latest-nightly", "ubuntu-16.04"); + it("latest nightly usage", async () => { + const test = await dafnyURL("nightly-latest", "ubuntu-16.04"); expect(test).to.match( - /^https:\/\/github.com\/dafny-lang\/dafny\/releases\/download\/nightly\/dafny-nightly-/ + /^https:\/\/github.com\/dafny-lang\/dafny\/releases\/download\/nightly\/dafny-.*-nightly-/ ); }); - it("version 2.3.0", () => { - const test = dafnyURL("2.3.0", "win"); + it("version 2.3.0", async () => { + const test = await dafnyURL("2.3.0", "win"); // https://github.com/dafny-lang/dafny/releases/download/v2.3.0/dafny-2.3.0.10506-x64-osx-10.14.1.zip // https://github.com/dafny-lang/dafny/releases/download/v2.3.0/dafny-2.3.0.10506-x64-ubuntu-16.04.zip // https://github.com/dafny-lang/dafny/releases/download/v2.3.0/dafny-2.3.0.10506-x64-win.zip From eabad98afc5d430c661ebd72a1bb649dc222e9ca Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Mon, 13 Feb 2023 15:08:31 -0800 Subject: [PATCH 03/18] So does npm run package --- dist/index.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/dist/index.js b/dist/index.js index 031e57a..fbd3004 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6724,12 +6724,38 @@ async function installDotnetTool(toolName, version) { exports.dafnyURL = dafnyURL; exports.getDistribution = getDistribution; -function dafnyURL(version, distribution) { +async function dafnyURL(version, distribution) { const versionPath = version.startsWith("nightly") ? "nightly" : `v${version}`; + if (version == "nightly-latest") { + version = await latestNightlyVersion() + } const root = "https://github.com/dafny-lang/dafny/releases/download"; return `${root}/${versionPath}/dafny-${version == "2.3.0" ? "2.3.0.10506" : version}-x64-${distribution}.zip`; } +async function latestNightlyVersion() { + // Shamelessly copied from dafny-lang/ide-vscode + // I'd prefer to use the GitHub API to list the assets under the "nightly" release, + // but @actions/github requires authentication. + // This method has the advantage of relying on more rigourous dotnet tool metadata at least. + const { exitCode, stdout, stderr } = await exec.getExecOutput("dotnet", [ 'tool', 'search', 'Dafny', '--detail', '--prerelease' ], {silent: true}) + const entries = stdout.split('----------------').map(entry => entry.split('\n').filter(e => e !== '')) + const dafnyEntry = entries.filter(entry => entry[0] === 'dafny')[0] + const versionsIndex = dafnyEntry.findIndex(v => v.startsWith('Versions:')) + const versions = dafnyEntry.slice(versionsIndex + 1).map(versionLine => versionLine.trimStart().split(' ')[0]) + + const nightlies = versions.filter(l => l.includes('nightly')) + const dates = nightlies.map((n, index) => { + const split = n.split('-'); + return { index, date: split[2] + split[3] + split[4] } + }); + dates.sort((a, b) => a.date < b.date ? 1 : -1) + toolVersion = nightlies[dates[0].index] + + core.info(`Using latest nightly version: ${toolVersion}`); + return toolVersion +} + function getDistribution(platform, version) { return platform === "darwin" // Osx ? version == "2.3.0" ? "osx-10.14.1" : "osx-10.14.2" From 98646ae8a0d33de3b3df13645c00a85bb18a4123 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Mon, 13 Feb 2023 15:14:24 -0800 Subject: [PATCH 04/18] Formatting, missing await --- index.js | 58 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/index.js b/index.js index a527e9d..fa7b5f7 100644 --- a/index.js +++ b/index.js @@ -7,7 +7,7 @@ const os = require("os"); try { const version = core.getInput("dafny-version", { required: true }); const distribution = getDistribution(os.platform(), version); - const url = dafnyURL(version, distribution); + const url = await dafnyURL(version, distribution); core.info(`Dafny Url: ${url}`); core.info(`Dafny Distribution: ${distribution}`); @@ -22,14 +22,21 @@ const os = require("os"); // Install related tools. // Hopefully in the future we can install Dafny itself this way as well. // For now the zipped releases are simpler because they include Z3. - await installDotnetTool("dafny-reportgenerator", "1.*") + await installDotnetTool("dafny-reportgenerator", "1.*"); } catch (error) { core.setFailed(error.message); } })(); async function installDotnetTool(toolName, version) { - await exec.exec("dotnet", ["tool", "install", "-g", toolName, "--version", version]) + await exec.exec("dotnet", [ + "tool", + "install", + "-g", + toolName, + "--version", + version, + ]); } // Export functions for testing @@ -39,10 +46,12 @@ exports.getDistribution = getDistribution; async function dafnyURL(version, distribution) { const versionPath = version.startsWith("nightly") ? "nightly" : `v${version}`; if (version == "nightly-latest") { - version = await latestNightlyVersion() + version = await latestNightlyVersion(); } const root = "https://github.com/dafny-lang/dafny/releases/download"; - return `${root}/${versionPath}/dafny-${version == "2.3.0" ? "2.3.0.10506" : version}-x64-${distribution}.zip`; + return `${root}/${versionPath}/dafny-${ + version == "2.3.0" ? "2.3.0.10506" : version + }-x64-${distribution}.zip`; } async function latestNightlyVersion() { @@ -50,27 +59,42 @@ async function latestNightlyVersion() { // I'd prefer to use the GitHub API to list the assets under the "nightly" release, // but @actions/github requires authentication. // This method has the advantage of relying on more rigourous dotnet tool metadata at least. - const { exitCode, stdout, stderr } = await exec.getExecOutput("dotnet", [ 'tool', 'search', 'Dafny', '--detail', '--prerelease' ], {silent: true}) - const entries = stdout.split('----------------').map(entry => entry.split('\n').filter(e => e !== '')) - const dafnyEntry = entries.filter(entry => entry[0] === 'dafny')[0] - const versionsIndex = dafnyEntry.findIndex(v => v.startsWith('Versions:')) - const versions = dafnyEntry.slice(versionsIndex + 1).map(versionLine => versionLine.trimStart().split(' ')[0]) + const { exitCode, stdout, stderr } = await exec.getExecOutput( + "dotnet", + ["tool", "search", "Dafny", "--detail", "--prerelease"], + { silent: true } + ); + if (exitCode != 0) { + throw new Error( + `dotnet tool command failed (exitCode ${exitCode}):\n${stderr}"` + ); + } + const entries = stdout + .split("----------------") + .map((entry) => entry.split("\n").filter((e) => e !== "")); + const dafnyEntry = entries.filter((entry) => entry[0] === "dafny")[0]; + const versionsIndex = dafnyEntry.findIndex((v) => v.startsWith("Versions:")); + const versions = dafnyEntry + .slice(versionsIndex + 1) + .map((versionLine) => versionLine.trimStart().split(" ")[0]); - const nightlies = versions.filter(l => l.includes('nightly')) + const nightlies = versions.filter((l) => l.includes("nightly")); const dates = nightlies.map((n, index) => { - const split = n.split('-'); - return { index, date: split[2] + split[3] + split[4] } + const split = n.split("-"); + return { index, date: split[2] + split[3] + split[4] }; }); - dates.sort((a, b) => a.date < b.date ? 1 : -1) - toolVersion = nightlies[dates[0].index] + dates.sort((a, b) => (a.date < b.date ? 1 : -1)); + const toolVersion = nightlies[dates[0].index]; core.info(`Using latest nightly version: ${toolVersion}`); - return toolVersion + return toolVersion; } function getDistribution(platform, version) { return platform === "darwin" // Osx - ? version == "2.3.0" ? "osx-10.14.1" : "osx-10.14.2" + ? version == "2.3.0" + ? "osx-10.14.1" + : "osx-10.14.2" : platform === "win32" // windows ? "win" : "ubuntu-16.04"; // Everything else is linux... From 38856bde99cdd4e2e79d5ab6846814e7850218ee Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Mon, 13 Feb 2023 15:15:51 -0800 Subject: [PATCH 05/18] Package --- dist/index.js | 60 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/dist/index.js b/dist/index.js index fbd3004..c1a8388 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6695,7 +6695,7 @@ const os = __nccwpck_require__(2037); try { const version = core.getInput("dafny-version", { required: true }); const distribution = getDistribution(os.platform(), version); - const url = dafnyURL(version, distribution); + const url = await dafnyURL(version, distribution); core.info(`Dafny Url: ${url}`); core.info(`Dafny Distribution: ${distribution}`); @@ -6710,14 +6710,21 @@ const os = __nccwpck_require__(2037); // Install related tools. // Hopefully in the future we can install Dafny itself this way as well. // For now the zipped releases are simpler because they include Z3. - await installDotnetTool("dafny-reportgenerator", "1.*") + await installDotnetTool("dafny-reportgenerator", "1.*"); } catch (error) { core.setFailed(error.message); } })(); async function installDotnetTool(toolName, version) { - await exec.exec("dotnet", ["tool", "install", "-g", toolName, "--version", version]) + await exec.exec("dotnet", [ + "tool", + "install", + "-g", + toolName, + "--version", + version, + ]); } // Export functions for testing @@ -6727,10 +6734,12 @@ exports.getDistribution = getDistribution; async function dafnyURL(version, distribution) { const versionPath = version.startsWith("nightly") ? "nightly" : `v${version}`; if (version == "nightly-latest") { - version = await latestNightlyVersion() + version = await latestNightlyVersion(); } const root = "https://github.com/dafny-lang/dafny/releases/download"; - return `${root}/${versionPath}/dafny-${version == "2.3.0" ? "2.3.0.10506" : version}-x64-${distribution}.zip`; + return `${root}/${versionPath}/dafny-${ + version == "2.3.0" ? "2.3.0.10506" : version + }-x64-${distribution}.zip`; } async function latestNightlyVersion() { @@ -6738,27 +6747,42 @@ async function latestNightlyVersion() { // I'd prefer to use the GitHub API to list the assets under the "nightly" release, // but @actions/github requires authentication. // This method has the advantage of relying on more rigourous dotnet tool metadata at least. - const { exitCode, stdout, stderr } = await exec.getExecOutput("dotnet", [ 'tool', 'search', 'Dafny', '--detail', '--prerelease' ], {silent: true}) - const entries = stdout.split('----------------').map(entry => entry.split('\n').filter(e => e !== '')) - const dafnyEntry = entries.filter(entry => entry[0] === 'dafny')[0] - const versionsIndex = dafnyEntry.findIndex(v => v.startsWith('Versions:')) - const versions = dafnyEntry.slice(versionsIndex + 1).map(versionLine => versionLine.trimStart().split(' ')[0]) - - const nightlies = versions.filter(l => l.includes('nightly')) + const { exitCode, stdout, stderr } = await exec.getExecOutput( + "dotnet", + ["tool", "search", "Dafny", "--detail", "--prerelease"], + { silent: true } + ); + if (exitCode != 0) { + throw new Error( + `dotnet tool command failed (exitCode ${exitCode}):\n${stderr}"` + ); + } + const entries = stdout + .split("----------------") + .map((entry) => entry.split("\n").filter((e) => e !== "")); + const dafnyEntry = entries.filter((entry) => entry[0] === "dafny")[0]; + const versionsIndex = dafnyEntry.findIndex((v) => v.startsWith("Versions:")); + const versions = dafnyEntry + .slice(versionsIndex + 1) + .map((versionLine) => versionLine.trimStart().split(" ")[0]); + + const nightlies = versions.filter((l) => l.includes("nightly")); const dates = nightlies.map((n, index) => { - const split = n.split('-'); - return { index, date: split[2] + split[3] + split[4] } + const split = n.split("-"); + return { index, date: split[2] + split[3] + split[4] }; }); - dates.sort((a, b) => a.date < b.date ? 1 : -1) - toolVersion = nightlies[dates[0].index] + dates.sort((a, b) => (a.date < b.date ? 1 : -1)); + const toolVersion = nightlies[dates[0].index]; core.info(`Using latest nightly version: ${toolVersion}`); - return toolVersion + return toolVersion; } function getDistribution(platform, version) { return platform === "darwin" // Osx - ? version == "2.3.0" ? "osx-10.14.1" : "osx-10.14.2" + ? version == "2.3.0" + ? "osx-10.14.1" + : "osx-10.14.2" : platform === "win32" // windows ? "win" : "ubuntu-16.04"; // Everything else is linux... From 09245dd4909f7438e2b812108194952453d9aea8 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Mon, 13 Feb 2023 15:29:08 -0800 Subject: [PATCH 06/18] Trim off version prefix --- dist/index.js | 12 ++++++------ index.js | 8 ++++---- test/setup-dafny-action.js | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/dist/index.js b/dist/index.js index c1a8388..f1e4b48 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6743,10 +6743,9 @@ async function dafnyURL(version, distribution) { } async function latestNightlyVersion() { - // Shamelessly copied from dafny-lang/ide-vscode + // Shamelessly copied and modified from dafny-lang/ide-vscode // I'd prefer to use the GitHub API to list the assets under the "nightly" release, // but @actions/github requires authentication. - // This method has the advantage of relying on more rigourous dotnet tool metadata at least. const { exitCode, stdout, stderr } = await exec.getExecOutput( "dotnet", ["tool", "search", "Dafny", "--detail", "--prerelease"], @@ -6773,9 +6772,10 @@ async function latestNightlyVersion() { }); dates.sort((a, b) => (a.date < b.date ? 1 : -1)); const toolVersion = nightlies[dates[0].index]; + const version = toolVersion.slice(toolVersion.indexOf("-") + 1) - core.info(`Using latest nightly version: ${toolVersion}`); - return toolVersion; + core.info(`Using latest nightly version: ${version}`); + return version; } function getDistribution(platform, version) { @@ -6784,8 +6784,8 @@ function getDistribution(platform, version) { ? "osx-10.14.1" : "osx-10.14.2" : platform === "win32" // windows - ? "win" - : "ubuntu-16.04"; // Everything else is linux... + ? "win" + : "ubuntu-16.04"; // Everything else is linux... } })(); diff --git a/index.js b/index.js index fa7b5f7..baac89f 100644 --- a/index.js +++ b/index.js @@ -55,10 +55,9 @@ async function dafnyURL(version, distribution) { } async function latestNightlyVersion() { - // Shamelessly copied from dafny-lang/ide-vscode + // Shamelessly copied and modified from dafny-lang/ide-vscode // I'd prefer to use the GitHub API to list the assets under the "nightly" release, // but @actions/github requires authentication. - // This method has the advantage of relying on more rigourous dotnet tool metadata at least. const { exitCode, stdout, stderr } = await exec.getExecOutput( "dotnet", ["tool", "search", "Dafny", "--detail", "--prerelease"], @@ -85,9 +84,10 @@ async function latestNightlyVersion() { }); dates.sort((a, b) => (a.date < b.date ? 1 : -1)); const toolVersion = nightlies[dates[0].index]; + const version = toolVersion.slice(toolVersion.indexOf("-") + 1); - core.info(`Using latest nightly version: ${toolVersion}`); - return toolVersion; + core.info(`Using latest nightly version: ${version}`); + return version; } function getDistribution(platform, version) { diff --git a/test/setup-dafny-action.js b/test/setup-dafny-action.js index 9073c96..6a48083 100644 --- a/test/setup-dafny-action.js +++ b/test/setup-dafny-action.js @@ -20,7 +20,7 @@ describe("dafnyURL", () => { it("latest nightly usage", async () => { const test = await dafnyURL("nightly-latest", "ubuntu-16.04"); expect(test).to.match( - /^https:\/\/github.com\/dafny-lang\/dafny\/releases\/download\/nightly\/dafny-.*-nightly-/ + /^https:\/\/github.com\/dafny-lang\/dafny\/releases\/download\/nightly\/dafny-nightly-/ ); }); From d94ed1f64d89b1a015597977487f33f2448a60d9 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Mon, 13 Feb 2023 15:37:15 -0800 Subject: [PATCH 07/18] Case-insensitive grep in test script --- __tests__/verify-dafny.sh | 2 +- dist/index.js | 8 +++++--- index.js | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/__tests__/verify-dafny.sh b/__tests__/verify-dafny.sh index 76e95f6..78db7f0 100755 --- a/__tests__/verify-dafny.sh +++ b/__tests__/verify-dafny.sh @@ -26,7 +26,7 @@ fi echo "Expected Dafny Version: $expectedVersionString" dafny_version="$(dafny $version)" echo "Found $dafny_version" -if ! echo "$dafny_version" | grep -q "Dafny $expectedVersionString"; then +if ! echo "$dafny_version" | grep -qi "Dafny $expectedVersionString"; then echo "Unexpected version" 1>&2 exit 1 fi diff --git a/dist/index.js b/dist/index.js index f1e4b48..1d8d0db 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6772,7 +6772,9 @@ async function latestNightlyVersion() { }); dates.sort((a, b) => (a.date < b.date ? 1 : -1)); const toolVersion = nightlies[dates[0].index]; - const version = toolVersion.slice(toolVersion.indexOf("-") + 1) + + // Slice off the "3.11.0.50201-" from 3.11.0.50201-nightly-2023-02-13-14bc57f, for e.g. + const version = toolVersion.slice(toolVersion.indexOf("-") + 1); core.info(`Using latest nightly version: ${version}`); return version; @@ -6784,8 +6786,8 @@ function getDistribution(platform, version) { ? "osx-10.14.1" : "osx-10.14.2" : platform === "win32" // windows - ? "win" - : "ubuntu-16.04"; // Everything else is linux... + ? "win" + : "ubuntu-16.04"; // Everything else is linux... } })(); diff --git a/index.js b/index.js index baac89f..dc2a9a7 100644 --- a/index.js +++ b/index.js @@ -84,6 +84,8 @@ async function latestNightlyVersion() { }); dates.sort((a, b) => (a.date < b.date ? 1 : -1)); const toolVersion = nightlies[dates[0].index]; + + // Slice off the "3.11.0.50201-" from 3.11.0.50201-nightly-2023-02-13-14bc57f, for e.g. const version = toolVersion.slice(toolVersion.indexOf("-") + 1); core.info(`Using latest nightly version: ${version}`); From 3b8354c907235b0f9f327e8abea31b97e39236a3 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Tue, 14 Feb 2023 10:30:02 -0800 Subject: [PATCH 08/18] Debugging windows failure --- dist/index.js | 5 ++--- index.js | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dist/index.js b/dist/index.js index 1d8d0db..9dda30d 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6743,9 +6743,7 @@ async function dafnyURL(version, distribution) { } async function latestNightlyVersion() { - // Shamelessly copied and modified from dafny-lang/ide-vscode - // I'd prefer to use the GitHub API to list the assets under the "nightly" release, - // but @actions/github requires authentication. + // Shamelessly copied and modified from dafny-lang/ide-vscode. const { exitCode, stdout, stderr } = await exec.getExecOutput( "dotnet", ["tool", "search", "Dafny", "--detail", "--prerelease"], @@ -6756,6 +6754,7 @@ async function latestNightlyVersion() { `dotnet tool command failed (exitCode ${exitCode}):\n${stderr}"` ); } + await console.log(stdout) const entries = stdout .split("----------------") .map((entry) => entry.split("\n").filter((e) => e !== "")); diff --git a/index.js b/index.js index dc2a9a7..e5b35cf 100644 --- a/index.js +++ b/index.js @@ -55,9 +55,7 @@ async function dafnyURL(version, distribution) { } async function latestNightlyVersion() { - // Shamelessly copied and modified from dafny-lang/ide-vscode - // I'd prefer to use the GitHub API to list the assets under the "nightly" release, - // but @actions/github requires authentication. + // Shamelessly copied and modified from dafny-lang/ide-vscode. const { exitCode, stdout, stderr } = await exec.getExecOutput( "dotnet", ["tool", "search", "Dafny", "--detail", "--prerelease"], @@ -68,6 +66,7 @@ async function latestNightlyVersion() { `dotnet tool command failed (exitCode ${exitCode}):\n${stderr}"` ); } + await console.log(stdout) const entries = stdout .split("----------------") .map((entry) => entry.split("\n").filter((e) => e !== "")); From 63517f13f0b6f073de82712336d737ce48373f51 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Tue, 14 Feb 2023 11:25:04 -0800 Subject: [PATCH 09/18] More debugging windows --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5799018..e5da048 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,6 +23,8 @@ jobs: - os: ubuntu-latest dafny: 2.3.0 steps: + - run: dotnet tool search --help + - name: Checkout uses: actions/checkout@v2 From 1336a5329532fda33a2305c9c2cc1beec4b6dba2 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Tue, 14 Feb 2023 11:29:35 -0800 Subject: [PATCH 10/18] More debugging --- index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/index.js b/index.js index e5b35cf..cdfccf8 100644 --- a/index.js +++ b/index.js @@ -70,6 +70,7 @@ async function latestNightlyVersion() { const entries = stdout .split("----------------") .map((entry) => entry.split("\n").filter((e) => e !== "")); + await console.log(entries) const dafnyEntry = entries.filter((entry) => entry[0] === "dafny")[0]; const versionsIndex = dafnyEntry.findIndex((v) => v.startsWith("Versions:")); const versions = dafnyEntry From 4a5e8c9b6c69ec5c524371632f515f342ee576c3 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Tue, 14 Feb 2023 11:31:39 -0800 Subject: [PATCH 11/18] Package --- dist/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/dist/index.js b/dist/index.js index 9dda30d..96ff0a4 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6758,6 +6758,7 @@ async function latestNightlyVersion() { const entries = stdout .split("----------------") .map((entry) => entry.split("\n").filter((e) => e !== "")); + await console.log(entries) const dafnyEntry = entries.filter((entry) => entry[0] === "dafny")[0]; const versionsIndex = dafnyEntry.findIndex((v) => v.startsWith("Versions:")); const versions = dafnyEntry From a2efa0548a1d0d55f4620258308a4dea024e0b7e Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Tue, 14 Feb 2023 11:36:00 -0800 Subject: [PATCH 12/18] Fix windows --- dist/index.js | 4 +--- index.js | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/dist/index.js b/dist/index.js index 96ff0a4..6ca475f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6754,11 +6754,9 @@ async function latestNightlyVersion() { `dotnet tool command failed (exitCode ${exitCode}):\n${stderr}"` ); } - await console.log(stdout) const entries = stdout .split("----------------") - .map((entry) => entry.split("\n").filter((e) => e !== "")); - await console.log(entries) + .map((entry) => entry.split("\r?\n").filter((e) => e !== "")); const dafnyEntry = entries.filter((entry) => entry[0] === "dafny")[0]; const versionsIndex = dafnyEntry.findIndex((v) => v.startsWith("Versions:")); const versions = dafnyEntry diff --git a/index.js b/index.js index cdfccf8..ddb267a 100644 --- a/index.js +++ b/index.js @@ -66,11 +66,9 @@ async function latestNightlyVersion() { `dotnet tool command failed (exitCode ${exitCode}):\n${stderr}"` ); } - await console.log(stdout) const entries = stdout .split("----------------") - .map((entry) => entry.split("\n").filter((e) => e !== "")); - await console.log(entries) + .map((entry) => entry.split("\r?\n").filter((e) => e !== "")); const dafnyEntry = entries.filter((entry) => entry[0] === "dafny")[0]; const versionsIndex = dafnyEntry.findIndex((v) => v.startsWith("Versions:")); const versions = dafnyEntry From 562807d061b1fd80541c2cba9e51699a825ea6de Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Tue, 14 Feb 2023 11:38:56 -0800 Subject: [PATCH 13/18] Typo and big old comment --- dist/index.js | 9 ++++++++- index.js | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index 6ca475f..7c48e21 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6744,6 +6744,13 @@ async function dafnyURL(version, distribution) { async function latestNightlyVersion() { // Shamelessly copied and modified from dafny-lang/ide-vscode. + // Parsing the dotnet tool output is obviously not great, + // and we could consider using the NuGet API in the future. + // Alternatively if we move to installing Dafny using `dotnet tool install` + // we could use the `--prerelease` flag, although that assumes + // that all nightly builds use a fresh version number, + // and can't be used together with `--version` to express something like + // "install the latest 3.X version including prereleases". const { exitCode, stdout, stderr } = await exec.getExecOutput( "dotnet", ["tool", "search", "Dafny", "--detail", "--prerelease"], @@ -6756,7 +6763,7 @@ async function latestNightlyVersion() { } const entries = stdout .split("----------------") - .map((entry) => entry.split("\r?\n").filter((e) => e !== "")); + .map((entry) => entry.split(/\r?\n/).filter((e) => e !== "")); const dafnyEntry = entries.filter((entry) => entry[0] === "dafny")[0]; const versionsIndex = dafnyEntry.findIndex((v) => v.startsWith("Versions:")); const versions = dafnyEntry diff --git a/index.js b/index.js index ddb267a..303a7b6 100644 --- a/index.js +++ b/index.js @@ -56,6 +56,13 @@ async function dafnyURL(version, distribution) { async function latestNightlyVersion() { // Shamelessly copied and modified from dafny-lang/ide-vscode. + // Parsing the dotnet tool output is obviously not great, + // and we could consider using the NuGet API in the future. + // Alternatively if we move to installing Dafny using `dotnet tool install` + // we could use the `--prerelease` flag, although that assumes + // that all nightly builds use a fresh version number, + // and can't be used together with `--version` to express something like + // "install the latest 3.X version including prereleases". const { exitCode, stdout, stderr } = await exec.getExecOutput( "dotnet", ["tool", "search", "Dafny", "--detail", "--prerelease"], @@ -68,7 +75,7 @@ async function latestNightlyVersion() { } const entries = stdout .split("----------------") - .map((entry) => entry.split("\r?\n").filter((e) => e !== "")); + .map((entry) => entry.split(/\r?\n/).filter((e) => e !== "")); const dafnyEntry = entries.filter((entry) => entry[0] === "dafny")[0]; const versionsIndex = dafnyEntry.findIndex((v) => v.startsWith("Versions:")); const versions = dafnyEntry From 51ed729d8fdbb3454a4327c1d7b6c3d39ef33531 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Tue, 14 Feb 2023 11:47:49 -0800 Subject: [PATCH 14/18] Comments --- .github/workflows/main.yml | 4 ++++ test/setup-dafny-action.js | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e5da048..04f4fcf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,6 +23,10 @@ jobs: - os: ubuntu-latest dafny: 2.3.0 steps: + # The first call to `dotnet tool` on a fresh runner sometimes takes multiple minutes, + # perhaps because it is lazily downloading and installing assets. + # It helps to hit that here so we don't hit it in a mocha test with a tight timeout. + - name: Warm up dotnet tool - run: dotnet tool search --help - name: Checkout diff --git a/test/setup-dafny-action.js b/test/setup-dafny-action.js index 6a48083..45c0027 100644 --- a/test/setup-dafny-action.js +++ b/test/setup-dafny-action.js @@ -16,13 +16,12 @@ describe("dafnyURL", () => { ); }); - // TODO: Really we want to say "latest 3.x nightly" so that we don't automatically pick up major version bumps it("latest nightly usage", async () => { const test = await dafnyURL("nightly-latest", "ubuntu-16.04"); expect(test).to.match( /^https:\/\/github.com\/dafny-lang\/dafny\/releases\/download\/nightly\/dafny-nightly-/ ); - }); + }).timeout(5000); // Invoking and parsing the output of `dotnet tool search` can take a bit over 2 seconds it("version 2.3.0", async () => { const test = await dafnyURL("2.3.0", "win"); From 8b30437bafc4523e3385d3c7f25598aeb7aea44d Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Tue, 14 Feb 2023 11:54:25 -0800 Subject: [PATCH 15/18] Poke CI From 8a5d5cc537a20bc68cbb66acd0b18c882e4297a1 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Tue, 14 Feb 2023 12:50:29 -0800 Subject: [PATCH 16/18] Workflow typo --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 04f4fcf..aa46cc2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,7 +27,7 @@ jobs: # perhaps because it is lazily downloading and installing assets. # It helps to hit that here so we don't hit it in a mocha test with a tight timeout. - name: Warm up dotnet tool - - run: dotnet tool search --help + run: dotnet tool search --help - name: Checkout uses: actions/checkout@v2 From 5d5649ba111832dbb1d27be0d1076d1f681ebf0c Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Tue, 14 Feb 2023 13:40:04 -0800 Subject: [PATCH 17/18] Increase test timeout --- test/setup-dafny-action.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/setup-dafny-action.js b/test/setup-dafny-action.js index 45c0027..da61dd0 100644 --- a/test/setup-dafny-action.js +++ b/test/setup-dafny-action.js @@ -21,7 +21,7 @@ describe("dafnyURL", () => { expect(test).to.match( /^https:\/\/github.com\/dafny-lang\/dafny\/releases\/download\/nightly\/dafny-nightly-/ ); - }).timeout(5000); // Invoking and parsing the output of `dotnet tool search` can take a bit over 2 seconds + }).timeout(20_000); // Invoking and parsing the output of `dotnet tool search` can take well over 2 seconds it("version 2.3.0", async () => { const test = await dafnyURL("2.3.0", "win"); From 56f2eb15245efe07098ad46109d332d3b3af0085 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Wed, 15 Feb 2023 15:35:11 -0800 Subject: [PATCH 18/18] PR feedback --- dist/index.js | 31 ++++++++++-------- index.js | 32 ++++++++++-------- test/setup-dafny-action.js | 66 +++++++++++++++++++++++++++++++++++++- 3 files changed, 102 insertions(+), 27 deletions(-) diff --git a/dist/index.js b/dist/index.js index 7c48e21..ad4eb7f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6730,6 +6730,7 @@ async function installDotnetTool(toolName, version) { // Export functions for testing exports.dafnyURL = dafnyURL; exports.getDistribution = getDistribution; +exports.latestNightlyVersionFromDotnetToolSearch = latestNightlyVersionFromDotnetToolSearch; async function dafnyURL(version, distribution) { const versionPath = version.startsWith("nightly") ? "nightly" : `v${version}`; @@ -6743,14 +6744,6 @@ async function dafnyURL(version, distribution) { } async function latestNightlyVersion() { - // Shamelessly copied and modified from dafny-lang/ide-vscode. - // Parsing the dotnet tool output is obviously not great, - // and we could consider using the NuGet API in the future. - // Alternatively if we move to installing Dafny using `dotnet tool install` - // we could use the `--prerelease` flag, although that assumes - // that all nightly builds use a fresh version number, - // and can't be used together with `--version` to express something like - // "install the latest 3.X version including prereleases". const { exitCode, stdout, stderr } = await exec.getExecOutput( "dotnet", ["tool", "search", "Dafny", "--detail", "--prerelease"], @@ -6761,7 +6754,19 @@ async function latestNightlyVersion() { `dotnet tool command failed (exitCode ${exitCode}):\n${stderr}"` ); } - const entries = stdout + return latestNightlyVersionFromDotnetToolSearch(stdout) +} + +function latestNightlyVersionFromDotnetToolSearch(output) { + // Shamelessly copied and modified from dafny-lang/ide-vscode. + // Parsing the dotnet tool output is obviously not great, + // and we could consider using the NuGet API in the future. + // Alternatively if we move to installing Dafny using `dotnet tool install` + // we could use the `--prerelease` flag, although that assumes + // that all nightly builds use a fresh version number, + // and can't be used together with `--version` to express something like + // "install the latest 3.X version including prereleases". + const entries = output .split("----------------") .map((entry) => entry.split(/\r?\n/).filter((e) => e !== "")); const dafnyEntry = entries.filter((entry) => entry[0] === "dafny")[0]; @@ -6771,12 +6776,12 @@ async function latestNightlyVersion() { .map((versionLine) => versionLine.trimStart().split(" ")[0]); const nightlies = versions.filter((l) => l.includes("nightly")); - const dates = nightlies.map((n, index) => { - const split = n.split("-"); - return { index, date: split[2] + split[3] + split[4] }; + const dates = nightlies.map(nightly => { + const date = new Date(nightly.split('-').slice(2, 5).join('-')) + return { nightly, date }; }); dates.sort((a, b) => (a.date < b.date ? 1 : -1)); - const toolVersion = nightlies[dates[0].index]; + const toolVersion = dates[0].nightly; // Slice off the "3.11.0.50201-" from 3.11.0.50201-nightly-2023-02-13-14bc57f, for e.g. const version = toolVersion.slice(toolVersion.indexOf("-") + 1); diff --git a/index.js b/index.js index 303a7b6..a7a9c27 100644 --- a/index.js +++ b/index.js @@ -42,6 +42,8 @@ async function installDotnetTool(toolName, version) { // Export functions for testing exports.dafnyURL = dafnyURL; exports.getDistribution = getDistribution; +exports.latestNightlyVersionFromDotnetToolSearch = + latestNightlyVersionFromDotnetToolSearch; async function dafnyURL(version, distribution) { const versionPath = version.startsWith("nightly") ? "nightly" : `v${version}`; @@ -55,14 +57,6 @@ async function dafnyURL(version, distribution) { } async function latestNightlyVersion() { - // Shamelessly copied and modified from dafny-lang/ide-vscode. - // Parsing the dotnet tool output is obviously not great, - // and we could consider using the NuGet API in the future. - // Alternatively if we move to installing Dafny using `dotnet tool install` - // we could use the `--prerelease` flag, although that assumes - // that all nightly builds use a fresh version number, - // and can't be used together with `--version` to express something like - // "install the latest 3.X version including prereleases". const { exitCode, stdout, stderr } = await exec.getExecOutput( "dotnet", ["tool", "search", "Dafny", "--detail", "--prerelease"], @@ -73,7 +67,19 @@ async function latestNightlyVersion() { `dotnet tool command failed (exitCode ${exitCode}):\n${stderr}"` ); } - const entries = stdout + return latestNightlyVersionFromDotnetToolSearch(stdout); +} + +function latestNightlyVersionFromDotnetToolSearch(output) { + // Shamelessly copied and modified from dafny-lang/ide-vscode. + // Parsing the dotnet tool output is obviously not great, + // and we could consider using the NuGet API in the future. + // Alternatively if we move to installing Dafny using `dotnet tool install` + // we could use the `--prerelease` flag, although that assumes + // that all nightly builds use a fresh version number, + // and can't be used together with `--version` to express something like + // "install the latest 3.X version including prereleases". + const entries = output .split("----------------") .map((entry) => entry.split(/\r?\n/).filter((e) => e !== "")); const dafnyEntry = entries.filter((entry) => entry[0] === "dafny")[0]; @@ -83,12 +89,12 @@ async function latestNightlyVersion() { .map((versionLine) => versionLine.trimStart().split(" ")[0]); const nightlies = versions.filter((l) => l.includes("nightly")); - const dates = nightlies.map((n, index) => { - const split = n.split("-"); - return { index, date: split[2] + split[3] + split[4] }; + const dates = nightlies.map((nightly) => { + const date = new Date(nightly.split("-").slice(2, 5).join("-")); + return { nightly, date }; }); dates.sort((a, b) => (a.date < b.date ? 1 : -1)); - const toolVersion = nightlies[dates[0].index]; + const toolVersion = dates[0].nightly; // Slice off the "3.11.0.50201-" from 3.11.0.50201-nightly-2023-02-13-14bc57f, for e.g. const version = toolVersion.slice(toolVersion.indexOf("-") + 1); diff --git a/test/setup-dafny-action.js b/test/setup-dafny-action.js index da61dd0..e713031 100644 --- a/test/setup-dafny-action.js +++ b/test/setup-dafny-action.js @@ -1,4 +1,8 @@ -const { dafnyURL, getDistribution } = require("../index"); +const { + dafnyURL, + getDistribution, + latestNightlyVersionFromDotnetToolSearch, +} = require("../index"); const { expect } = require("chai"); describe("dafnyURL", () => { @@ -16,6 +20,13 @@ describe("dafnyURL", () => { ); }); + it("latest nightly parsing logic", async () => { + const test = latestNightlyVersionFromDotnetToolSearch( + sampleDotnetToolSearchOutput + ); + expect(test).to.equal("nightly-2023-02-15-567a5ba"); + }); + it("latest nightly usage", async () => { const test = await dafnyURL("nightly-latest", "ubuntu-16.04"); expect(test).to.match( @@ -34,6 +45,59 @@ describe("dafnyURL", () => { }); }); +const sampleDotnetToolSearchOutput = ` +---------------- +dafny +Latest Version: 3.11.0.50201 +Authors: Dafny +Tags: +Downloads: 16159 +Verified: False +Description: Package Description +Versions: + 3.10.0.41215-nightly-2023-01-24-fda11e6 Downloads: 54 + 3.10.0.41215-nightly-2023-01-25-07932fc Downloads: 54 + 3.10.0.41215-nightly-2023-01-26-97f1ced Downloads: 47 + 3.10.0.41215-nightly-2023-01-27-5bd9203 Downloads: 50 + 3.10.0.41215-nightly-2023-01-28-acb7991 Downloads: 52 + 3.10.0.41215-nightly-2023-01-29-acb7991 Downloads: 51 + 3.10.0.41215-nightly-2023-01-30-acb7991 Downloads: 53 + 3.10.0.41215-nightly-2023-01-31-c23b224 Downloads: 57 + 3.10.0.41215-nightly-2023-02-01-c5b4e15 Downloads: 46 + 3.10.0.41215 Downloads: 166 + 3.11.0.50201-nightly-2023-02-01-0cff53e Downloads: 43 + 3.11.0.50201-nightly-2023-02-02-4e54d04 Downloads: 49 + 3.11.0.50201-nightly-2023-02-03-9b97489 Downloads: 41 + 3.11.0.50201-nightly-2023-02-04-b8d8816 Downloads: 34 + 3.11.0.50201-nightly-2023-02-05-b8d8816 Downloads: 33 + 3.11.0.50201-nightly-2023-02-06-b8d8816 Downloads: 34 + 3.11.0.50201-nightly-2023-02-07-2461f1f Downloads: 30 + 3.11.0.50201-nightly-2023-02-08-37cfcb0 Downloads: 31 + 3.11.0.50201-nightly-2023-02-09-a86c579 Downloads: 31 + 3.11.0.50201-nightly-2023-02-10-a2a4e1b Downloads: 27 + 3.11.0.50201-nightly-2023-02-10-a86c579 Downloads: 26 + 3.11.0.50201-nightly-2023-02-11-6aeaa2b Downloads: 28 + 3.11.0.50201-nightly-2023-02-11-a2a4e1b Downloads: 30 + 3.11.0.50201-nightly-2023-02-12-6aeaa2b Downloads: 29 + 3.11.0.50201-nightly-2023-02-13-14bc57f Downloads: 27 + 3.11.0.50201-nightly-2023-02-14-7cf7164 Downloads: 27 + 3.11.0.50201-nightly-2023-02-15-567a5ba Downloads: 14 + 3.11.0.50201 Downloads: 94 + +---------------- +dafny-reportgenerator +Latest Version: 1.2.0 +Authors: dafny-reportgenerator +Tags: +Downloads: 11564 +Verified: False +Description: Package Description +Versions: + 1.0.0 Downloads: 248 + 1.0.1 Downloads: 525 + 1.2.0 Downloads: 10791 +`; + describe("getDistribution", () => { // https://nodejs.org/docs/latest/api/os.html#os_os_platform [