Skip to content

Commit c8d3452

Browse files
committed
Support the manifest alias
1 parent 67ec926 commit c8d3452

File tree

18 files changed

+269
-28
lines changed

18 files changed

+269
-28
lines changed

.github/workflows/ci.yaml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,19 @@ jobs:
4343
steps:
4444
- uses: actions/checkout@v4
4545

46-
- name: Create Project.toml
46+
- name: Create Project.toml and Manifest.toml
4747
shell: bash
4848
run: |
49-
echo -e '[compat]\njulia = "1.6"' >Project.toml
49+
echo -e '[compat]\njulia = "1.7"' >Project.toml
50+
echo -e 'julia_version = "1.7.3"' >Manifest.toml
5051
5152
- name: Test julia-version
5253
id: julia-version
5354
uses: ./
5455
with:
5556
versions: |
5657
- min
58+
- manifest
5759
- lts
5860
- 1
5961
- ~1.10
@@ -63,10 +65,11 @@ jobs:
6365
shell: bash
6466
run: |
6567
set -x
66-
[[ "$(jq -r 'length' <<<"$unique_json")" -eq 3 ]] || exit 1
67-
[[ "$(jq -r '.[0]' <<<"$unique_json")" == "1.6.0" ]] || exit 1
68-
[[ "$(jq -r '.[1]' <<<"$unique_json")" =~ ^1\.10\.([8-9]|[1-9][0-9]*)$ ]] || exit 1 # [1.10.8, 1.11.0)
69-
[[ "$(jq -r '.[2]' <<<"$unique_json")" =~ ^1\.(1[1-9]|2[0-9]+)\.[0-9]+$ ]] || exit 1 # [1.11.0, ∞)
68+
[[ "$(jq -r 'length' <<<"$unique_json")" -eq 4 ]] || exit 1
69+
[[ "$(jq -r '.[0]' <<<"$unique_json")" == "1.7.0" ]] || exit 1
70+
[[ "$(jq -r '.[1]' <<<"$unique_json")" == "1.7.3" ]] || exit 1
71+
[[ "$(jq -r '.[2]' <<<"$unique_json")" =~ ^1\.10\.([8-9]|[1-9][0-9]*)$ ]] || exit 1 # [1.10.8, 1.11.0)
72+
[[ "$(jq -r '.[3]' <<<"$unique_json")" =~ ^1\.(1[1-9]|2[0-9]+)\.[0-9]+$ ]] || exit 1 # [1.11.0, ∞)
7073
7174
[[ "$version" == "" ]] || exit 1
7275
env:

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ Resolves to the lowest Julia version compatible with the Julia project. Using
167167
this alias requires that the `project` input refers to a directory containing a
168168
`Project.toml` (or `JuliaProject.toml`) and a `julia` compat entry exist.
169169

170+
### `manifest` Alias
171+
172+
Resolves to the Julia version as specified in the Julia manifest file. Using
173+
this alias requires that the `project` input refers to a directory containing a
174+
`Manifest.toml` (or `JuliaManifest.toml`).
175+
170176
### Grammar
171177

172178
Here is the complete Backus-Naur grammar for a version specifier:
@@ -177,7 +183,7 @@ Here is the complete Backus-Naur grammar for a version specifier:
177183
<caret> ::= "^" <partial>
178184
<partial> ::= <n> | <n> "." <n> | <n> "." <n> "." <n>
179185
<nightly> ::= <n> "." <n> "-nightly" | "nightly"
180-
<alias> ::= "lts" | "min"
186+
<alias> ::= "lts" | "min" | "manifest"
181187
<n> ::= "0" | <positive> <digits>
182188
<digits> ::= <digit> | <digit> <digits>
183189
<digit> ::= "0" | <positive>

__fixtures__/constants.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,20 @@ export const versionsJsonFile = path.join(
1010
"versions.json"
1111
)
1212

