Skip to content

Commit 7bf289b

Browse files
committed
migrate old python plugin
1 parent bb91a0b commit 7bf289b

8 files changed

Lines changed: 203 additions & 145 deletions

File tree

hooks/available.lua

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,4 @@
1-
local util = require("util")
2-
3-
--- Return all available versions provided by this plugin
4-
--- @param ctx table Empty table used as context, for future extension
5-
--- @return table Descriptions of available versions and accompanying tool descriptions
1+
require("util")
62
function PLUGIN:Available(ctx)
7-
util:DoSomeThing()
8-
return {
9-
{
10-
version = "xxxx",
11-
note = "LTS",
12-
addition = {
13-
{
14-
name = "npm",
15-
version = "8.8.8",
16-
}
17-
}
18-
}
19-
}
3+
return parseVersion()
204
end

hooks/env_keys.lua

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,23 @@
1-
--- Each SDK may have different environment variable configurations.
2-
--- This allows plugins to define custom environment variables (including PATH settings)
3-
--- Note: Be sure to distinguish between environment variable settings for different platforms!
4-
--- @param ctx table Context information
5-
--- @field ctx.path string SDK installation directory
1+
require("util")
62
function PLUGIN:EnvKeys(ctx)
7-
--- this variable is same as ctx.sdkInfo['plugin-name'].path
83
local mainPath = ctx.path
9-
local mainSdkInfo = ctx.main
10-
local mpath = mainSdkInfo.path
11-
local mversion = mainSdkInfo.version
12-
local mname = mainSdkInfo.name
13-
local sdkInfo = ctx.sdkInfo['sdk-name']
14-
local path = sdkInfo.path
15-
local version = sdkInfo.version
16-
local name = sdkInfo.name
17-
return {
18-
{
19-
key = "JAVA_HOME",
20-
value = mainPath
21-
},
22-
{
23-
key = "PATH",
24-
value = mainPath .. "/bin"
25-
},
26-
{
27-
key = "PATH",
28-
value = mainPath .. "/bin2"
29-
},
30-
31-
}
32-
4+
if RUNTIME.osType == "windows" then
5+
return {
6+
{
7+
key = "PATH",
8+
value = mainPath,
9+
},
10+
{
11+
key = "PATH",
12+
value = mainPath .. "\\Scripts"
13+
}
14+
}
15+
else
16+
return {
17+
{
18+
key = "PATH",
19+
value = mainPath .. "/bin"
20+
}
21+
}
22+
end
3323
end

hooks/post_install.lua

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
--- Extension point, called after PreInstall, can perform additional operations,
2-
--- such as file operations for the SDK installation directory or compile source code
3-
--- Currently can be left unimplemented!
1+
require("util")
42
function PLUGIN:PostInstall(ctx)
5-
--- ctx.rootPath SDK installation directory
6-
local rootPath = ctx.rootPath
7-
local sdkInfo = ctx.sdkInfo['sdk-name']
8-
local path = sdkInfo.path
9-
local version = sdkInfo.version
10-
local name = sdkInfo.name
11-
local note = sdkInfo.note
3+
if OS_TYPE == "windows" then
4+
return windowsCompile(ctx)
5+
else
6+
return linuxCompile(ctx)
7+
end
128
end

