├── .github └── workflows │ └── index.yml ├── .idea ├── .gitignore ├── copyright │ ├── apache.xml │ └── profiles_settings.xml ├── modules.xml ├── vcs.xml └── version-fox-plugins.iml ├── LICENSE ├── README.md ├── dart └── dart.lua ├── deno └── deno.lua ├── dotnet └── dotnet.lua ├── flutter ├── flutter-cn.lua └── flutter.lua ├── generate-index.sh ├── golang └── golang.lua ├── gradle └── gradle.lua ├── java ├── adoptium-jdk.lua ├── azul-adoptium-jdk.lua ├── azul-jdk.lua ├── graalvm.lua ├── ibm-adoptium-jdk.lua ├── microsoft-adoptium-jdk.lua └── redhat-adoptium-jdk.lua ├── kotlin └── kotlin.lua ├── maven └── maven.lua ├── nodejs ├── nodejs.lua └── npmmirror.lua ├── python ├── npmmirror.lua └── python.lua ├── template.lua ├── update-readme.sh └── zig └── zig.lua /.github/workflows/index.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Deploy plugins index 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: write 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | jobs: 25 | # Single deploy job since we're just deploying 26 | deploy: 27 | environment: 28 | name: github-pages 29 | url: ${{ steps.deployment.outputs.page_url }} 30 | runs-on: ubuntu-latest 31 | steps: 32 | - name: Checkout 33 | uses: actions/checkout@v4 34 | - name: Setup Pages 35 | uses: actions/configure-pages@v4 36 | - name: Generate index page 37 | run: | 38 | chmod 777 ./generate-index.sh 39 | ./generate-index.sh 40 | ls index.json 41 | - name: Upload artifact 42 | uses: actions/upload-pages-artifact@v3 43 | with: 44 | # Upload entire repository 45 | path: '.' 46 | - name: Deploy to GitHub Pages 47 | id: deployment 48 | uses: actions/deploy-pages@v4 49 | 50 | - name: Install jq 51 | run: sudo apt-get install jq 52 | - name: Update readme 53 | run: | 54 | chmod 777 ./update-readme.sh 55 | ./update-readme.sh 56 | - name: Commit files 57 | run: | 58 | git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" 59 | git config --local user.name "github-actions[bot]" 60 | git commit -a -m "Update Available Plugins List" 61 | - name: Push changes 62 | uses: ad-m/github-push-action@master 63 | with: 64 | github_token: ${{ secrets.GITHUB_TOKEN }} 65 | branch: ${{ github.ref }} 66 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | # GitHub Copilot persisted chat sessions 10 | /copilot/chatSessions 11 | -------------------------------------------------------------------------------- /.idea/copyright/apache.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/version-fox-plugins.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2024 Han Li and contributors 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VersionFox Plugins 2 | 3 | ## ⚠️ This repo is not being maintained, please go to [new plugin repository](https://github.com/version-fox/vfox-plugins). 4 | 5 | ## Supported Plugins 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 |
NameVersionAuthorDescription
dart/dart0.0.2Aooohandart plugin, support for getting stable, dev, beta version
deno/deno0.0.2AooohanDeno plugin, https://deno.com/
dotnet/dotnet0.0.2Korbinian Haberederdotnet plugin, support for dotnet sdks 6.0, 7.0, 8.0
flutter/flutter-cn0.0.6Aooohanflutter plugin for China, support for getting stable, dev, beta version
flutter/flutter0.0.5Aooohanflutter plugin, support for getting stable, dev, beta version
golang/golang0.0.3Aooohan
gradle/gradle0.0.2ahaigradle
java/adoptium-jdk0.0.3aooohanAdoptium JDK
java/azul-adoptium-jdk0.0.6axdankAzul (Zulu) JDK - Adoptium
java/azul-jdk0.0.5yimiaoxiehouAzul JDK, also known as Zulu
java/graalvm0.0.7ahaigraalvm JDK
java/ibm-adoptium-jdk0.0.5axdankIBM JDK - Adoptium
java/microsoft-adoptium-jdk0.0.4axdankMicrosoft JDK - Adoptium
java/redhat-adoptium-jdk0.0.4axdankRedHat JDK - Adoptium
kotlin/kotlin0.0.31.9.0AooohanKotlin plugin
maven/maven0.0.3Aooohan
nodejs/nodejs0.0.8AooohanNode.js
nodejs/npmmirror0.0.6yimiaoxiehouinstall Node.js use https://cdn.npmmirror.com
python/npmmirror0.0.4aooohanvfox >= 0.2.3 !!! From npmmirror.org. For Windows, only support >=3.5.0, but no restrictions for unix-like
python/python0.0.4aooohanvfox >= 0.2.3 !! For Windows, only support >=3.5.0, but no restrictions for unix-like
zig/zig0.0.5aooohanZig
141 | 142 | -------------------------------------------------------------------------------- /dart/dart.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 | VersionURL = 22 | "https://storage.googleapis.com/storage/v1/b/dart-archive/o?delimiter=/&prefix=channels/%s/release/&alt=json" 23 | DownloadURL = "https://storage.googleapis.com/dart-archive/channels/%s/release/%s/sdk/dartsdk-%s-%s-release.zip" 24 | SHA256URL = "https://storage.googleapis.com/dart-archive/channels/%s/release/%s/sdk/dartsdk-%s-%s-release.zip.sha256sum" 25 | LatestVersionURL = "https://storage.googleapis.com/dart-archive/channels/%s/release/latest/VERSION" 26 | PLUGIN = { 27 | --- Plugin name 28 | name = "dart", 29 | --- Plugin author 30 | author = "Aooohan", 31 | --- Plugin version 32 | version = "0.0.2", 33 | description = "dart plugin, support for getting stable, dev, beta version", 34 | -- Update URL 35 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/dart/dart.lua", 36 | manifestUrl = "https://github.com/version-fox/vfox-dart/releases/download/manifest/manifest.json", 37 | minRuntimeVersion = "0.3.0", 38 | } 39 | 40 | function PLUGIN:PreInstall(ctx) 41 | local arg = ctx.version 42 | local type = getOsTypeAndArch() 43 | if arg == "stable" or arg == "dev" or arg == "beta" then 44 | local resp, err = http.get({ 45 | url = LatestVersionURL:format(arg) 46 | }) 47 | if err ~= nil or resp.status_code ~= 200 then 48 | error("get version failed" .. err) 49 | end 50 | local latestVersion = json.decode(resp.body) 51 | local version = latestVersion.version 52 | local sha256Url = SHA256URL:format(arg, version, type.osType, type.archType) 53 | local r = { 54 | version = version, 55 | url = DownloadURL:format(arg, version, type.osType, type.archType), 56 | sha256 = extractChecksum(sha256Url) 57 | } 58 | return r 59 | else 60 | local releases = self:Available({}) 61 | for _, info in ipairs(releases) do 62 | if info.version == arg then 63 | return { 64 | version = info.version, 65 | url = info.url, 66 | sha256 = extractChecksum(info.sha256) 67 | } 68 | end 69 | end 70 | end 71 | end 72 | 73 | function PLUGIN:PostInstall(ctx) 74 | end 75 | 76 | function PLUGIN:Available(ctx) 77 | local result = {} 78 | parseReleases("stable", result) 79 | parseReleases("dev", result) 80 | parseReleases("beta", result) 81 | table.sort(result, function(a, b) 82 | return a.version > b.version 83 | end) 84 | return result 85 | end 86 | 87 | function extractChecksum(url) 88 | local resp, err = http.get({ 89 | url = url 90 | }) 91 | if err ~= nil or resp.status_code ~= 200 then 92 | error("get checksum failed" .. err) 93 | end 94 | local checksum = resp.body:match("^(%w+)%s") 95 | return checksum 96 | end 97 | 98 | function parseReleases(devType, resultArr) 99 | local type = getOsTypeAndArch() 100 | local resp, err = http.get({ 101 | url = VersionURL:format(devType) 102 | }) 103 | if err ~= nil or resp.status_code ~= 200 then 104 | error("get version failed" .. err) 105 | end 106 | local body = json.decode(resp.body) 107 | for _, info in ipairs(body.prefixes) do 108 | local version = extractVersions(info) 109 | if version ~= nil then 110 | table.insert(resultArr, { 111 | version = version, 112 | url = DownloadURL:format(devType, version, type.osType, type.archType), 113 | sha256 = SHA256URL:format(devType, version, type.osType, type.archType), 114 | note = devType, 115 | }) 116 | end 117 | end 118 | end 119 | 120 | function extractVersions(str) 121 | local version = str:match(".*/(.-)/$") 122 | if version and not version:match("^%d+$") and version ~= "latest" then 123 | return version 124 | end 125 | return nil 126 | end 127 | 128 | function getOsTypeAndArch() 129 | local osType = OS_TYPE 130 | local archType = ARCH_TYPE 131 | if OS_TYPE == "darwin" then 132 | osType = "macos" 133 | end 134 | if ARCH_TYPE == "amd64" then 135 | archType = "x64" 136 | elseif ARCH_TYPE == "386" then 137 | archType = "ia32" 138 | else 139 | error("dart does not support" .. ARCH_TYPE .. "architecture") 140 | end 141 | return { 142 | osType = osType, archType = archType 143 | } 144 | end 145 | 146 | function PLUGIN:EnvKeys(ctx) 147 | local mainPath = ctx.path 148 | return { 149 | { 150 | key = "PATH", 151 | value = mainPath .. "/bin" 152 | } 153 | } 154 | end 155 | -------------------------------------------------------------------------------- /deno/deno.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 | 19 | OS_TYPE = "" 20 | ARCH_TYPE = "" 21 | 22 | ReleaseURL = "https://raw.githubusercontent.com/denoland/deno/main/Releases.md" 23 | 24 | DownloadURL = "https://github.com/denoland/deno/releases/download/v%s/%s" 25 | 26 | PLUGIN = { 27 | name = "deno", 28 | author = "Aooohan", 29 | version = "0.0.2", 30 | description = "Deno plugin, https://deno.com/", 31 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/deno/deno.lua", 32 | manifestUrl = "https://github.com/version-fox/vfox-deno/releases/download/manifest/manifest.json", 33 | minRuntimeVersion = "0.3.0", 34 | } 35 | 36 | function PLUGIN:PreInstall(ctx) 37 | local version = ctx.version 38 | 39 | local type = getOsTypeAndArch() 40 | if version == "latest" then 41 | local lists = self:Available({}) 42 | version = lists[1].version 43 | end 44 | local filename = "deno-" .. type.archType .. "-" .. type.osType .. ".zip" 45 | return { 46 | version = version, 47 | url = DownloadURL:format(version, filename), 48 | } 49 | 50 | end 51 | 52 | function getOsTypeAndArch() 53 | local osType = OS_TYPE 54 | local archType = ARCH_TYPE 55 | if OS_TYPE == "darwin" then 56 | osType = "apple-darwin" 57 | elseif OS_TYPE == "windows" then 58 | osType = "pc-windows-msvc" 59 | elseif OS_TYPE == "linux" then 60 | osType = "unknown-linux-gnu" 61 | else 62 | error("Deno does not support " .. OS_TYPE .. " os") 63 | end 64 | if ARCH_TYPE == "amd64" then 65 | archType = "x86_64" 66 | elseif ARCH_TYPE == "arm64" then 67 | archType = "aarch64" 68 | else 69 | error("Deno does not support " .. ARCH_TYPE .. " architecture") 70 | end 71 | return { 72 | osType = osType, archType = archType 73 | } 74 | end 75 | 76 | function PLUGIN:Available(ctx) 77 | local resp, err = http.get({ 78 | url = ReleaseURL 79 | }) 80 | if err ~= nil or resp.status_code ~= 200 then 81 | return {} 82 | end 83 | local result = {} 84 | for line in string.gmatch(resp.body, '([^\n]*)\n?') do 85 | if string.match(line, "^###") then 86 | local start = string.sub(line, 5) 87 | local version = string.sub(start, 1, -14) 88 | if string.sub(version, 1, 1) == "v" then 89 | version = string.sub(version, 2) 90 | end 91 | table.insert(result, { 92 | version = version, 93 | note = "" 94 | }) 95 | end 96 | end 97 | return result 98 | end 99 | 100 | --- Expansion point 101 | function PLUGIN:PostInstall(ctx) 102 | end 103 | 104 | function PLUGIN:EnvKeys(ctx) 105 | local version_path = ctx.path 106 | return { 107 | { 108 | key = "PATH", 109 | value = version_path 110 | }, 111 | } 112 | end 113 | -------------------------------------------------------------------------------- /dotnet/dotnet.lua: -------------------------------------------------------------------------------- 1 | --- Copyright 2024 [liquidiert haberederkorbinian@googlemail.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 | local html = require("html") 18 | 19 | OS_TYPE = "" 20 | ARCH_TYPE = "" 21 | 22 | BARE_URL = "https://dotnet.microsoft.com" 23 | VERSIONS_URL = "https://dotnet.microsoft.com/en-us/download/dotnet" 24 | 25 | PLUGIN = { 26 | --- Plugin name 27 | name = "dotnet", 28 | --- Plugin author 29 | author = "Korbinian Habereder", 30 | --- Plugin version 31 | version = "0.0.2", 32 | description = "dotnet plugin, support for dotnet sdks 6.0, 7.0, 8.0", 33 | -- Update URL 34 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/dotnet/dotnet.lua", 35 | manifestUrl = "https://github.com/version-fox/vfox-dotnet/releases/download/manifest/manifest.json", 36 | minRuntimeVersion = "0.3.0", 37 | } 38 | 39 | function PLUGIN:PreInstall(ctx) 40 | local releases = self:Available(ctx) 41 | for _, release in ipairs(releases) do 42 | if release.version == ctx.version then 43 | return release 44 | end 45 | end 46 | return {} 47 | end 48 | 49 | function PLUGIN:PostInstall(ctx) 50 | end 51 | 52 | function PLUGIN:Available(ctx) 53 | local result = {} 54 | local versions = {} 55 | local resp, err = http.get({ 56 | url = VERSIONS_URL 57 | }) 58 | if err ~= nil or resp.status_code ~= 200 then 59 | error("Getting releases failed: " .. err) 60 | end 61 | local type = getOsTypeAndArch() 62 | local doc = html.parse(resp.body) 63 | local tableDoc = doc:find("table") 64 | -- first find available sdk versions 65 | tableDoc:find("tbody"):first():find("tr"):each(function(ti, ts) 66 | local td = ts:find("td") 67 | local downloadLink = td:eq(0):find("a"):attr("href") 68 | local support = td:eq(1):text() 69 | local installableVersion = td:eq(3):text() 70 | local endOfLife = td:eq(5):text():gsub("\n", ""):gsub("%s+$", "") 71 | table.insert(versions, { 72 | version = installableVersion, 73 | url = BARE_URL .. downloadLink, 74 | note = "End of Support: " .. endOfLife, 75 | -- sha256 = nil, 76 | }) 77 | end) 78 | -- then find os and arch specific version 79 | for _, version in ipairs(versions) do 80 | local resp, err = http.get({ 81 | url = version.url 82 | }) 83 | if err ~= nil or resp.status_code ~= 200 then 84 | error("Getting specific versions failed: " .. err) 85 | end 86 | local downloadDoc = html.parse(resp.body) 87 | local tableDoc = downloadDoc:find("table"):first():find("tbody"):first() 88 | local osSpecifics = tableDoc:find("tr") 89 | 90 | local downloadUrl = "" 91 | 92 | if type.osType == "Linux" then 93 | local archVersions = osSpecifics:eq(0):find("td"):eq(1):find("a") 94 | if type.archType == "x64" then 95 | downloadUrl = archVersions:eq(4):attr("href") 96 | elseif type.archType == "Arm64" then 97 | downloadUrl = archVersions:eq(2):attr("href") 98 | elseif type.archType == "x86" then 99 | error("Can't provide dotnet for x86 architecture linux") 100 | end 101 | elseif type.osType == "macOS" then 102 | local archVersions = osSpecifics:eq(1):find("td"):eq(1):find("a") 103 | if type.archType == "x64" then 104 | downloadUrl = archVersions:eq(1):attr("href") 105 | elseif type.archType == "Arm64" then 106 | downloadUrl = archVersions:eq(0):attr("href") 107 | end 108 | elseif type.osType == "Windows" then 109 | local archVersions = osSpecifics:eq(2):find("td"):eq(1):find("a") 110 | if type.archType == "x64" then 111 | downloadUrl = archVersions:eq(1):attr("href") 112 | elseif type.archType == "Arm64" then 113 | downloadUrl = archVersions:eq(0):attr("href") 114 | elseif type.archType == "x86" then 115 | downloadUrl = archVersions:eq(2):attr("href") 116 | end 117 | end 118 | 119 | -- after getting download url parse direct download link and checksum 120 | local resp, err = http.get({ 121 | url = BARE_URL .. downloadUrl 122 | }) 123 | if err ~= nil or resp.status_code ~= 200 then 124 | error("Getting specific versions failed: " .. err) 125 | end 126 | 127 | local directLinkDoc = html.parse(resp.body) 128 | local directLink = directLinkDoc:find("a#directLink"):attr("href") 129 | local checksum = directLinkDoc:find("input#checksum"):attr("value") 130 | 131 | table.insert(result, { 132 | version = version.version, 133 | url = directLink, 134 | note = version.note, 135 | sha512 = checksum 136 | }) 137 | end 138 | return result 139 | end 140 | 141 | 142 | function getOsTypeAndArch() 143 | local osType = OS_TYPE 144 | local archType = ARCH_TYPE 145 | if OS_TYPE == "darwin" then 146 | osType = "macOS" 147 | elseif OS_TYPE == "linux" then 148 | osType = "Linux" 149 | elseif OS_TYPE == "windows" then 150 | osType = "Windows" 151 | end 152 | if ARCH_TYPE == "amd64" then 153 | archType = "x64" 154 | elseif ARCH_TYPE == "arm64" then 155 | archType = "Arm64" 156 | elseif ARCH_TYPE == "386" then 157 | archType = "x86" 158 | end 159 | return { 160 | osType = osType, archType = archType 161 | } 162 | end 163 | 164 | function PLUGIN:EnvKeys(ctx) 165 | local mainPath = ctx.path 166 | return { 167 | { 168 | key = "DOTNET_ROOT", 169 | value = mainPath 170 | }, 171 | { 172 | key = "PATH", 173 | value = mainPath 174 | } 175 | } 176 | end -------------------------------------------------------------------------------- /flutter/flutter-cn.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 | BASE_URL = "https://storage.flutter-io.cn/flutter_infra_release/releases/releases_%s.json" 22 | 23 | PLUGIN = { 24 | --- Plugin name 25 | name = "flutter", 26 | --- Plugin author 27 | author = "Aooohan", 28 | --- Plugin version 29 | version = "0.0.6", 30 | description = "flutter plugin for China, support for getting stable, dev, beta version", 31 | -- Update URL 32 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/flutter/flutter-cn.lua", 33 | manifestUrl = "https://github.com/version-fox/vfox-flutter/releases/download/manifest/manifest.json", 34 | minRuntimeVersion = "0.3.0", 35 | } 36 | 37 | function PLUGIN:PreInstall(ctx) 38 | local arg = ctx.version 39 | if arg == "beta" or arg == "dev" or arg == "stable" then 40 | local type = getOsTypeAndArch() 41 | local resp, err = http.get({ 42 | url = BASE_URL:format(type.osType) 43 | }) 44 | if err ~= nil or resp.status_code ~= 200 then 45 | error("get version failed" .. err) 46 | end 47 | local body = json.decode(resp.body) 48 | local cr = body.current_release 49 | local key = cr[arg] 50 | local releases = self:Available({}) 51 | for _, info in ipairs(releases) do 52 | if info.key == key then 53 | return { 54 | version = info.version, 55 | url = info.url, 56 | sha256 = info.sha256 57 | } 58 | end 59 | end 60 | end 61 | local releases = self:Available({}) 62 | for _, info in ipairs(releases) do 63 | if info.version == arg then 64 | return { 65 | version = info.version, 66 | url = info.url, 67 | sha256 = info.sha256 68 | } 69 | end 70 | end 71 | return nil 72 | end 73 | 74 | function PLUGIN:PostInstall(ctx) 75 | end 76 | 77 | function PLUGIN:Available(ctx) 78 | local type = getOsTypeAndArch() 79 | local resp, err = http.get({ 80 | url = BASE_URL:format(type.osType) 81 | }) 82 | if err ~= nil or resp.status_code ~= 200 then 83 | error("get version failed" .. err) 84 | end 85 | local body = json.decode(resp.body) 86 | local result = {} 87 | for _, info in ipairs(body.releases) do 88 | local version = info.version 89 | local oldVersion = string.sub(version, 1, 1) == "v" 90 | if oldVersion then 91 | break 92 | end 93 | table.insert(result, { 94 | version = info.version, 95 | url = body.base_url .. "/" .. info.archive, 96 | sha256 = info.sha256, 97 | key = info.hash, 98 | note = info.channel, 99 | addition = { 100 | { 101 | name = "dart", 102 | version = info.dart_sdk_version 103 | } 104 | } 105 | }) 106 | end 107 | return result 108 | end 109 | 110 | 111 | function getOsTypeAndArch() 112 | local osType = OS_TYPE 113 | local archType = ARCH_TYPE 114 | if OS_TYPE == "darwin" then 115 | osType = "macos" 116 | end 117 | if ARCH_TYPE == "amd64" then 118 | archType = "x64" 119 | elseif ARCH_TYPE == "arm64" then 120 | archType = "arm64" 121 | else 122 | error("flutter does not support" .. ARCH_TYPE .. "architecture") 123 | end 124 | return { 125 | osType = osType, archType = archType 126 | } 127 | end 128 | 129 | function PLUGIN:EnvKeys(ctx) 130 | local mainPath = ctx.path 131 | return { 132 | { 133 | key = "PATH", 134 | value = mainPath .. "/bin" 135 | } 136 | } 137 | end -------------------------------------------------------------------------------- /flutter/flutter.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 | BASE_URL = "https://storage.googleapis.com/flutter_infra_release/releases/releases_%s.json" 22 | 23 | PLUGIN = { 24 | --- Plugin name 25 | name = "flutter", 26 | --- Plugin author 27 | author = "Aooohan", 28 | --- Plugin version 29 | version = "0.0.5", 30 | description = "flutter plugin, support for getting stable, dev, beta version", 31 | -- Update URL 32 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/flutter/flutter.lua", 33 | manifestUrl = "https://github.com/version-fox/vfox-flutter/releases/download/manifest/manifest.json", 34 | minRuntimeVersion = "0.3.0", 35 | } 36 | 37 | function PLUGIN:PreInstall(ctx) 38 | local arg = ctx.version 39 | if arg == "beta" or arg == "dev" or arg == "stable" then 40 | local type = getOsTypeAndArch() 41 | local resp, err = http.get({ 42 | url = BASE_URL:format(type.osType) 43 | }) 44 | if err ~= nil or resp.status_code ~= 200 then 45 | error("get version failed" .. err) 46 | end 47 | local body = json.decode(resp.body) 48 | local cr = body.current_release 49 | local key = cr[arg] 50 | local releases = self:Available({}) 51 | for _, info in ipairs(releases) do 52 | if info.key == key then 53 | return { 54 | version = info.version, 55 | url = info.url, 56 | sha256 = info.sha256 57 | } 58 | end 59 | end 60 | end 61 | local releases = self:Available({}) 62 | for _, info in ipairs(releases) do 63 | if info.version == arg then 64 | return { 65 | version = info.version, 66 | url = info.url, 67 | sha256 = info.sha256 68 | } 69 | end 70 | end 71 | return nil 72 | end 73 | 74 | function PLUGIN:PostInstall(ctx) 75 | end 76 | 77 | function PLUGIN:Available(ctx) 78 | local type = getOsTypeAndArch() 79 | local resp, err = http.get({ 80 | url = BASE_URL:format(type.osType) 81 | }) 82 | if err ~= nil or resp.status_code ~= 200 then 83 | error("get version failed" .. err) 84 | end 85 | local body = json.decode(resp.body) 86 | local result = {} 87 | for _, info in ipairs(body.releases) do 88 | local version = info.version 89 | local oldVersion = string.sub(version, 1, 1) == "v" 90 | if oldVersion then 91 | break 92 | end 93 | table.insert(result, { 94 | version = info.version, 95 | url = body.base_url .. "/" .. info.archive, 96 | sha256 = info.sha256, 97 | key = info.hash, 98 | note = info.channel, 99 | addition = { 100 | { 101 | name = "dart", 102 | version = info.dart_sdk_version 103 | } 104 | } 105 | }) 106 | end 107 | return result 108 | end 109 | 110 | 111 | function getOsTypeAndArch() 112 | local osType = OS_TYPE 113 | local archType = ARCH_TYPE 114 | if OS_TYPE == "darwin" then 115 | osType = "macos" 116 | end 117 | if ARCH_TYPE == "amd64" then 118 | archType = "x64" 119 | elseif ARCH_TYPE == "arm64" then 120 | archType = "arm64" 121 | else 122 | error("flutter does not support" .. ARCH_TYPE .. "architecture") 123 | end 124 | return { 125 | osType = osType, archType = archType 126 | } 127 | end 128 | 129 | function PLUGIN:EnvKeys(ctx) 130 | local mainPath = ctx.path 131 | return { 132 | { 133 | key = "PATH", 134 | value = mainPath .. "/bin" 135 | } 136 | } 137 | end -------------------------------------------------------------------------------- /generate-index.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | base_url="https://version-fox.github.io/version-fox-plugins" 4 | 5 | echo "[" > index.json 6 | 7 | generate_list() { 8 | for dir in "$1"/*; do 9 | if [ -d "$dir" ]; then 10 | echo "{" >> index.json 11 | echo "\"category\": \"$(basename "$dir")\"," >> index.json 12 | count=$(find "$dir" -type f -name "*.lua" | wc -l) 13 | echo "\"count\": \"$count\"," >> index.json 14 | echo "\"files\": [" >> index.json 15 | for file in "$dir"/*.lua; do 16 | if [ -f "$file" ]; then 17 | filename=$(basename "$file" .lua) 18 | sha256=$(sha256sum "$file" | awk '{ print $1 }') 19 | plugin_name=$(perl -ne 'if(/name\s*=\s*"([^"]*)"/){print $1;}' $file) 20 | plugin_author=$(perl -ne 'if(/author\s*=\s*"([^"]*)"/){print $1;}' $file) 21 | plugin_version=$(perl -ne 'if(/version\s*=\s*"([^"]*)"/){print $1;}' $file) 22 | plugin_desc=$(perl -ne 'if(/description\s*=\s*"([^"]*)"/){print $1;}' $file) 23 | url="$base_url/$(basename "$dir")/$filename.lua" 24 | echo "{" >> index.json 25 | echo "\"name\": \"$filename\"," >> index.json 26 | echo "\"url\": \"$url\"," >> index.json 27 | echo "\"sha256\": \"$sha256\"," >> index.json 28 | echo "\"plugin_name\": \"$plugin_name\"," >> index.json 29 | echo "\"plugin_author\": \"$plugin_author\"," >> index.json 30 | echo "\"plugin_version\": \"$plugin_version\"," >> index.json 31 | echo "\"plugin_desc\": \"$plugin_desc\"" >> index.json 32 | echo "}," >> index.json 33 | fi 34 | done 35 | # Remove the last comma 36 | sed -i '$ s/,$//' index.json 37 | echo "]" >> index.json 38 | echo "}," >> index.json 39 | fi 40 | done 41 | } 42 | 43 | generate_list . 44 | 45 | # Remove the last comma 46 | sed -i '$ s/,$//' index.json 47 | 48 | echo "]" >> index.json -------------------------------------------------------------------------------- /golang/golang.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 | local json = require("json") 18 | 19 | OS_TYPE = "" 20 | ARCH_TYPE = "" 21 | 22 | GOLANG_URL = "https://go.dev/dl/" 23 | 24 | PLUGIN = { 25 | --- Plugin name 26 | name = "golang", 27 | --- Plugin author 28 | author = "Aooohan", 29 | --- Plugin version 30 | version = "0.0.3", 31 | -- Update URL 32 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/golang/golang.lua", 33 | minRuntimeVersion = "0.3.0", 34 | manifestUrl = "https://github.com/version-fox/vfox-golang/releases/download/manifest/manifest.json" 35 | } 36 | 37 | function PLUGIN:PreInstall(ctx) 38 | local version = ctx.version 39 | local releases = getReleases() 40 | if version == "latest" then 41 | return releases[1] 42 | end 43 | for _, release in ipairs(releases) do 44 | if release.version == version then 45 | return release 46 | end 47 | end 48 | return {} 49 | end 50 | 51 | function PLUGIN:PostInstall(ctx) 52 | end 53 | 54 | function PLUGIN:Available(ctx) 55 | return getReleases() 56 | end 57 | 58 | function getReleases() 59 | local result = {} 60 | local resp, err = http.get({ 61 | url = GOLANG_URL .. "?mode=json" 62 | }) 63 | if err ~= nil or resp.status_code ~= 200 then 64 | error("paring release info failed." .. err) 65 | end 66 | local body = json.decode(resp.body) 67 | for _, info in ipairs(body) do 68 | local v = string.sub(info.version, 3) 69 | for _, file in ipairs(info.files) do 70 | if file.kind == "archive" and file.os == OS_TYPE and file.arch == ARCH_TYPE then 71 | table.insert(result, { 72 | version = v, 73 | url = GOLANG_URL .. file.filename, 74 | note = "stable", 75 | sha256 = file.sha256, 76 | }) 77 | end 78 | end 79 | end 80 | resp, err = http.get({ 81 | url = GOLANG_URL 82 | }) 83 | if err ~= nil or resp.status_code ~= 200 then 84 | error("paring release info failed." .. err) 85 | end 86 | local type = getOsTypeAndArch() 87 | local doc = html.parse(resp.body) 88 | local listDoc = doc:find("div#archive") 89 | listDoc:find(".toggle"):each(function(i, selection) 90 | local versionStr = selection:attr("id") 91 | if versionStr ~= nil then 92 | selection:find("table.downloadtable tbody tr"):each(function(ti, ts) 93 | local td = ts:find("td") 94 | local filename = td:eq(0):text() 95 | local kind = td:eq(1):text() 96 | local os = td:eq(2):text() 97 | local arch = td:eq(3):text() 98 | local checksum = td:eq(5):text() 99 | if kind == "Archive" and os == type.osType and arch == type.archType then 100 | table.insert(result, { 101 | version = string.sub(versionStr, 3), 102 | url = GOLANG_URL .. filename, 103 | note = "", 104 | sha256 = checksum, 105 | }) 106 | end 107 | end) 108 | end 109 | end) 110 | return result 111 | end 112 | 113 | function getOsTypeAndArch() 114 | local osType = OS_TYPE 115 | local archType = ARCH_TYPE 116 | if OS_TYPE == "darwin" then 117 | osType = "macOS" 118 | elseif OS_TYPE == "linux" then 119 | osType = "Linux" 120 | elseif OS_TYPE == "windows" then 121 | osType = "Windows" 122 | end 123 | if ARCH_TYPE == "amd64" then 124 | archType = "x86-64" 125 | elseif ARCH_TYPE == "arm64" then 126 | archType = "ARM64" 127 | elseif ARCH_TYPE == "386" then 128 | archType = "x86" 129 | end 130 | return { 131 | osType = osType, archType = archType 132 | } 133 | end 134 | 135 | function PLUGIN:EnvKeys(ctx) 136 | local mainPath = ctx.path 137 | return { 138 | { 139 | key = "PATH", 140 | value = mainPath .. "/bin" 141 | } 142 | } 143 | end -------------------------------------------------------------------------------- /gradle/gradle.lua: -------------------------------------------------------------------------------- 1 | 2 | --- Common libraries provided by VersionFox (optional) 3 | local http = require("http") 4 | 5 | --- The following two parameters are injected by VersionFox at runtime 6 | --- Operating system type at runtime (Windows, Linux, Darwin) 7 | OS_TYPE = "" 8 | --- Operating system architecture at runtime (amd64, arm64, etc.) 9 | ARCH_TYPE = "" 10 | 11 | PLUGIN = { 12 | --- Plugin name 13 | name = "gradle", 14 | --- Plugin author 15 | author = "ahai", 16 | --- Plugin version 17 | version = "0.0.2", 18 | --- Plugin description 19 | description = "gradle", 20 | -- Update URL 21 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/gradle/gradle.lua", 22 | manifestUrl = "https://github.com/version-fox/vfox-gradle/releases/download/manifest/manifest.json", 23 | -- minimum compatible vfox version 24 | minRuntimeVersion = "0.3.0", 25 | } 26 | 27 | AvailableVersionsUrl = "https://gradle.org/releases/" 28 | DownloadInfoUrl = "https://services.gradle.org/distributions/gradle-%s-bin.zip" 29 | 30 | 31 | function PLUGIN:PreInstall(ctx) 32 | local version = ctx.version 33 | local downloadUrl = DownloadInfoUrl:format(version) 34 | 35 | local resp, err = http.get({ 36 | url = downloadUrl..".sha256" 37 | }) 38 | if err ~= nil then 39 | error(err) 40 | end 41 | 42 | if resp.status_code ~= 200 then 43 | return nil 44 | end 45 | 46 | local sha256 = resp.body 47 | 48 | return { 49 | version = version, 50 | sha256 = sha256, 51 | url = downloadUrl, 52 | } 53 | end 54 | 55 | function PLUGIN:PostInstall(ctx) 56 | 57 | end 58 | 59 | function compare_versions(v1o, v2o) 60 | local v1 = v1o.version 61 | local v2 = v2o.version 62 | local v1_parts = {} 63 | for part in string.gmatch(v1, "[^.]+") do 64 | table.insert(v1_parts, tonumber(part)) 65 | end 66 | 67 | local v2_parts = {} 68 | for part in string.gmatch(v2, "[^.]+") do 69 | table.insert(v2_parts, tonumber(part)) 70 | end 71 | 72 | for i = 1, math.max(#v1_parts, #v2_parts) do 73 | local v1_part = v1_parts[i] or 0 74 | local v2_part = v2_parts[i] or 0 75 | if v1_part > v2_part then 76 | return true 77 | elseif v1_part < v2_part then 78 | return false 79 | end 80 | end 81 | 82 | return false 83 | end 84 | 85 | 86 | function PLUGIN:Available(ctx) 87 | local resp, err = http.get({ 88 | url = AvailableVersionsUrl 89 | }) 90 | if err ~= nil or resp.status_code ~= 200 then 91 | error('get release info failed.') 92 | end 93 | local htmlBody = resp.body 94 | local htmlContent= [[]] .. htmlBody .. [[]] 95 | 96 | local result = {} 97 | 98 | for version in htmlContent:gmatch('') do 99 | table.insert(result, {version=version,note=""}) 100 | end 101 | table.sort(result, compare_versions) 102 | 103 | return result 104 | end 105 | 106 | 107 | function PLUGIN:EnvKeys(ctx) 108 | local path = ctx.path 109 | return { 110 | { 111 | key = "GRADLE_HOME", 112 | value = path 113 | }, 114 | { 115 | key = "PATH", 116 | value = path .. "/bin" 117 | } 118 | } 119 | end 120 | -------------------------------------------------------------------------------- /java/adoptium-jdk.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 | SearchUrl = "https://api.adoptium.net/v3/assets/latest/%s/hotspot?os=%s&architecture=%s" 22 | AvailableVersionsUrl = "https://api.adoptium.net/v3/info/available_releases" 23 | DownloadInfoUrl = "https://api.adoptium.net/v3/assets/feature_releases/%s/ga?architecture=%s&heap_size=normal&image_type=jdk&jvm_impl=hotspot&os=%s&page=0&page_size=1&project=jdk&sort_method=DEFAULT&sort_order=DESC&vendor=eclipse" 24 | 25 | PLUGIN = { 26 | name = "java", 27 | author = "aooohan", 28 | version = "0.0.3", 29 | description = "Adoptium JDK", 30 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/java/adoptium-jdk.lua", 31 | minRuntimeVersion = "0.3.0", 32 | manifestUrl = "https://github.com/version-fox/vfox-java/releases/download/manifest/manifest.json" 33 | } 34 | 35 | function PLUGIN:PreInstall(ctx) 36 | local version = ctx.version 37 | if tonumber(version) == nil then 38 | error("invalid version: " .. ctx.version) 39 | end 40 | 41 | local type = getOsTypeAndArch() 42 | 43 | local resp, err = http.get({ 44 | url = DownloadInfoUrl:format(version, type.archType, type.osType) 45 | }) 46 | if err ~= nil then 47 | error(err) 48 | end 49 | if resp.status_code ~= 200 then 50 | return nil 51 | end 52 | 53 | local body = json.decode(resp.body) 54 | local downloadInfo = body[1] 55 | local binaryInfo = downloadInfo.binaries[1] 56 | 57 | return { 58 | version = version, 59 | url = binaryInfo.package.link, 60 | sha256 = binaryInfo.package.checksum, 61 | } 62 | 63 | end 64 | 65 | function getOsTypeAndArch() 66 | local osType = OS_TYPE 67 | local archType = ARCH_TYPE 68 | if OS_TYPE == "darwin" then 69 | osType = "mac" 70 | end 71 | if ARCH_TYPE == "amd64" then 72 | archType = "x64" 73 | elseif ARCH_TYPE == "arm64" then 74 | archType = "aarch64" 75 | elseif ARCH_TYPE == "386" then 76 | archType = "x32" 77 | end 78 | return { 79 | osType = osType, archType = archType 80 | } 81 | end 82 | 83 | function PLUGIN:Available(ctx) 84 | local resp, err = http.get({ 85 | url = AvailableVersionsUrl 86 | }) 87 | if err ~= nil or resp.status_code ~= 200 then 88 | return {} 89 | end 90 | local body = json.decode(resp.body) 91 | local ltsMap = {} 92 | for _, v in ipairs(body.available_lts_releases) do 93 | ltsMap[v] = v 94 | end 95 | local result = {} 96 | for _, v in ipairs(body.available_releases) do 97 | local note = "" 98 | if ltsMap[v] ~= nil then 99 | note = "LTS" 100 | end 101 | table.insert(result, { 102 | version = v .. '', 103 | note = note, 104 | }) 105 | end 106 | return result 107 | end 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 = "JAVA_HOME", 117 | value = path 118 | }, 119 | { 120 | key = "PATH", 121 | value = path .. "/bin" 122 | } 123 | } 124 | end 125 | -------------------------------------------------------------------------------- /java/azul-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/azul" 22 | DownloadLatestUrl = "https://marketplace-api.adoptium.net/v1/assets/latest/azul/%s/hotspot" 23 | 24 | PLUGIN = { 25 | name = "java", 26 | author = "axdank", 27 | version = "0.0.6", 28 | description = "Azul (Zulu) JDK - Adoptium", 29 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/java/azul-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, 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 | return { 131 | { 132 | key = "JAVA_HOME", 133 | value = path 134 | }, 135 | { 136 | key = "PATH", 137 | value = path .. "/bin" 138 | } 139 | } 140 | end 141 | -------------------------------------------------------------------------------- /java/azul-jdk.lua: -------------------------------------------------------------------------------- 1 | --- Copyright 2024 [yimiao yimiaoxiehou@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 | -- api from azul swagger https://api.azul.com/metadata/v1/docs/swagger 22 | AzulMetadataUrl = "https://api.azul.com/metadata/v1/zulu/packages/?release_status=ga&availability_types=CA&certifications=tck&page=1&page_size=1000&java_package_type=jdk&archive_type=%s&latest=true&os=%s&arch=%s" 23 | AzulBinaryInfo = "https://api.azul.com/metadata/v1/zulu/packages/%s" 24 | 25 | PLUGIN = { 26 | name = "java", 27 | author = "yimiaoxiehou", 28 | version = "0.0.5", 29 | description = "Azul JDK, also known as Zulu", 30 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/java/azul-jdk.lua", 31 | minRuntimeVersion = "0.3.0", 32 | manifestUrl = "https://github.com/version-fox/vfox-java/releases/download/manifest/manifest.json" 33 | } 34 | 35 | function PLUGIN:PreInstall(ctx) 36 | local version = ctx.version 37 | if tonumber(version) == nil then 38 | error("invalid version: " .. ctx.version) 39 | end 40 | 41 | local type = getOsTypeAndArch() 42 | local archive_type = "tar.gz" 43 | if OS_TYPE == "windows" then 44 | archive_type = "zip" 45 | end 46 | local url = AzulMetadataUrl:format(archive_type, type.osType, type.archType) 47 | url = url.."&java_version="..version 48 | local resp, err = http.get({ 49 | url = url 50 | }) 51 | if err ~= nil then 52 | error(err) 53 | end 54 | if resp.status_code ~= 200 then 55 | return nil 56 | end 57 | local body = json.decode(resp.body) 58 | local result = { 59 | version = version, 60 | url = body[1].download_url, 61 | } 62 | 63 | resp, err = http.get({ 64 | url = AzulBinaryInfo:format(body[1].package_uuid) 65 | }) 66 | if err ~= nil then 67 | error(err) 68 | end 69 | if resp.status_code ~= 200 then 70 | return nil 71 | end 72 | local body = json.decode(resp.body) 73 | result.sha256 = body.sha256_hash 74 | return result 75 | end 76 | 77 | function getOsTypeAndArch() 78 | local osType = OS_TYPE 79 | local archType = ARCH_TYPE 80 | if OS_TYPE == "darwin" then 81 | osType = "macosx" 82 | end 83 | if ARCH_TYPE == "amd64" then 84 | archType = "x64" 85 | elseif ARCH_TYPE == "arm64" then 86 | archType = "aarch64" 87 | elseif ARCH_TYPE == "386" then 88 | archType = "i686" 89 | end 90 | return { 91 | osType = osType, archType = archType 92 | } 93 | end 94 | 95 | function PLUGIN:Available(ctx) 96 | local archive_type = "tar.gz" 97 | if OS_TYPE == "windows" then 98 | archive_type = "zip" 99 | end 100 | local type = getOsTypeAndArch() 101 | -- get lts version 102 | local url = AzulMetadataUrl:format(archive_type, type.osType, type.archType) 103 | url = url.."&support_term=lts" 104 | local resp, err = http.get({ 105 | url = url 106 | }) 107 | if err ~= nil or resp.status_code ~= 200 then 108 | return {} 109 | end 110 | local body = json.decode(resp.body) 111 | local ltsVersions = {} 112 | for _, v in ipairs(body) do 113 | table.insert(ltsVersions, v.java_version[1]) 114 | end 115 | ltsVersions = removeDuplicates(ltsVersions) 116 | 117 | -- all version 118 | local result = {} 119 | local versions = {} 120 | resp, err = http.get({ 121 | url = AzulMetadataUrl:format(archive_type, type.osType, type.archType) 122 | }) 123 | if err ~= nil or resp.status_code ~= 200 then 124 | return {} 125 | end 126 | body = json.decode(resp.body) 127 | for _, v in ipairs(body) do 128 | table.insert(versions, v.java_version[1]) 129 | end 130 | 131 | versions = removeDuplicates(versions) 132 | for _, v in ipairs(versions) do 133 | if hasElement(ltsVersions, v) then 134 | table.insert(result, { 135 | version = v .. '', 136 | note = "LTS", 137 | }) 138 | else 139 | table.insert(result, { 140 | version = v .. '', 141 | note = "", 142 | }) 143 | end 144 | end 145 | return result 146 | end 147 | 148 | function PLUGIN:EnvKeys(ctx) 149 | local path = ctx.path 150 | return { 151 | { 152 | key = "JAVA_HOME", 153 | value = path 154 | }, 155 | { 156 | key = "PATH", 157 | value = path .. "/bin" 158 | } 159 | } 160 | end 161 | 162 | function removeDuplicates(arr) 163 | local hash = {} 164 | local result = {} 165 | for _, value in ipairs(arr) do 166 | if not hash[value] then 167 | hash[value] = true 168 | table.insert(result, value) 169 | end 170 | end 171 | return result 172 | end 173 | 174 | 175 | function hasElement(array, element) 176 | for _, value in ipairs(array) do 177 | if value == element then 178 | return true 179 | end 180 | end 181 | return false 182 | end 183 | -------------------------------------------------------------------------------- /java/graalvm.lua: -------------------------------------------------------------------------------- 1 | 2 | --- Common libraries provided by VersionFox (optional) 3 | local http = require("http") 4 | 5 | --- The following two parameters are injected by VersionFox at runtime 6 | --- Operating system type at runtime (Windows, Linux, Darwin) 7 | OS_TYPE = "" 8 | --- Operating system architecture at runtime (amd64, arm64, etc.) 9 | ARCH_TYPE = "" 10 | 11 | AvailableVersionsUrl = "https://www.graalvm.org/downloads/" 12 | DownloadInfoUrl = "https://download.oracle.com/graalvm/%s/latest/graalvm-jdk-%s_%s-%s_bin.%s" 13 | 14 | PLUGIN = { 15 | --- Plugin name 16 | name = "java", 17 | --- Plugin author 18 | author = "ahai", 19 | --- Plugin version 20 | version = "0.0.7", 21 | --- Plugin description 22 | description = "graalvm JDK", 23 | -- Update URL 24 | --updateUrl = "https://raw.githubusercontent.com/version-fox/version-fox-plugins/main/java/graalvm.lua", 25 | manifestUrl = "https://github.com/version-fox/vfox-java/releases/download/manifest/manifest.json", 26 | minRuntimeVersion = "0.3.0", 27 | } 28 | 29 | 30 | function PLUGIN:PreInstall(ctx) 31 | local version = ctx.version 32 | local type = getOsTypeAndArch() 33 | local downloadUrl = DownloadInfoUrl:format(version, version,type.osType,type.archType, type.suffixType) 34 | 35 | local resp, err = http.get({ 36 | url = downloadUrl..".sha256" 37 | }) 38 | if err ~= nil then 39 | error(err) 40 | end 41 | 42 | if resp.status_code ~= 200 then 43 | return nil 44 | end 45 | 46 | local sha256 = resp.body 47 | 48 | return { 49 | version = version, 50 | sha256 = sha256, 51 | url = downloadUrl, 52 | } 53 | end 54 | 55 | function getOsTypeAndArch() 56 | local osType = OS_TYPE 57 | local archType = ARCH_TYPE 58 | local suffixType = "tar.gz" 59 | if OS_TYPE == "darwin" then 60 | osType = "macos" 61 | end 62 | 63 | if OS_TYPE == "windows" then 64 | suffixType = "zip" 65 | end 66 | 67 | if ARCH_TYPE == "amd64" then 68 | archType = "x64" 69 | elseif ARCH_TYPE == "arm64" then 70 | archType = "aarch64" 71 | elseif ARCH_TYPE == "386" then 72 | error("win32 is not supported at this time ") 73 | end 74 | return { 75 | osType = osType, archType = archType,suffixType = suffixType 76 | } 77 | end 78 | 79 | function PLUGIN:PostInstall(ctx) 80 | 81 | end 82 | 83 | 84 | function PLUGIN:Available(ctx) 85 | --- get htmlBody 86 | local resp, err = http.get({ 87 | url = AvailableVersionsUrl 88 | }) 89 | if err ~= nil or resp.status_code ~= 200 then 90 | return {} 91 | end 92 | local htmlBody = resp.body 93 | --- get version 94 | local htmlContent= [[]] .. htmlBody .. [[]] 95 | 96 | local result = {} 97 | for match in htmlContent:gmatch('(.-)') 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\n\n\n\n" 6 | table_end="
NameVersionAuthorDescription
" 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 | --------------------------------------------------------------------------------