13+
export const projectDirV1 = path.join(
14+
__dirname,
15+
"..",
16+
"__fixtures__",
17+
"julia-manifest-v1"
18+
)
19+
20+
export const projectDirV2 = path.join(
21+
__dirname,
22+
"..",
23+
"__fixtures__",
24+
"julia-manifest-v2"
25+
)
26+
1327
export const testVersions = Object.keys(
1428
JSON.parse(fs.readFileSync(versionsJsonFile).toString())
1529
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# This file is machine-generated - editing it directly is not advised
2+
3+
[[Example]]
4+
git-tree-sha1 = "e1f0e1a832ccd8e97d6d0348dec33ee139a5aeaf"
5+
uuid = "7876af07-990d-54b4-ab0e-23690620f79a"
6+
version = "0.5.5"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[deps]
2+
Example = "7876af07-990d-54b4-ab0e-23690620f79a"
3+
4+
[compat]
5+
Example = "0.5"
6+
julia = "~1.3, ~1.4, ~1.5, ~1.6"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This file is machine-generated - editing it directly is not advised
2+
3+
julia_version = "1.11.3"
4+
manifest_format = "2.0"
5+
project_hash = "2ca1c6c58cb30e79e021fb54e5626c96d05d5fdc"
6+
7+
[[deps.Example]]
8+
git-tree-sha1 = "e1f0e1a832ccd8e97d6d0348dec33ee139a5aeaf"
9+
uuid = "7876af07-990d-54b4-ab0e-23690620f79a"
10+
version = "0.5.5"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[deps]
2+
Example = "7876af07-990d-54b4-ab0e-23690620f79a"
3+
4+
[compat]
5+
Example = "0.5"
6+
julia = "1"

__tests__/input.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ describe("parseVersionSpecifiers", () => {
4242
it("Handle alias scalar", () => {
4343
expect(parseVersionSpecifiers("lts")).toEqual(["lts"])
4444
expect(parseVersionSpecifiers("min")).toEqual(["min"])
45+
expect(parseVersionSpecifiers("manifest")).toEqual(["manifest"])
4546

4647
expect(() => parseVersionSpecifiers("pre")).toThrow(
4748
"Invalid version specifier"

__tests__/project.test.ts

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { tmpdir } from "node:os"
1010
import {
1111
getJuliaCompatRange,
1212
getJuliaProjectFile,
13+
getJuliaManifestFile,
1314
validJuliaCompatRange,
1415
} from "../src/project.js"
1516

@@ -26,10 +27,10 @@ describe("getJuliaProjectFile tests", () => {
2627

2728
it("Can determine project file is missing", () => {
2829
expect(() => getJuliaProjectFile("DNE.toml")).toThrow(
29-
"Unable to locate project file"
30+
"Unable to locate Julia project file"
3031
)
3132
expect(() => getJuliaProjectFile(".")).toThrow(
32-
"Unable to locate project file"
33+
"Unable to locate Julia project file"
3334
)
3435
})
3536

@@ -70,6 +71,60 @@ describe("getJuliaProjectFile tests", () => {
7071
})
7172
})
7273

74+
describe("getJuliaManifestFile tests", () => {
75+
let orgWorkingDir: string
76+
77+
beforeEach(() => {
78+
orgWorkingDir = process.cwd()
79+
})
80+
81+
afterEach(() => {
82+
process.chdir(orgWorkingDir)
83+
})
84+
85+
it("Can determine manifest file is missing", () => {
86+
expect(() => getJuliaManifestFile(".")).toThrow(
87+
"Unable to locate Julia manifest file"
88+
)
89+
})
90+
91+
it("Can determine project file from a directory", () => {
92+
fs.mkdtemp(path.join(tmpdir(), "julia-version-"), (err, projectDir) => {
93+
const manifestFile = path.join(projectDir, "Manifest.toml")
94+
fs.closeSync(fs.openSync(manifestFile, "w"))
95+
expect(getJuliaManifestFile(projectDir)).toEqual(manifestFile)
96+
})
97+
98+
fs.mkdtemp(path.join(tmpdir(), "julia-version-"), (err, projectDir) => {
99+
const manifestFile = path.join(projectDir, "JuliaManifest.toml")
100+
fs.closeSync(fs.openSync(manifestFile, "w"))
101+
expect(getJuliaManifestFile(projectDir)).toEqual(manifestFile)
102+
})
103+
})
104+
105+
it("Prefers using JuliaManifest.toml over Manifest.toml", () => {
106+
fs.mkdtemp(path.join(tmpdir(), "julia-version-"), (err, projectDir) => {
107+
const manifestFile = path.join(projectDir, "Manifest.toml")
108+
fs.closeSync(fs.openSync(manifestFile, "w"))
109+
110+
const juliaManifestFile = path.join(projectDir, "JuliaManifest.toml")
111+
fs.closeSync(fs.openSync(juliaManifestFile, "w"))
112+
113+
expect(getJuliaManifestFile(projectDir)).toEqual(juliaManifestFile)
114+
})
115+
})
116+
117+
it("Can determine project from the current working directory", () => {
118+
fs.mkdtemp(path.join(tmpdir(), "julia-version-"), (err, projectDir) => {
119+
const projectFile = path.join(projectDir, "Manifest.toml")
120+
fs.closeSync(fs.openSync(projectFile, "w"))
121+
122+
process.chdir(projectDir)
123+
expect(getJuliaManifestFile(".")).toEqual("Manifest.toml")
124+
})
125+
})
126+
})
127+
73128
describe("validJuliaCompatRange tests", () => {
74129
it("Handles default caret specifier", () => {
75130
expect(validJuliaCompatRange("1")).toEqual(semver.validRange("^1"))

__tests__/version.test.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ import nock from "nock"
66
import semver from "semver"
77

88
import * as core from "../__fixtures__/core.js"
9-
import { testVersions, versionsJsonFile } from "../__fixtures__/constants.js"
9+
import {
10+
testVersions,
11+
versionsJsonFile,
12+
projectDirV1,
13+
projectDirV2,
14+
} from "../__fixtures__/constants.js"
1015

1116
// Mocks should be declared before the module being tested is imported.
1217
jest.unstable_mockModule("@actions/core", () => core)
@@ -67,6 +72,18 @@ describe("resolveVersions tests", () => {
6772
])
6873
})
6974

75+
it("Handles alias: manifest", async () => {
76+
await expect(resolveVersions(["manifest"], projectDirV2)).resolves.toEqual([
77+
"1.11.3",
78+
])
79+
await expect(resolveVersions(["manifest"], projectDirV1)).rejects.toThrow(
80+
"No Julia version exists matching specifier"
81+
)
82+
await expect(resolveVersions(["manifest"], ".")).rejects.toThrow(
83+
"Unable to locate Julia manifest file"
84+
)
85+
})
86+
7087
it("Respects ifMissing error", async () => {
7188
await expect(
7289
resolveVersions(["1.9-nightly"], ".", { ifMissing: "error" })
@@ -124,6 +141,18 @@ describe("resolveVersion tests", () => {
124141
it("version alias: lts", () => {
125142
expect(resolveVersion("lts", testVersions)).toEqual(latestLts)
126143
})
144+
145+
it("version alias: manifest", () => {
146+
expect(resolveVersion("manifest", testVersions)).toBeNull()
147+
expect(resolveVersion("manifest", testVersions, null, "1.11.3")).toEqual(
148+
"1.11.3"
149+
)
150+
151+
// An unofficial build of say `1.12.0-DEV.850` is recorded as `1.12.0-DEV` in the manifest
152+
expect(
153+
resolveVersion("manifest", testVersions, null, "1.12.0-DEV")
154+
).toEqual("1.12.0-DEV")
155+
})
127156
})
128157

129158
describe("version ranges", () => {

0 commit comments

Comments
 (0)