hooks/pre_install.lua

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,23 @@
1-
--- Returns some pre-installed information, such as version number, download address, local files, etc.
2-
--- If checksum is provided, vfox will automatically check it for you.
3-
--- @param ctx table
4-
--- @field ctx.version string User-input version
5-
--- @return table Version information
1+
require("util")
62
function PLUGIN:PreInstall(ctx)
73
local version = ctx.version
8-
return {
9-
--- Version number
10-
version = "xxx",
11-
--- remote URL or local file path [optional]
12-
url = "xxx",
13-
--- SHA256 checksum [optional]
14-
sha256 = "xxx",
15-
--- md5 checksum [optional]
16-
md5 = "xxx",
17-
--- sha1 checksum [optional]
18-
sha1 = "xxx",
19-
--- sha512 checksum [optional]
20-
sha512 = "xx",
21-
--- additional need files [optional]
22-
addition = {
23-
{
24-
--- additional file name !
25-
name = "xxx",
26-
--- remote URL or local file path [optional]
27-
url = "xxx",
28-
--- SHA256 checksum [optional]
29-
sha256 = "xxx",
30-
--- md5 checksum [optional]
31-
md5 = "xxx",
32-
--- sha1 checksum [optional]
33-
sha1 = "xxx",
34-
--- sha512 checksum [optional]
35-
sha512 = "xx",
36-
}
4+
if version == "latest" then
5+
version = self:Available({})[1].version
6+
end
7+
if not checkIsReleaseVersion(version) then
8+
error("The current version is not released")
9+
return
10+
end
11+
if OS_TYPE == "windows" then
12+
local url, filename = checkAvailableReleaseForWindows(version)
13+
return {
14+
version = version,
15+
url = url,
16+
note = filename
3717
}
38-
}
18+
else
19+
return {
20+
version = version,
21+
}
22+
end
3923
end

hooks/pre_use.lua

Lines changed: 0 additions & 27 deletions
This file was deleted.

lib/uilt.lua

Lines changed: 0 additions & 8 deletions
This file was deleted.

lib/util.lua

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
local http = require("http")
2+
local html = require("html")
3+
4+
local PYTHON_URL = "https://www.python.org/ftp/python/"
5+
6+
local DOWNLOAD_SOURCE = {
7+
--- TODO support zip or web-based installers
8+
WEB_BASED = "https://www.python.org/ftp/python/%s/python-%s%s-webinstall.exe",
9+
ZIP = "https://www.python.org/ftp/python/%s/python-%s-embed-%s.zip",
10+
MSI = "",
11+
--- Currently only exe installers are supported
12+
EXE = "https://www.python.org/ftp/python/%s/python-%s%s.exe",
13+
SOURCE = "https://www.python.org/ftp/python/%s/Python-%s.tar.xz"
14+
}
15+
16+
function getMirror()
17+
local mirror = os.getenv("VFOX_PYTHON_MIRROR")
18+
if mirror == nil then
19+
return "https://www.python.org/ftp/python/"
20+
end
21+
return mirror
22+
end
23+
24+
function checkIsReleaseVersion(version)
25+
local resp, err = http.head({
26+
url = DOWNLOAD_SOURCE.SOURCE:format(version, version)
27+
})
28+
if err ~= nil or resp.status_code ~= 200 then
29+
return false
30+
end
31+
return true
32+
end
33+
function windowsCompile(ctx)
34+
local sdkInfo = ctx.sdkInfo['python']
35+
local path = sdkInfo.path
36+
local filename = sdkInfo.note
37+
--- Attention system difference
38+
local qInstallFile = path .. "\\" .. filename
39+
local qInstallPath = path
40+
--local exitCode = os.execute('msiexec /quiet /a "' .. qInstallFile .. '" TargetDir="' .. qInstallPath .. '"')
41+
print("Installing python, please wait patiently for a while, about two minutes.")
42+
local exitCode = os.execute(qInstallFile .. ' /quiet InstallAllUsers=0 PrependPath=0 TargetDir=' .. qInstallPath)
43+
if exitCode ~= 0 then
44+
error("error installing python")
45+
end
46+
print("Cleaning up ...")
47+
os.remove(qInstallFile)
48+
end
49+
function linuxCompile(ctx)
50+
local sdkInfo = ctx.sdkInfo['python']
51+
local path = sdkInfo.path
52+
local version = sdkInfo.version
53+
local pyenv_url = "https://github.com/pyenv/pyenv.git"
54+
local dest_pyenv_path = ctx.rootPath .. "/pyenv"
55+
local status = os.execute("git clone " .. pyenv_url .. " " .. dest_pyenv_path)
56+
if status ~= 0 then
57+
error("git clone failed")
58+
end
59+
local pyenv_build_path = dest_pyenv_path .. "/plugins/python-build/bin/python-build"
60+
print("Building python ...")
61+
status = os.execute(pyenv_build_path .. " " .. version .. " " .. path)
62+
if status ~= 0 then
63+
error("python build failed")
64+
end
65+
print("Build python success!")
66+
print("Cleaning up ...")
67+
status = os.execute("rm -rf " .. dest_pyenv_path)
68+
if status ~= 0 then
69+
error("remove build tool failed")
70+
end
71+
end
72+
function checkAvailableReleaseForWindows(version)
73+
local archType = RUNTIME.archType
74+
if archType == "386" then
75+
archType = ""
76+
else
77+
archType = "-" .. archType
78+
end
79+
--- Currently only exe installers are supported
80+
--- TODO support zip or web-based installers
81+
local url = DOWNLOAD_SOURCE.EXE:format(version, version, archType)
82+
local resp, err = http.head({
83+
url = url
84+
})
85+
if err ~= nil or resp.status_code ~= 200 then
86+
error("No available installer found for current version")
87+
end
88+
return url, "python-" .. version .. archType .. ".exe"
89+
end
90+
function parseVersion()
91+
local resp, err = http.get({
92+
url = PYTHON_URL
93+
})
94+
if err ~= nil or resp.status_code ~= 200 then
95+
error("paring release info failed." .. err)
96+
end
97+
local result = {}
98+
html.parse(resp.body):find("a"):each(function(i, selection)
99+
local href = selection:attr("href")
100+
local sn = string.match(href, "^%d")
101+
local es = string.match(href, "/$")
102+
if sn and es then
103+
local vn = string.sub(href, 1, -2)
104+
if RUNTIME.osType == "windows" then
105+
if compare_versions(vn, "3.5.0") >= 0 then
106+
table.insert(result, {
107+
version = string.sub(href, 1, -2),
108+
note = "",
109+
})
110+
end
111+
else
112+
table.insert(result, {
113+
version = vn,
114+
note = "",
115+
})
116+
end
117+
end
118+
end)
119+
table.sort(result, function(a, b)
120+
return compare_versions(a.version, b.version) > 0
121+
end)
122+
return result
123+
end
124+
125+
function compare_versions(v1, v2)
126+
local v1_parts = {}
127+
for part in string.gmatch(v1, "[^.]+") do
128+
table.insert(v1_parts, tonumber(part))
129+
end
130+
131+
local v2_parts = {}
132+
for part in string.gmatch(v2, "[^.]+") do
133+
table.insert(v2_parts, tonumber(part))
134+
end
135+
136+
for i = 1, math.max(#v1_parts, #v2_parts) do
137+
local v1_part = v1_parts[i] or 0
138+
local v2_part = v2_parts[i] or 0
139+
if v1_part > v2_part then
140+
return 1
141+
elseif v1_part < v2_part then
142+
return -1
143+
end
144+
end
145+
146+
return 0
147+
end

metadata.lua

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ PLUGIN = {}
33

44
--- !!! MUST BE SET !!!
55
--- Plugin name
6-
PLUGIN.name = "your plugin name"
6+
PLUGIN.name = "python"
77
--- Plugin version
8-
PLUGIN.version = "0.0.1"
8+
PLUGIN.version = "0.1.0"
99
--- Plugin homepage
10-
PLUGIN.homepage = "https://github.com/version-fox/vfox-plugin-template"
10+
PLUGIN.homepage = "https://github.com/version-fox/vfox-python"
1111
--- Plugin license, please choose a correct license according to your needs.
1212
PLUGIN.license = "Apache 2.0"
1313
--- Plugin description
14-
PLUGIN.description = "your plugin description"
14+
PLUGIN.description = "Python language support, https://www.python.org"
1515

1616

1717
--- !!! OPTIONAL !!!
@@ -22,19 +22,11 @@ NOTE:
2222
vfox will not load the plugin and prompt the user to upgrade vfox.
2323
--]]
2424
PLUGIN.minRuntimeVersion = "0.3.0"
25-
--[[
26-
NOTE:
27-
If configured, vfox will check for updates to the plugin at this address,
28-
otherwise it will check for updates at the global registry.
29-
30-
If you want use the global registry to distribute your plugin, you can remove this field.
31-
32-
If you develop a plugin based on the template, which will automatically generate a manifest file by CI,
33-
you can set this address to the manifest file address, so that the plugin can be updated automatically.
34-
35-
--]]
36-
PLUGIN.manifestUrl = "https://github.com/version-fox/vfox-plugin-template/releases/download/manifest/manifest.json"
3725
-- Some things that need user to be attention!
3826
PLUGIN.notes = {
39-
"",
27+
"Mirror Setting:",
28+
"You can use VFOX_PYTHON_MIRROR environment variable to set mirror.",
29+
" ",
30+
"Others:",
31+
"For Windows, only support >=3.5.0, but no restrictions for unix-like."
4032
}

0 commit comments

Comments
 (0)