') do
98 | for item in match:gmatch('
]*>(.-)') do
99 | for number in item:gmatch("%d+") do
100 | table.insert(result, {version=tonumber(number) .. '',note="latest"})
101 | end
102 | end
103 | end
104 |
105 | return result
106 | end
107 |
108 |
109 | function PLUGIN:EnvKeys(ctx)
110 | local path = ctx.path
111 | if OS_TYPE == "darwin" then
112 | path = path .. "/Contents/Home"
113 | end
114 | return {
115 | {
116 | key = "GRAALVM_HOME",
117 | value = path
118 | },
119 | {
120 | key = "PATH",
121 | value = path .. "/bin"
122 | }
123 | }
124 | end
--------------------------------------------------------------------------------
/java/ibm-adoptium-jdk.lua:
--------------------------------------------------------------------------------
1 | --- Copyright 2024 [axdank axdank@proton.me]
2 | --
3 | -- Licensed under the Apache License, Version 2.0 (the "License");
4 | -- you may not use this file except in compliance with the License.
5 | -- You may obtain a copy of the License at
6 | --
7 | -- http://www.apache.org/licenses/LICENSE-2.0
8 | --
9 | -- Unless required by applicable law or agreed to in writing, software
10 | -- distributed under the License is distributed on an "AS IS" BASIS,
11 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | -- See the License for the specific language governing permissions and
13 | -- limitations under the License.
14 |
15 | local http = require("http")
16 | local json = require("json")
17 |
18 | OS_TYPE = ""
19 | ARCH_TYPE = ""
20 |
21 | AvailableVersionsUrl = "https://marketplace-api.adoptium.net/v1/info/available_releases/ibm"
22 | DownloadLatestUrl = "https://marketplace-api.adoptium.net/v1/assets/latest/ibm/%s/openj9"
23 |
24 | PLUGIN = {
25 | name = "java",
26 | author = "axdank",
27 | version = "0.0.5",
28 | description = "IBM JDK - Adoptium",
29 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/java/ibm-adoptium-jdk.lua",
30 | minRuntimeVersion = "0.3.0",
31 | manifestUrl = "https://github.com/version-fox/vfox-java/releases/download/manifest/manifest.json"
32 | }
33 |
34 | function PLUGIN:PreInstall(ctx)
35 | local version = ctx.version
36 |
37 | if version == nil or version == "" then
38 | return nil
39 | end
40 |
41 | if tonumber(version) == nil then
42 | error("invalid version: " .. ctx.version)
43 | end
44 |
45 | local type = getOsTypeAndArch()
46 |
47 | local resp, err = http.get({
48 | url = DownloadLatestUrl:format(version)
49 | })
50 |
51 | if err ~= nil then
52 | error(err)
53 | end
54 |
55 | if resp.status_code ~= 200 then
56 | return nil
57 | end
58 |
59 | local body = json.decode(resp.body)
60 | local binaryInfo = nil
61 |
62 | for _, bin in pairs(body) do
63 | local bin_os = bin.binary.os
64 | local bin_arch = bin.binary.architecture
65 | local bin_type = bin.binary.image_type
66 | if bin_os == type.osType and bin_arch == type.archType and bin_type == "jdk" then
67 | binaryInfo = bin
68 | break
69 | end
70 | end
71 |
72 | if binaryInfo == nil then
73 | return nil
74 | else
75 | return {
76 | version = version,
77 | url = binaryInfo.binary.package.link,
78 | sha256 = (binaryInfo.binary.package.sha265sum or nil),
79 | }
80 | end
81 |
82 | end
83 |
84 | function getOsTypeAndArch()
85 | local osType = OS_TYPE
86 | local archType = ARCH_TYPE
87 | if OS_TYPE == "darwin" then
88 | osType = "mac"
89 | end
90 | if ARCH_TYPE == "amd64" then
91 | archType = "x64"
92 | elseif ARCH_TYPE == "arm64" then
93 | archType = "aarch64"
94 | elseif ARCH_TYPE == "386" then
95 | archType = "x32"
96 | end
97 | return {
98 | osType = osType, archType = archType
99 | }
100 | end
101 |
102 | function PLUGIN:Available(ctx)
103 | local resp, err = http.get({
104 | url = AvailableVersionsUrl
105 | })
106 | if err ~= nil or resp.status_code ~= 200 then
107 | return {}
108 | end
109 | local body = json.decode(resp.body)
110 | local ltsMap = {}
111 | for _, v in ipairs(body.available_lts_releases) do
112 | ltsMap[v] = v
113 | end
114 | local result = {}
115 | for _, v in ipairs(body.available_releases) do
116 | local note = ""
117 | if ltsMap[v] ~= nil then
118 | note = "LTS"
119 | end
120 | table.insert(result, {
121 | version = v .. '',
122 | note = note,
123 | })
124 | end
125 | return result
126 | end
127 |
128 | function PLUGIN:EnvKeys(ctx)
129 | local path = ctx.path
130 | if OS_TYPE == "darwin" then
131 | path = path .. "/Contents/Home"
132 | end
133 | return {
134 | {
135 | key = "JAVA_HOME",
136 | value = path
137 | },
138 | {
139 | key = "PATH",
140 | value = path .. "/bin"
141 | }
142 | }
143 | end
144 |
--------------------------------------------------------------------------------
/java/microsoft-adoptium-jdk.lua:
--------------------------------------------------------------------------------
1 | --- Copyright 2024 [axdank axdank@proton.me]
2 | --
3 | -- Licensed under the Apache License, Version 2.0 (the "License");
4 | -- you may not use this file except in compliance with the License.
5 | -- You may obtain a copy of the License at
6 | --
7 | -- http://www.apache.org/licenses/LICENSE-2.0
8 | --
9 | -- Unless required by applicable law or agreed to in writing, software
10 | -- distributed under the License is distributed on an "AS IS" BASIS,
11 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | -- See the License for the specific language governing permissions and
13 | -- limitations under the License.
14 |
15 | local http = require("http")
16 | local json = require("json")
17 |
18 | OS_TYPE = ""
19 | ARCH_TYPE = ""
20 |
21 | AvailableVersionsUrl = "https://marketplace-api.adoptium.net/v1/info/available_releases/microsoft"
22 | DownloadLatestUrl = "https://marketplace-api.adoptium.net/v1/assets/latest/microsoft/%s/hotspot"
23 |
24 | PLUGIN = {
25 | name = "java",
26 | author = "axdank",
27 | version = "0.0.4",
28 | description = "Microsoft JDK - Adoptium",
29 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/java/microsoft-adoptium-jdk.lua",
30 | minRuntimeVersion = "0.3.0",
31 | manifestUrl = "https://github.com/version-fox/vfox-java/releases/download/manifest/manifest.json"
32 | }
33 |
34 | function PLUGIN:PreInstall(ctx)
35 | local version = ctx.version
36 |
37 | if version == nil or version == "" then
38 | return nil
39 | end
40 |
41 | if tonumber(version) == nil then
42 | error("invalid version: " .. ctx.version)
43 | end
44 |
45 | local type = getOsTypeAndArch()
46 |
47 | local resp, err = http.get({
48 | url = DownloadLatestUrl:format(version)
49 | })
50 |
51 | if err ~= nil then
52 | error(err)
53 | end
54 |
55 | if resp.status_code ~= 200 then
56 | return nil
57 | end
58 |
59 | local body = json.decode(resp.body)
60 | local binaryInfo = nil
61 |
62 | for _, bin in pairs(body) do
63 | local bin_os = bin.binary.os
64 | local bin_arch = bin.binary.architecture
65 | local bin_type = bin.binary.image_type
66 | if bin_os == type.osType and bin_arch == type.archType and bin_type == "jdk" then
67 | binaryInfo = bin
68 | break
69 | end
70 | end
71 |
72 | if binaryInfo == nil then
73 | return nil
74 | else
75 | return {
76 | version = version,
77 | url = binaryInfo.binary.package.link,
78 | sha256 = (binaryInfo.binary.package.sha265sum or nil),
79 | }
80 | end
81 |
82 | end
83 |
84 | function getOsTypeAndArch()
85 | local osType = OS_TYPE
86 | local archType = ARCH_TYPE
87 | if OS_TYPE == "darwin" then
88 | osType = "mac"
89 | end
90 | if ARCH_TYPE == "amd64" then
91 | archType = "x64"
92 | elseif ARCH_TYPE == "arm64" then
93 | archType = "aarch64"
94 | elseif ARCH_TYPE == "386" then
95 | archType = "x32"
96 | end
97 | return {
98 | osType = osType, archType = archType
99 | }
100 | end
101 |
102 | function PLUGIN:Available(ctx)
103 | local resp, err = http.get({
104 | url = AvailableVersionsUrl
105 | })
106 | if err ~= nil or resp.status_code ~= 200 then
107 | return {}
108 | end
109 | local body = json.decode(resp.body)
110 | local ltsMap = {}
111 | for _, v in ipairs(body.available_lts_releases) do
112 | ltsMap[v] = v
113 | end
114 | local result = {}
115 | for _, v in ipairs(body.available_releases) do
116 | local note = ""
117 | if ltsMap[v] ~= nil then
118 | note = "LTS"
119 | end
120 | table.insert(result, {
121 | version = v .. '',
122 | note = note,
123 | })
124 | end
125 | return result
126 | end
127 |
128 | function PLUGIN:EnvKeys(ctx)
129 | local path = ctx.path
130 | if OS_TYPE == "darwin" then
131 | path = path .. "/Contents/Home"
132 | end
133 | return {
134 | {
135 | key = "JAVA_HOME",
136 | value = path
137 | },
138 | {
139 | key = "PATH",
140 | value = path .. "/bin"
141 | }
142 | }
143 | end
144 |
--------------------------------------------------------------------------------
/java/redhat-adoptium-jdk.lua:
--------------------------------------------------------------------------------
1 | --- Copyright 2024 [axdank axdank@proton.me]
2 | --
3 | -- Licensed under the Apache License, Version 2.0 (the "License");
4 | -- you may not use this file except in compliance with the License.
5 | -- You may obtain a copy of the License at
6 | --
7 | -- http://www.apache.org/licenses/LICENSE-2.0
8 | --
9 | -- Unless required by applicable law or agreed to in writing, software
10 | -- distributed under the License is distributed on an "AS IS" BASIS,
11 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | -- See the License for the specific language governing permissions and
13 | -- limitations under the License.
14 |
15 | local http = require("http")
16 | local json = require("json")
17 |
18 | OS_TYPE = ""
19 | ARCH_TYPE = ""
20 |
21 | AvailableVersionsUrl = "https://marketplace-api.adoptium.net/v1/info/available_releases/redhat"
22 | DownloadLatestUrl = "https://marketplace-api.adoptium.net/v1/assets/latest/redhat/%s/hotspot"
23 |
24 | PLUGIN = {
25 | name = "java",
26 | author = "axdank",
27 | version = "0.0.4",
28 | description = "RedHat JDK - Adoptium",
29 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/java/redhat-adoptium-jdk.lua",
30 | minRuntimeVersion = "0.3.0",
31 | manifestUrl = "https://github.com/version-fox/vfox-java/releases/download/manifest/manifest.json"
32 | }
33 |
34 | function PLUGIN:PreInstall(ctx)
35 | local version = ctx.version
36 |
37 | if version == nil or version == "" then
38 | return nil
39 | end
40 |
41 | if tonumber(version) == nil then
42 | error("invalid version: " .. ctx.version)
43 | end
44 |
45 | local type = getOsTypeAndArch()
46 |
47 | local resp, err = http.get({
48 | url = DownloadLatestUrl:format(version)
49 | })
50 |
51 | if err ~= nil then
52 | error(err)
53 | end
54 |
55 | if resp.status_code ~= 200 then
56 | return nil
57 | end
58 |
59 | local body = json.decode(resp.body)
60 | local binaryInfo = nil
61 |
62 | for _, bin in pairs(body) do
63 | local bin_os = bin.binary.os
64 | local bin_arch = bin.binary.architecture
65 | local bin_type = bin.binary.image_type
66 | if bin_os == type.osType and bin_arch == type.archType and bin_type == "jdk" then
67 | binaryInfo = bin
68 | break
69 | end
70 | end
71 |
72 | if binaryInfo == nil then
73 | return nil
74 | else
75 | return {
76 | version = version,
77 | url = binaryInfo.binary.package.link,
78 | sha256 = (binaryInfo.binary.package.sha265sum or nil),
79 | }
80 | end
81 |
82 | end
83 |
84 | function getOsTypeAndArch()
85 | local osType = OS_TYPE
86 | local archType = ARCH_TYPE
87 | if OS_TYPE == "darwin" then
88 | osType = "mac"
89 | end
90 | if ARCH_TYPE == "amd64" then
91 | archType = "x64"
92 | elseif ARCH_TYPE == "arm64" then
93 | archType = "aarch64"
94 | elseif ARCH_TYPE == "386" then
95 | archType = "x32"
96 | end
97 | return {
98 | osType = osType, archType = archType
99 | }
100 | end
101 |
102 | function PLUGIN:Available(ctx)
103 | local resp, err = http.get({
104 | url = AvailableVersionsUrl
105 | })
106 | if err ~= nil or resp.status_code ~= 200 then
107 | return {}
108 | end
109 | local body = json.decode(resp.body)
110 | local ltsMap = {}
111 | for _, v in ipairs(body.available_lts_releases) do
112 | ltsMap[v] = v
113 | end
114 | local result = {}
115 | for _, v in ipairs(body.available_releases) do
116 | local note = ""
117 | if ltsMap[v] ~= nil then
118 | note = "LTS"
119 | end
120 | table.insert(result, {
121 | version = v .. '',
122 | note = note,
123 | })
124 | end
125 | return result
126 | end
127 |
128 | function PLUGIN:EnvKeys(ctx)
129 | local path = ctx.path
130 | if OS_TYPE == "darwin" then
131 | path = path .. "/Contents/Home"
132 | end
133 | return {
134 | {
135 | key = "JAVA_HOME",
136 | value = path
137 | },
138 | {
139 | key = "PATH",
140 | value = path .. "/bin"
141 | }
142 | }
143 | end
144 |
--------------------------------------------------------------------------------
/kotlin/kotlin.lua:
--------------------------------------------------------------------------------
1 | --- Copyright 2024 Han Li
2 | --
3 | -- Licensed under the Apache License, Version 2.0 (the "License");
4 | -- you may not use this file except in compliance with the License.
5 | -- You may obtain a copy of the License at
6 | --
7 | -- http://www.apache.org/licenses/LICENSE-2.0
8 | --
9 | -- Unless required by applicable law or agreed to in writing, software
10 | -- distributed under the License is distributed on an "AS IS" BASIS,
11 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | -- See the License for the specific language governing permissions and
13 | -- limitations under the License.
14 | --- Default global variable
15 | --- OS_TYPE: windows, linux, darwin
16 | --- ARCH_TYPE: 386, amd64, arm, arm64 ...
17 | local http = require("http")
18 | local html = require("html")
19 |
20 | OS_TYPE = ""
21 | ARCH_TYPE = ""
22 |
23 | DownloadURL = "https://github.com/JetBrains/kotlin/releases/download/v%s/kotlin-compiler-%s.zip"
24 |
25 |
26 | PLUGIN = {
27 | name = "kotlin",
28 | author = "Aooohan",
29 | version = "0.0.3",
30 | description = "Kotlin plugin",
31 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/kotlin/kotlin.lua",
32 | manifestUrl = "https://github.com/version-fox/vfox-kotlin/releases/download/manifest/manifest.json",
33 | minRuntimeVersion = "0.3.0",
34 | }
35 |
36 | function PLUGIN:PreInstall(ctx)
37 | local version = ctx.version
38 |
39 | if version == "latest" then
40 | local lists = self:Available({})
41 | version = lists[1].version
42 | end
43 | local url = DownloadURL:format(version, version)
44 | local resp, err = http.head({
45 | url = url
46 | })
47 | if err ~= nil or resp.status_code ~= 200 then
48 | error("Current version information not detected.")
49 | end
50 | if compare_versions({ version = version },{version = "1.9.0"}) or version=="1.9.0" then
51 | resp, err = http.get({
52 | url = url .. ".sha256"
53 | })
54 | if err ~= nil or resp.status_code ~= 200 then
55 | error("Current version checksum not detected.")
56 | end
57 | return {
58 | version = version,
59 | url = url,
60 | sha256 = resp.body
61 | }
62 | else
63 | return {
64 | version = version,
65 | url = url
66 | }
67 | end
68 | end
69 |
70 | function compare_versions(v1o, v2o)
71 | local v1 = v1o.version
72 | local v2 = v2o.version
73 | local v1_parts = {}
74 | for part in string.gmatch(v1, "[^.]+") do
75 | table.insert(v1_parts, tonumber(part))
76 | end
77 |
78 | local v2_parts = {}
79 | for part in string.gmatch(v2, "[^.]+") do
80 | table.insert(v2_parts, tonumber(part))
81 | end
82 |
83 | for i = 1, math.max(#v1_parts, #v2_parts) do
84 | local v1_part = v1_parts[i] or 0
85 | local v2_part = v2_parts[i] or 0
86 | if v1_part > v2_part then
87 | return true
88 | elseif v1_part < v2_part then
89 | return false
90 | end
91 | end
92 |
93 | return false
94 | end
95 |
96 | function PLUGIN:Available(ctx)
97 | local resp, err = http.get({
98 | url = "https://kotlinlang.org/docs/releases.html#release-details"
99 | })
100 | if err ~= nil or resp.status_code ~= 200 then
101 | return {}
102 | end
103 | local result = {}
104 | html.parse(resp.body):find("tbody tr"):each(function(i, sel)
105 | local version = sel:find("td b"):first():text()
106 | table.insert(result, {
107 | version = version,
108 | note = "",
109 | })
110 | end)
111 | return result
112 | end
113 |
114 | --- Expansion point
115 | function PLUGIN:PostInstall(ctx)
116 | end
117 |
118 | function PLUGIN:EnvKeys(ctx)
119 | local version_path = ctx.path
120 | return {
121 | {
122 | key = "PATH",
123 | value = version_path .. "/bin"
124 | },
125 | }
126 | end
127 |
--------------------------------------------------------------------------------
/maven/maven.lua:
--------------------------------------------------------------------------------
1 | --- Copyright 2024 [lihan aooohan@gmail.com]
2 | --
3 | -- Licensed under the Apache License, Version 2.0 (the "License");
4 | -- you may not use this file except in compliance with the License.
5 | -- You may obtain a copy of the License at
6 | --
7 | -- http://www.apache.org/licenses/LICENSE-2.0
8 | --
9 | -- Unless required by applicable law or agreed to in writing, software
10 | -- distributed under the License is distributed on an "AS IS" BASIS,
11 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | -- See the License for the specific language governing permissions and
13 | -- limitations under the License.
14 |
15 | local http = require("http")
16 | local html = require("html")
17 |
18 | OS_TYPE = ""
19 | ARCH_TYPE = ""
20 |
21 | MAVEN_URL = "https://archive.apache.org/dist/maven/"
22 | FILE_URL = "https://archive.apache.org/dist/maven/maven-%s/%s/binaries/apache-maven-%s-bin.tar.gz"
23 | CHECKSUM_URL = "https://archive.apache.org/dist/maven/maven-%s/%s/binaries/apache-maven-%s-bin.tar.gz.%s"
24 |
25 | PLUGIN = {
26 | --- Plugin name
27 | name = "maven",
28 | --- Plugin author
29 | author = "Aooohan",
30 | --- Plugin version
31 | version = "0.0.3",
32 | -- Update URL
33 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/maven/maven.lua",
34 | minRuntimeVersion = "0.3.0",
35 | manifestUrl = "https://github.com/version-fox/vfox-maven/releases/download/manifest/manifest.json"
36 | }
37 |
38 | function PLUGIN:PreInstall(ctx)
39 | local v = ctx.version
40 | local major = string.sub(v, 1, 1)
41 | if tonumber(major) ~= nil then
42 | if major == "3" or major == "4" then
43 | local checksums = {
44 | sha512 = CHECKSUM_URL:format(major, v, v, "sha512"),
45 | md5 = CHECKSUM_URL:format(major, v, v, "md5"),
46 | sha1 = CHECKSUM_URL:format(major, v, v, "sha1"),
47 | }
48 | for k, url in pairs(checksums) do
49 | local resp, err = http.get({
50 | url = url
51 | })
52 | if err == nil and resp.status_code == 200 then
53 | local result = {
54 | version = v,
55 | url = FILE_URL:format(major, v, v),
56 | }
57 | local removeSpace = string.match(resp.body,"(.-)%s")
58 | result[k] = removeSpace or resp.body
59 | return result
60 | end
61 | end
62 | else
63 | error("invalid version: " .. v)
64 | end
65 | else
66 | error("invalid version: " .. v)
67 | end
68 | return {}
69 | end
70 |
71 |
72 | function PLUGIN:PostInstall(ctx)
73 | end
74 |
75 | function PLUGIN:Available(ctx)
76 | local m4 = parseVersion("maven-4/")
77 | local m3 = parseVersion("maven-3/")
78 | for _, v in ipairs(m3) do
79 | table.insert(m4, v)
80 | end
81 | table.sort(m4, function(a, b)
82 | return a.version > b.version
83 | end)
84 | return m4
85 | end
86 |
87 | function parseVersion(path)
88 | local resp, err = http.get({
89 | url = MAVEN_URL .. path
90 | })
91 | if err ~= nil or resp.status_code ~= 200 then
92 | error("paring release info failed." .. err)
93 | end
94 | local result = {}
95 | html.parse(resp.body):find("a"):each(function(i, selection)
96 | local href = selection:attr("href")
97 | local sn = string.match(href, "^%d")
98 | local es = string.match(href, "/$")
99 | if sn and es then
100 | table.insert(result, {
101 | version = string.sub(href, 1, -2),
102 | note = "",
103 | })
104 | end
105 | end)
106 | return result
107 | end
108 |
109 | function PLUGIN:EnvKeys(ctx)
110 | local mainPath = ctx.path
111 | return {
112 | {
113 | key = "PATH",
114 | value = mainPath .. "/bin"
115 | }
116 | }
117 | end
118 |
--------------------------------------------------------------------------------
/nodejs/nodejs.lua:
--------------------------------------------------------------------------------
1 | --- Default global variable
2 | --- OS_TYPE: windows, linux, darwin
3 | --- ARCH_TYPE: 386, amd64, arm, arm64 ...
4 | local http = require("http")
5 | local json = require("json")
6 |
7 | OS_TYPE = ""
8 | ARCH_TYPE = ""
9 |
10 | NodeBaseUrl = "https://nodejs.org/dist/v%s/"
11 | FileName = "node-v%s-%s-%s%s"
12 | npmDownloadUrl = "https://github.com/npm/cli/archive/v%s.%s"
13 |
14 | VersionSourceUrl = "https://nodejs.org/dist/index.json"
15 |
16 | PLUGIN = {
17 | name = "nodejs",
18 | author = "Aooohan",
19 | version = "0.0.8",
20 | description = "Node.js",
21 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/nodejs/nodejs.lua",
22 | manifestUrl = "https://github.com/version-fox/vfox-nodejs/releases/download/manifest/manifest.json",
23 | minRuntimeVersion = "0.3.0",
24 | }
25 |
26 | function PLUGIN:PreInstall(ctx)
27 | local version = ctx.version
28 |
29 | if version == "latest" then
30 | local lists = self:Available({})
31 | version = lists[1].version
32 | end
33 |
34 | if not is_semver_simple(version) then
35 | local lists = self:Available({})
36 | local shorthands = calculate_shorthand(lists)
37 | version = shorthands[version]
38 | end
39 |
40 | if (version == nil) then
41 | error("version not found for provided version " .. version)
42 | end
43 |
44 | local arch_type = ARCH_TYPE
45 | local ext = ".tar.gz"
46 | local osType = OS_TYPE
47 | if arch_type == "amd64" then
48 | arch_type = "x64"
49 | end
50 | if OS_TYPE == "windows" then
51 | ext = ".zip"
52 | osType = "win"
53 | end
54 |
55 | -- add logic for macOS M1~
56 | if OS_TYPE == "darwin" then
57 | local major, _ = extract_semver(version)
58 | if major and tonumber(major) <= 16 then
59 | arch_type = "x64"
60 | end
61 | end
62 |
63 | local filename = FileName:format(version, osType, arch_type, ext)
64 | local baseUrl = NodeBaseUrl:format(version)
65 |
66 | local resp, err = http.get({
67 | url = baseUrl .. "SHASUMS256.txt"
68 | })
69 | if err ~= nil or resp.status_code ~= 200 then
70 | error("get checksum failed")
71 | end
72 | local checksum = get_checksum(resp.body, filename)
73 | return {
74 | version = version,
75 | url = baseUrl .. filename,
76 | sha256 = checksum,
77 | }
78 | end
79 |
80 | function compare_versions(v1o, v2o)
81 | local v1 = v1o.version
82 | local v2 = v2o.version
83 | local v1_parts = {}
84 | for part in string.gmatch(v1, "[^.]+") do
85 | table.insert(v1_parts, tonumber(part))
86 | end
87 |
88 | local v2_parts = {}
89 | for part in string.gmatch(v2, "[^.]+") do
90 | table.insert(v2_parts, tonumber(part))
91 | end
92 |
93 | for i = 1, math.max(#v1_parts, #v2_parts) do
94 | local v1_part = v1_parts[i] or 0
95 | local v2_part = v2_parts[i] or 0
96 | if v1_part > v2_part then
97 | return true
98 | elseif v1_part < v2_part then
99 | return false
100 | end
101 | end
102 |
103 | return false
104 | end
105 |
106 | function get_checksum(file_content, file_name)
107 | for line in string.gmatch(file_content, '([^\n]*)\n?') do
108 | local checksum, name = string.match(line, '(%w+)%s+(%S+)')
109 | if name == file_name then
110 | return checksum
111 | end
112 | end
113 | return nil
114 | end
115 |
116 | available_result = nil
117 |
118 | function PLUGIN:Available(ctx)
119 | if available_result then
120 | return available_result
121 | end
122 |
123 | local resp, err = http.get({
124 | url = VersionSourceUrl
125 | })
126 | if err ~= nil or resp.status_code ~= 200 then
127 | return {}
128 | end
129 | local body = json.decode(resp.body)
130 | local result = {}
131 |
132 | for _, v in ipairs(body) do
133 | table.insert(result, {
134 | version = string.gsub(v.version, "^v", ""),
135 | note = v.lts and "LTS" or "",
136 | addition = {
137 | {
138 | name = "npm",
139 | version = v.npm,
140 | }
141 | }
142 | })
143 | end
144 | table.sort(result, compare_versions)
145 | available_result = result
146 | return result
147 | end
148 |
149 | --- Expansion point
150 | function PLUGIN:PostInstall(ctx)
151 | local rootPath = ctx.rootPath
152 | local sdkInfo = ctx.sdkInfo['nodejs']
153 | local path = sdkInfo.path
154 | local version = sdkInfo.version
155 | local name = sdkInfo.name
156 | end
157 |
158 | function PLUGIN:EnvKeys(ctx)
159 | local version_path = ctx.path
160 | if OS_TYPE == "windows" then
161 | return {
162 | {
163 | key = "PATH",
164 | value = version_path
165 | },
166 | }
167 | else
168 | return {
169 | {
170 | key = "PATH",
171 | value = version_path .. "/bin"
172 | },
173 | }
174 | end
175 | end
176 |
177 | function PLUGIN:PreUse(ctx)
178 | --- user input version
179 | local version = ctx.version
180 |
181 | local shorthands = calculate_shorthand(ctx.installedSdks)
182 |
183 | if not is_semver_simple(version) then
184 | version = shorthands[version]
185 | end
186 |
187 | --- return the version information
188 | return {
189 | version = version,
190 | }
191 | end
192 |
193 | function is_semver_simple(str)
194 | -- match pattern: three digits, separated by dot
195 | local pattern = "^%d+%.%d+%.%d+$"
196 | return str:match(pattern) ~= nil
197 | end
198 |
199 | function extract_semver(semver)
200 | local pattern = "^(%d+)%.(%d+)%.[%d.]+$"
201 | local major, minor = semver:match(pattern)
202 | return major, minor
203 | end
204 |
205 | function calculate_shorthand(list)
206 | local versions_shorthand = {}
207 | for _, v in pairs(list) do
208 | local version = v.version
209 | local major, minor = extract_semver(version)
210 |
211 | if major then
212 | if not versions_shorthand[major] then
213 | versions_shorthand[major] = version
214 | else
215 | if compare_versions({ version = version }, { version = versions_shorthand[major] }) then
216 | versions_shorthand[major] = version
217 | end
218 | end
219 |
220 | if minor then
221 | local major_minor = major .. "." .. minor
222 | if not versions_shorthand[major_minor] then
223 | versions_shorthand[major_minor] = version
224 | else
225 | if compare_versions({ version = version }, { version = versions_shorthand[major_minor] }) then
226 | versions_shorthand[major_minor] = version
227 | end
228 | end
229 | end
230 | end
231 | end
232 |
233 | return versions_shorthand
234 | end
235 |
--------------------------------------------------------------------------------
/nodejs/npmmirror.lua:
--------------------------------------------------------------------------------
1 | --- Default global variable
2 | --- OS_TYPE: windows, linux, darwin
3 | --- ARCH_TYPE: 386, amd64, arm, arm64 ...
4 | local http = require("http")
5 | local json = require("json")
6 |
7 | OS_TYPE = ""
8 | ARCH_TYPE = ""
9 |
10 | NodeBaseUrl = "https://cdn.npmmirror.com/binaries/node/v%s/"
11 | FileName = "node-v%s-%s-%s%s"
12 | npmDownloadUrl = "https://cdn.npmmirror.com/binaries/node/npm/v%s.%s"
13 |
14 | VersionSourceUrl = "https://cdn.npmmirror.com/binaries/node/index.json"
15 |
16 | PLUGIN = {
17 | name = "nodejs",
18 | author = "yimiaoxiehou",
19 | version = "0.0.6",
20 | description = "install Node.js use https://cdn.npmmirror.com",
21 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/nodejs/npmmirror.lua",
22 | manifestUrl = "https://github.com/version-fox/vfox-nodejs/releases/download/manifest/manifest.json",
23 | minRuntimeVersion = "0.3.0",
24 | }
25 |
26 | function PLUGIN:PreInstall(ctx)
27 | local version = ctx.version
28 |
29 | if version == "latest" then
30 | local lists = self:Available({})
31 | version = lists[1].version
32 | end
33 |
34 | if not is_semver_simple(version) then
35 | local lists = self:Available({})
36 | local shorthands = calculate_shorthand(lists)
37 | version = shorthands[version]
38 | end
39 |
40 | if (version == nil) then
41 | error("version not found for provided version " .. version)
42 | end
43 |
44 | local arch_type = ARCH_TYPE
45 | local ext = ".tar.gz"
46 | local osType = OS_TYPE
47 | if arch_type == "amd64" then
48 | arch_type = "x64"
49 | end
50 | if OS_TYPE == "windows" then
51 | ext = ".zip"
52 | osType = "win"
53 | end
54 |
55 | -- add logic for macOS M1~
56 | if OS_TYPE == "darwin" then
57 | local major, _ = extract_semver(version)
58 | if major and tonumber(major) <= 16 then
59 | arch_type = "x64"
60 | end
61 | end
62 |
63 | local filename = FileName:format(version, osType, arch_type, ext)
64 | local baseUrl = NodeBaseUrl:format(version)
65 |
66 | local resp, err = http.get({
67 | url = baseUrl .. "SHASUMS256.txt"
68 | })
69 | if err ~= nil or resp.status_code ~= 200 then
70 | error("get checksum failed")
71 | end
72 | local checksum = get_checksum(resp.body, filename)
73 | return {
74 | version = version,
75 | url = baseUrl .. filename,
76 | sha256 = checksum,
77 | }
78 | end
79 |
80 | function compare_versions(v1o, v2o)
81 | local v1 = v1o.version
82 | local v2 = v2o.version
83 | local v1_parts = {}
84 | for part in string.gmatch(v1, "[^.]+") do
85 | table.insert(v1_parts, tonumber(part))
86 | end
87 |
88 | local v2_parts = {}
89 | for part in string.gmatch(v2, "[^.]+") do
90 | table.insert(v2_parts, tonumber(part))
91 | end
92 |
93 | for i = 1, math.max(#v1_parts, #v2_parts) do
94 | local v1_part = v1_parts[i] or 0
95 | local v2_part = v2_parts[i] or 0
96 | if v1_part > v2_part then
97 | return true
98 | elseif v1_part < v2_part then
99 | return false
100 | end
101 | end
102 |
103 | return false
104 | end
105 |
106 | function get_checksum(file_content, file_name)
107 | for line in string.gmatch(file_content, '([^\n]*)\n?') do
108 | local checksum, name = string.match(line, '(%w+)%s+(%S+)')
109 | if name == file_name then
110 | return checksum
111 | end
112 | end
113 | return nil
114 | end
115 |
116 | available_result = nil
117 |
118 | function PLUGIN:Available(ctx)
119 | if available_result then
120 | return available_result
121 | end
122 |
123 | local resp, err = http.get({
124 | url = VersionSourceUrl
125 | })
126 | if err ~= nil or resp.status_code ~= 200 then
127 | return {}
128 | end
129 | local body = json.decode(resp.body)
130 | local result = {}
131 |
132 | for _, v in ipairs(body) do
133 | table.insert(result, {
134 | version = string.gsub(v.version, "^v", ""),
135 | note = v.lts and "LTS" or "",
136 | addition = {
137 | {
138 | name = "npm",
139 | version = v.npm,
140 | }
141 | }
142 | })
143 | end
144 | table.sort(result, compare_versions)
145 | available_result = result
146 | return result
147 | end
148 |
149 | --- Expansion point
150 | function PLUGIN:PostInstall(ctx)
151 | local rootPath = ctx.rootPath
152 | local sdkInfo = ctx.sdkInfo['nodejs']
153 | local path = sdkInfo.path
154 | local version = sdkInfo.version
155 | local name = sdkInfo.name
156 | end
157 |
158 | function PLUGIN:EnvKeys(ctx)
159 | local version_path = ctx.path
160 | if OS_TYPE == "windows" then
161 | return {
162 | {
163 | key = "PATH",
164 | value = version_path
165 | },
166 | }
167 | else
168 | return {
169 | {
170 | key = "PATH",
171 | value = version_path .. "/bin"
172 | },
173 | }
174 | end
175 | end
176 |
177 | function PLUGIN:PreUse(ctx)
178 | --- user input version
179 | local version = ctx.version
180 |
181 | local shorthands = calculate_shorthand(ctx.installedSdks)
182 |
183 | if not is_semver_simple(version) then
184 | version = shorthands[version]
185 | end
186 |
187 | --- return the version information
188 | return {
189 | version = version,
190 | }
191 | end
192 |
193 | function is_semver_simple(str)
194 | -- match pattern: three digits, separated by dot
195 | local pattern = "^%d+%.%d+%.%d+$"
196 | return str:match(pattern) ~= nil
197 | end
198 |
199 | function extract_semver(semver)
200 | local pattern = "^(%d+)%.(%d+)%.[%d.]+$"
201 | local major, minor = semver:match(pattern)
202 | return major, minor
203 | end
204 |
205 | function calculate_shorthand(list)
206 | local versions_shorthand = {}
207 | for _, v in pairs(list) do
208 | local version = v.version
209 | local major, minor = extract_semver(version)
210 |
211 | if major then
212 | if not versions_shorthand[major] then
213 | versions_shorthand[major] = version
214 | else
215 | if compare_versions({ version = version }, { version = versions_shorthand[major] }) then
216 | versions_shorthand[major] = version
217 | end
218 | end
219 |
220 | if minor then
221 | local major_minor = major .. "." .. minor
222 | if not versions_shorthand[major_minor] then
223 | versions_shorthand[major_minor] = version
224 | else
225 | if compare_versions({ version = version }, { version = versions_shorthand[major_minor] }) then
226 | versions_shorthand[major_minor] = version
227 | end
228 | end
229 | end
230 | end
231 | end
232 |
233 | return versions_shorthand
234 | end
235 |
--------------------------------------------------------------------------------
/python/npmmirror.lua:
--------------------------------------------------------------------------------
1 | --- Copyright 2024 [lihan aooohan@gmail.com]
2 | --
3 | -- Licensed under the Apache License, Version 2.0 (the "License");
4 | -- you may not use this file except in compliance with the License.
5 | -- You may obtain a copy of the License at
6 | --
7 | -- http://www.apache.org/licenses/LICENSE-2.0
8 | --
9 | -- Unless required by applicable law or agreed to in writing, software
10 | -- distributed under the License is distributed on an "AS IS" BASIS,
11 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | -- See the License for the specific language governing permissions and
13 | -- limitations under the License.
14 |
15 | local http = require("http")
16 | local json = require("json")
17 | OS_TYPE = ""
18 | ARCH_TYPE = ""
19 |
20 | local PYTHON_URL = "https://registry.npmmirror.com/-/binary/python/"
21 |
22 | local DOWNLOAD_SOURCE = {
23 | --- TODO support zip or web-based installers
24 | WEB_BASED = "https://registry.npmmirror.com/-/binary/python/%s/python-%s-%s-webinstall.exe",
25 | ZIP = "https://registry.npmmirror.com/-/binary/python/%s/python-%s-embed-%s.zip",
26 | MSI = "",
27 | --- Currently only exe installers are supported
28 | EXE = "https://registry.npmmirror.com/-/binary/python/%s/python-%s%s.exe",
29 | SOURCE = "https://registry.npmmirror.com/-/binary/python/%s/Python-%s.tar.xz"
30 | }
31 |
32 | PLUGIN = {
33 | --- Plugin name
34 | name = "python",
35 | --- Plugin author
36 | author = "aooohan",
37 | --- Plugin version
38 | version = "0.0.4",
39 | description = "vfox >= 0.2.3 !!! From npmmirror.org. For Windows, only support >=3.5.0, but no restrictions for unix-like",
40 | -- Update URL
41 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/python/npmmirror.lua",
42 | manifestUrl = "https://github.com/version-fox/vfox-python/releases/download/manifest/manifest.json",
43 | minRuntimeVersion = "0.3.0",
44 | }
45 |
46 | function PLUGIN:PreInstall(ctx)
47 | local version = ctx.version
48 | if version == "latest" then
49 | version = self:Available({})[1].version
50 | end
51 | if not checkIsReleaseVersion(version) then
52 | error("The current version is not released")
53 | return
54 | end
55 | if OS_TYPE == "windows" then
56 | local url, filename = checkAvailableReleaseForWindows(version)
57 | return {
58 | version = version,
59 | url = url,
60 | note = filename
61 | }
62 | else
63 | return {
64 | version = version,
65 | }
66 | end
67 | end
68 |
69 | function checkAvailableReleaseForWindows(version)
70 | local archType = ARCH_TYPE
71 | if ARCH_TYPE == "386" then
72 | archType = ""
73 | else
74 | archType = "-" .. archType
75 | end
76 | --- Currently only exe installers are supported
77 | --- TODO support zip or web-based installers
78 | local url = DOWNLOAD_SOURCE.EXE:format(version, version, archType)
79 | local resp, err = http.head({
80 | url = url
81 | })
82 | if err ~= nil or resp.status_code ~= 200 then
83 | error("No available installer found for current version")
84 | end
85 | return url, "python-" .. version .. archType .. ".exe"
86 | end
87 |
88 | function linuxCompile(ctx)
89 | local sdkInfo = ctx.sdkInfo['python']
90 | local path = sdkInfo.path
91 | local version = sdkInfo.version
92 | local pyenv_url = "https://github.com/pyenv/pyenv.git"
93 | local dest_pyenv_path = ctx.rootPath .. "/pyenv"
94 | local status = os.execute("git clone " .. pyenv_url .. " " .. dest_pyenv_path)
95 | if status ~= 0 then
96 | error("git clone failed")
97 | end
98 | local pyenv_build_path = dest_pyenv_path .. "/plugins/python-build/bin/python-build"
99 | print("Building python ...")
100 | status = os.execute(pyenv_build_path .. " " .. version .. " " .. path)
101 | if status ~= 0 then
102 | error("python build failed")
103 | end
104 | print("Build python success!")
105 | print("Cleaning up ...")
106 | status = os.execute("rm -rf " .. dest_pyenv_path)
107 | if status ~= 0 then
108 | error("remove build tool failed")
109 | end
110 | end
111 |
112 | function windowsCompile(ctx)
113 | local sdkInfo = ctx.sdkInfo['python']
114 | local path = sdkInfo.path
115 | local filename = sdkInfo.note
116 | --- Attention system difference
117 | local qInstallFile = path .. "\\" .. filename
118 | local qInstallPath = path
119 | --local exitCode = os.execute('msiexec /quiet /a "' .. qInstallFile .. '" TargetDir="' .. qInstallPath .. '"')
120 | print("Installing python, please wait patiently for a while, about two minutes.")
121 | local exitCode = os.execute(qInstallFile .. ' /quiet InstallAllUsers=0 PrependPath=0 TargetDir=' .. qInstallPath)
122 | if exitCode ~= 0 then
123 | error("error installing python")
124 | end
125 | print("Cleaning up ...")
126 | os.remove(qInstallFile)
127 | end
128 |
129 | function PLUGIN:PostInstall(ctx)
130 | if OS_TYPE == "windows" then
131 | return windowsCompile(ctx)
132 | else
133 | return linuxCompile(ctx)
134 | end
135 | end
136 |
137 | function PLUGIN:Available(ctx)
138 | return parseVersion()
139 | end
140 |
141 | function checkIsReleaseVersion(version)
142 | local resp, err = http.head({
143 | url = DOWNLOAD_SOURCE.SOURCE:format(version, version)
144 | })
145 | if err ~= nil or resp.status_code ~= 200 then
146 | return false
147 | end
148 | return true
149 | end
150 |
151 | function parseVersion()
152 | local resp, err = http.get({
153 | url = PYTHON_URL
154 | })
155 | if err ~= nil or resp.status_code ~= 200 then
156 | error("paring release info failed." .. err)
157 | end
158 | local body = json.decode(resp.body)
159 | local result = {}
160 | for _, v in ipairs(body) do
161 | local href = v.name
162 | local sn = string.match(href, "^%d")
163 | local es = string.match(href, "/$")
164 | if sn and es then
165 | local vn = string.sub(href, 1, -2)
166 | if OS_TYPE == "windows" then
167 | if compare_versions(vn, "3.5.0") >= 0 then
168 | table.insert(result, {
169 | version = string.sub(href, 1, -2),
170 | note = "",
171 | })
172 | end
173 | else
174 | table.insert(result, {
175 | version = vn,
176 | note = "",
177 | })
178 | end
179 | end
180 | end
181 | table.sort(result, function(a, b)
182 | return compare_versions(a.version, b.version) > 0
183 | end)
184 | return result
185 | end
186 |
187 | function PLUGIN:EnvKeys(ctx)
188 | local mainPath = ctx.path
189 | if OS_TYPE == "windows" then
190 | return {
191 | {
192 | key = "PATH",
193 | value = mainPath .. ';' .. mainPath .. "\\Scripts"
194 | }
195 | }
196 | else
197 | return {
198 | {
199 | key = "PATH",
200 | value = mainPath .. "/bin"
201 | }
202 | }
203 | end
204 | end
205 |
206 | function compare_versions(v1, v2)
207 | local v1_parts = {}
208 | for part in string.gmatch(v1, "[^.]+") do
209 | table.insert(v1_parts, tonumber(part))
210 | end
211 |
212 | local v2_parts = {}
213 | for part in string.gmatch(v2, "[^.]+") do
214 | table.insert(v2_parts, tonumber(part))
215 | end
216 |
217 | for i = 1, math.max(#v1_parts, #v2_parts) do
218 | local v1_part = v1_parts[i] or 0
219 | local v2_part = v2_parts[i] or 0
220 | if v1_part > v2_part then
221 | return 1
222 | elseif v1_part < v2_part then
223 | return -1
224 | end
225 | end
226 |
227 | return 0
228 | end
--------------------------------------------------------------------------------
/python/python.lua:
--------------------------------------------------------------------------------
1 | --- Copyright 2024 [lihan aooohan@gmail.com]
2 | --
3 | -- Licensed under the Apache License, Version 2.0 (the "License");
4 | -- you may not use this file except in compliance with the License.
5 | -- You may obtain a copy of the License at
6 | --
7 | -- http://www.apache.org/licenses/LICENSE-2.0
8 | --
9 | -- Unless required by applicable law or agreed to in writing, software
10 | -- distributed under the License is distributed on an "AS IS" BASIS,
11 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | -- See the License for the specific language governing permissions and
13 | -- limitations under the License.
14 |
15 | local http = require("http")
16 | local html = require("html")
17 | OS_TYPE = ""
18 | ARCH_TYPE = ""
19 |
20 | local PYTHON_URL = "https://www.python.org/ftp/python/"
21 |
22 | local DOWNLOAD_SOURCE = {
23 | --- TODO support zip or web-based installers
24 | WEB_BASED = "https://www.python.org/ftp/python/%s/python-%s%s-webinstall.exe",
25 | ZIP = "https://www.python.org/ftp/python/%s/python-%s-embed-%s.zip",
26 | MSI = "",
27 | --- Currently only exe installers are supported
28 | EXE = "https://www.python.org/ftp/python/%s/python-%s%s.exe",
29 | SOURCE = "https://www.python.org/ftp/python/%s/Python-%s.tar.xz"
30 | }
31 |
32 | PLUGIN = {
33 | --- Plugin name
34 | name = "python",
35 | --- Plugin author
36 | author = "aooohan",
37 | --- Plugin version
38 | version = "0.0.4",
39 | description = "vfox >= 0.2.3 !! For Windows, only support >=3.5.0, but no restrictions for unix-like",
40 | -- Update URL
41 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/python/python.lua",
42 | manifestUrl = "https://github.com/version-fox/vfox-python/releases/download/manifest/manifest.json",
43 | minRuntimeVersion = "0.3.0",
44 | }
45 |
46 | function PLUGIN:PreInstall(ctx)
47 | local version = ctx.version
48 | if version == "latest" then
49 | version = self:Available({})[1].version
50 | end
51 | if not checkIsReleaseVersion(version) then
52 | error("The current version is not released")
53 | return
54 | end
55 | if OS_TYPE == "windows" then
56 | local url, filename = checkAvailableReleaseForWindows(version)
57 | return {
58 | version = version,
59 | url = url,
60 | note = filename
61 | }
62 | else
63 | return {
64 | version = version,
65 | }
66 | end
67 | end
68 |
69 | function checkAvailableReleaseForWindows(version)
70 | local archType = ARCH_TYPE
71 | if ARCH_TYPE == "386" then
72 | archType = ""
73 | else
74 | archType = "-" .. archType
75 | end
76 | --- Currently only exe installers are supported
77 | --- TODO support zip or web-based installers
78 | local url = DOWNLOAD_SOURCE.EXE:format(version, version, archType)
79 | local resp, err = http.head({
80 | url = url
81 | })
82 | if err ~= nil or resp.status_code ~= 200 then
83 | error("No available installer found for current version")
84 | end
85 | return url, "python-" .. version .. archType .. ".exe"
86 | end
87 |
88 | function linuxCompile(ctx)
89 | local sdkInfo = ctx.sdkInfo['python']
90 | local path = sdkInfo.path
91 | local version = sdkInfo.version
92 | local pyenv_url = "https://github.com/pyenv/pyenv.git"
93 | local dest_pyenv_path = ctx.rootPath .. "/pyenv"
94 | local status = os.execute("git clone " .. pyenv_url .. " " .. dest_pyenv_path)
95 | if status ~= 0 then
96 | error("git clone failed")
97 | end
98 | local pyenv_build_path = dest_pyenv_path .. "/plugins/python-build/bin/python-build"
99 | print("Building python ...")
100 | status = os.execute(pyenv_build_path .. " " .. version .. " " .. path)
101 | if status ~= 0 then
102 | error("python build failed")
103 | end
104 | print("Build python success!")
105 | print("Cleaning up ...")
106 | status = os.execute("rm -rf " .. dest_pyenv_path)
107 | if status ~= 0 then
108 | error("remove build tool failed")
109 | end
110 | end
111 |
112 | function windowsCompile(ctx)
113 | local sdkInfo = ctx.sdkInfo['python']
114 | local path = sdkInfo.path
115 | local filename = sdkInfo.note
116 | --- Attention system difference
117 | local qInstallFile = path .. "\\" .. filename
118 | local qInstallPath = path
119 | --local exitCode = os.execute('msiexec /quiet /a "' .. qInstallFile .. '" TargetDir="' .. qInstallPath .. '"')
120 | print("Installing python, please wait patiently for a while, about two minutes.")
121 | local exitCode = os.execute(qInstallFile .. ' /quiet InstallAllUsers=0 PrependPath=0 TargetDir=' .. qInstallPath)
122 | if exitCode ~= 0 then
123 | error("error installing python")
124 | end
125 | print("Cleaning up ...")
126 | os.remove(qInstallFile)
127 | end
128 |
129 | function PLUGIN:PostInstall(ctx)
130 | if OS_TYPE == "windows" then
131 | return windowsCompile(ctx)
132 | else
133 | return linuxCompile(ctx)
134 | end
135 | end
136 |
137 | function PLUGIN:Available(ctx)
138 | return parseVersion()
139 | end
140 |
141 | function checkIsReleaseVersion(version)
142 | local resp, err = http.head({
143 | url = DOWNLOAD_SOURCE.SOURCE:format(version, version)
144 | })
145 | if err ~= nil or resp.status_code ~= 200 then
146 | return false
147 | end
148 | return true
149 | end
150 |
151 | function parseVersion()
152 | local resp, err = http.get({
153 | url = PYTHON_URL
154 | })
155 | if err ~= nil or resp.status_code ~= 200 then
156 | error("paring release info failed." .. err)
157 | end
158 | local result = {}
159 | html.parse(resp.body):find("a"):each(function(i, selection)
160 | local href = selection:attr("href")
161 | local sn = string.match(href, "^%d")
162 | local es = string.match(href, "/$")
163 | if sn and es then
164 | local vn = string.sub(href, 1, -2)
165 | if OS_TYPE == "windows" then
166 | if compare_versions(vn, "3.5.0") >= 0 then
167 | table.insert(result, {
168 | version = string.sub(href, 1, -2),
169 | note = "",
170 | })
171 | end
172 | else
173 | table.insert(result, {
174 | version = vn,
175 | note = "",
176 | })
177 | end
178 | end
179 | end)
180 | table.sort(result, function(a, b)
181 | return compare_versions(a.version, b.version) > 0
182 | end)
183 | return result
184 | end
185 |
186 | function PLUGIN:EnvKeys(ctx)
187 | local mainPath = ctx.path
188 | if OS_TYPE == "windows" then
189 | return {
190 | {
191 | key = "PATH",
192 | value = mainPath .. ';' .. mainPath .. "\\Scripts"
193 | }
194 | }
195 | else
196 | return {
197 | {
198 | key = "PATH",
199 | value = mainPath .. "/bin"
200 | }
201 | }
202 | end
203 | end
204 |
205 | function compare_versions(v1, v2)
206 | local v1_parts = {}
207 | for part in string.gmatch(v1, "[^.]+") do
208 | table.insert(v1_parts, tonumber(part))
209 | end
210 |
211 | local v2_parts = {}
212 | for part in string.gmatch(v2, "[^.]+") do
213 | table.insert(v2_parts, tonumber(part))
214 | end
215 |
216 | for i = 1, math.max(#v1_parts, #v2_parts) do
217 | local v1_part = v1_parts[i] or 0
218 | local v2_part = v2_parts[i] or 0
219 | if v1_part > v2_part then
220 | return 1
221 | elseif v1_part < v2_part then
222 | return -1
223 | end
224 | end
225 |
226 | return 0
227 | end
--------------------------------------------------------------------------------
/template.lua:
--------------------------------------------------------------------------------
1 | --- Common libraries provided by VersionFox (optional)
2 | local http = require("http")
3 | local json = require("json")
4 | local html = require("html")
5 |
6 | --- The following two parameters are injected by VersionFox at runtime
7 | --- Operating system type at runtime (Windows, Linux, Darwin)
8 | ------ Default global variable
9 | ----- OS_TYPE: windows, linux, darwin
10 | ----- ARCH_TYPE: 386, amd64, arm, arm64 ...
11 | OS_TYPE = ""
12 | --- Operating system architecture at runtime (amd64, arm64, etc.)
13 | ARCH_TYPE = ""
14 |
15 | PLUGIN = {
16 | --- Plugin name, only numbers, letters, and underscores are allowed
17 | name = "java",
18 | --- Plugin author
19 | author = "Lihan",
20 | --- Plugin version
21 | version = "0.0.1",
22 | --- Plugin description
23 | description = "xxx",
24 | -- Update URL
25 | updateUrl = "{URL}/sdk.lua",
26 | -- minimum compatible vfox version
27 | minRuntimeVersion = "0.2.2",
28 | }
29 |
30 | --- Returns some pre-installed information, such as version number, download address, local files, etc.
31 | --- If checksum is provided, vfox will automatically check it for you.
32 | --- @param ctx table
33 | --- @field ctx.version string User-input version
34 | --- @return table Version information
35 | function PLUGIN:PreInstall(ctx)
36 | local version = ctx.version
37 | local runtimeVersion = ctx.runtimeVersion
38 | return {
39 | --- Version number
40 | version = "xxx",
41 | --- remote URL or local file path [optional]
42 | url = "xxx",
43 | --- SHA256 checksum [optional]
44 | sha256 = "xxx",
45 | --- md5 checksum [optional]
46 | md5 = "xxx",
47 | --- sha1 checksum [optional]
48 | sha1 = "xxx",
49 | --- sha512 checksum [optional]
50 | sha512 = "xx",
51 | --- additional need files [optional]
52 | addition = {
53 | {
54 | --- additional file name !
55 | name = "xxx",
56 | --- remote URL or local file path [optional]
57 | url = "xxx",
58 | --- SHA256 checksum [optional]
59 | sha256 = "xxx",
60 | --- md5 checksum [optional]
61 | md5 = "xxx",
62 | --- sha1 checksum [optional]
63 | sha1 = "xxx",
64 | --- sha512 checksum [optional]
65 | sha512 = "xx",
66 | }
67 | }
68 | }
69 | end
70 |
71 | --- Extension point, called after PreInstall, can perform additional operations,
72 | --- such as file operations for the SDK installation directory or compile source code
73 | --- Currently can be left unimplemented!
74 | function PLUGIN:PostInstall(ctx)
75 | --- ctx.rootPath SDK installation directory
76 | local rootPath = ctx.rootPath
77 | local runtimeVersion = ctx.runtimeVersion
78 | local sdkInfo = ctx.sdkInfo['sdk-name']
79 | local path = sdkInfo.path
80 | local version = sdkInfo.version
81 | local name = sdkInfo.name
82 | end
83 |
84 | --- Return all available versions provided by this plugin
85 | --- @param ctx table Empty table used as context, for future extension
86 | --- @return table Descriptions of available versions and accompanying tool descriptions
87 | function PLUGIN:Available(ctx)
88 | local runtimeVersion = ctx.runtimeVersion
89 | return {
90 | {
91 | version = "xxxx",
92 | note = "LTS",
93 | addition = {
94 | {
95 | name = "npm",
96 | version = "8.8.8",
97 | }
98 | }
99 | }
100 | }
101 | end
102 |
103 | --- Each SDK may have different environment variable configurations.
104 | --- This allows plugins to define custom environment variables (including PATH settings)
105 | --- Note: Be sure to distinguish between environment variable settings for different platforms!
106 | --- @param ctx table Context information
107 | --- @field ctx.path string SDK installation directory
108 | function PLUGIN:EnvKeys(ctx)
109 | --- this variable is same as ctx.sdkInfo['plugin-name'].path
110 | local mainPath = ctx.path
111 | local runtimeVersion = ctx.runtimeVersion
112 | local mainSdkInfo = ctx.main
113 | local mpath = mainSdkInfo.path
114 | local mversion = mainSdkInfo.version
115 | local mname = mainSdkInfo.name
116 | local sdkInfo = ctx.sdkInfo['sdk-name']
117 | local path = sdkInfo.path
118 | local version = sdkInfo.version
119 | local name = sdkInfo.name
120 | return {
121 | {
122 | key = "JAVA_HOME",
123 | value = mainPath
124 | },
125 | {
126 | key = "PATH",
127 | value = mainPath .. "/bin"
128 | }
129 | }
130 | end
131 |
132 | --- When user invoke `use` command, this function will be called to get the
133 | --- valid version information.
134 | --- @param ctx table Context information
135 | function PLUGIN:PreUse(ctx)
136 | local runtimeVersion = ctx.runtimeVersion
137 | --- user input version
138 | local version = ctx.version
139 | --- user current used version
140 | local previousVersion = ctx.previousVersion
141 |
142 | --- installed sdks
143 | local sdkInfo = ctx.installedSdks['version']
144 | local path = sdkInfo.path
145 | local name = sdkInfo.name
146 | local version = sdkInfo.version
147 |
148 | --- working directory
149 | local cwd = ctx.cwd
150 |
151 | --- user input scope
152 | --- could be one of global/project/session
153 | local scope = ctx.scope
154 |
155 | --- return the version information
156 | return {
157 | version = version,
158 | }
159 | end
160 |
--------------------------------------------------------------------------------
/update-readme.sh:
--------------------------------------------------------------------------------
1 | readme_file="README.md"
2 | json_file="index.json"
3 | json=$(cat ${json_file})
4 |
5 | table_start="
\n\n| Name | \nVersion | \nAuthor | \nDescription | \n
"
6 | table_end="
"
7 |
8 | table_content=""
9 | for row in $(echo "${json}" | jq -r '.[] | @base64'); do
10 | _jq() {
11 | echo ${row} | base64 --decode | jq -r ${1}
12 | }
13 |
14 | category=$(_jq '.category')
15 | files=$(_jq '.files')
16 |
17 | for file in $(echo "${files}" | jq -r '.[] | @base64'); do
18 | _jq_file() {
19 | echo ${file} | base64 --decode | jq -r ${1}
20 | }
21 |
22 | name="${category}/$(_jq_file '.name')"
23 | version=$(_jq_file '.plugin_version')
24 | author=$(_jq_file '.plugin_author')
25 | desc=$(_jq_file '.plugin_desc')
26 |
27 | name="
${name}" # Make the name bold
28 | version="
${version}" # Change the font size
29 | author="
${author}" # Change the font size
30 | desc="
${desc}" # Change the font size
31 | desc=${desc//$'\n'/
} # Replace newline characters with
tags
32 |
33 | table_content="${table_content}\n
\n| ${name} | \n${version} | \n${author} | \n${desc} | \n
"
34 | done
35 | done
36 | echo "=======successfully generated table content========"
37 | echo "$table_content"
38 | # Insert the table into the README file
39 | sed -i "//,//c\\\n${table_start}${table_content}\n${table_end}\n" ${readme_file}
40 | echo "=======successfully updated README file========"
41 | cat ${readme_file}
--------------------------------------------------------------------------------
/zig/zig.lua:
--------------------------------------------------------------------------------
1 | --- Copyright 2024 [lihan aooohan@gmail.com]
2 | --
3 | -- Licensed under the Apache License, Version 2.0 (the "License");
4 | -- you may not use this file except in compliance with the License.
5 | -- You may obtain a copy of the License at
6 | --
7 | -- http://www.apache.org/licenses/LICENSE-2.0
8 | --
9 | -- Unless required by applicable law or agreed to in writing, software
10 | -- distributed under the License is distributed on an "AS IS" BASIS,
11 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | -- See the License for the specific language governing permissions and
13 | -- limitations under the License.
14 |
15 | local http = require("http")
16 | local json = require("json")
17 |
18 | OS_TYPE = ""
19 | ARCH_TYPE = ""
20 |
21 | BaseUrl = "https://ziglang.org/download/index.json"
22 | MachUrl = "https://machengine.org/zig/index.json"
23 |
24 | PLUGIN = {
25 | name = "zig",
26 | author = "aooohan",
27 | version = "0.0.5",
28 | description = "Zig",
29 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/zig/zig.lua",
30 | minRuntimeVersion = "0.3.0",
31 | manifestUrl = "https://github.com/version-fox/vfox-zig/releases/download/manifest/manifest.json"
32 | }
33 |
34 | function PLUGIN:PreInstall(ctx)
35 | local version = ctx.version
36 | local releases = self:Available({})
37 | for _, release in ipairs(releases) do
38 | if release.version == version then
39 | return release
40 | else
41 | for note in string.gmatch(release.note, "[^|]+") do
42 | if note == version then
43 | return release
44 | end
45 | end
46 | end
47 | end
48 | return {}
49 | end
50 |
51 | function compare_versions(v1o, v2o)
52 | local v1 = v1o.version
53 | local v2 = v2o.version
54 | local v1_parts = {}
55 | for part in string.gmatch(v1, "[^.+-]+") do
56 | table.insert(v1_parts, tonumber(part))
57 | end
58 |
59 | local v2_parts = {}
60 | for part in string.gmatch(v2, "[^.+-]+") do
61 | table.insert(v2_parts, tonumber(part))
62 | end
63 |
64 | for i = 1, math.max(#v1_parts, #v2_parts) do
65 | local v1_part = v1_parts[i] or 0
66 | local v2_part = v2_parts[i] or 0
67 | if v1_part > v2_part then
68 | return true
69 | elseif v1_part < v2_part then
70 | return false
71 | end
72 | end
73 |
74 | return false
75 | end
76 |
77 | function PLUGIN:Available(ctx)
78 | local archs = getArchArr()
79 | local os = getOsType()
80 | local base = getResults(BaseUrl, archs, os, "tarball")
81 | local mach = getResults(MachUrl, archs, os, "zigTarball")
82 |
83 | --merge the two together
84 | for k, v in pairs(mach) do
85 | if v.note == "nightly" then
86 | goto continue
87 | end
88 | if base[k] == nil then
89 | base[k] = v
90 | elseif base[k].note ~= "" then
91 | base[k].note = base[k].note .. "|" .. v.note
92 | end
93 | ::continue::
94 | end
95 |
96 | -- Need an list to sort it
97 | local result = {}
98 | for _, v in pairs(base) do
99 | table.insert(result, v)
100 | end
101 | table.sort(result, compare_versions)
102 |
103 | -- Get the first non-noted version to dictate latest
104 | for _, v in ipairs(result) do
105 | if v.note == "" then
106 | v.note = "latest"
107 | break
108 | end
109 | end
110 | return result
111 | end
112 |
113 | function getResults(url, archs, os, tar)
114 | local resp, err = http.get({
115 | url = url,
116 | })
117 | if err ~= nil or resp.status_code ~= 200 then
118 | error("get version failed" .. err)
119 | end
120 | local body = json.decode(resp.body)
121 | local result = {}
122 | for k, v in pairs(body) do
123 | local version = k
124 | local note = ""
125 | if v.version ~= nil then
126 | version = v.version
127 | if k == "master" then
128 | note = "nightly"
129 | else
130 | note = k
131 | end
132 | end
133 | for _, arch in ipairs(archs) do
134 | local key = arch .. "-" .. os
135 | if v[key] ~= nil then
136 | if result[version] ~= nil then
137 | result[version].note = result[version].note .. "|" .. note
138 | else
139 | result[version] = {
140 | version = version,
141 | url = v[key][tar],
142 | sha256 = v[key].shasum,
143 | note = note,
144 | }
145 | end
146 | end
147 | end
148 | end
149 | return result
150 | end
151 |
152 | function getOsType()
153 | if OS_TYPE == "darwin" then
154 | return "macos"
155 | end
156 | return OS_TYPE
157 | end
158 |
159 | function getArchArr()
160 | if ARCH_TYPE == "amd64" then
161 | return {
162 | "x86_64",
163 | }
164 | elseif ARCH_TYPE == "arm64" then
165 | return {
166 | "aarch64",
167 | }
168 | elseif ARCH_TYPE == "386" then
169 | return {
170 | "x86",
171 | "i386",
172 | }
173 | else
174 | return {
175 | ARCH_TYPE,
176 | }
177 | end
178 | end
179 |
180 | --- Expansion point
181 | function PLUGIN:PostInstall(ctx) end
182 |
183 | function PLUGIN:EnvKeys(ctx)
184 | local version_path = ctx.path
185 | return {
186 | {
187 | key = "PATH",
188 | value = version_path,
189 | },
190 | }
191 | end
192 |
--------------------------------------------------------------------------------