@ahqstore/cli 0.10.0 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +4 -0
- package/Cargo.toml +1 -1
- package/bundle.ps1 +7 -7
- package/go/ahqstore.go +166 -0
- package/go/ahqstore_unix.go +17 -0
- package/go/ahqstore_windows.go +16 -0
- package/go/go.mod +15 -0
- package/go/go.sum +28 -0
- package/js/cli.js +42 -9
- package/js/download.js +70 -12
- package/package.json +1 -1
- package/python/.vscode/settings.json +4 -0
- package/python/cli.py +124 -0
- package/python/pyproject.toml +27 -0
- package/python/setup.py +3 -0
package/Cargo.toml
CHANGED
package/bundle.ps1
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
mkdir dist
|
|
2
2
|
|
|
3
|
-
Copy-Item "./target/$env:TARGET/release/ahqstore.exe" "./dist/ahqstore.exe" -ErrorAction
|
|
4
|
-
Copy-Item "./target/$env:TARGET/release/ahqstore.exe" "./dist/ahqstore_cli_rs.exe" -ErrorAction
|
|
3
|
+
Copy-Item "./target/$env:TARGET/release/ahqstore.exe" "./dist/ahqstore.exe" -ErrorAction SilentlyContinue
|
|
4
|
+
Copy-Item "./target/$env:TARGET/release/ahqstore.exe" "./dist/ahqstore_cli_rs.exe" -ErrorAction SilentlyContinue
|
|
5
5
|
|
|
6
|
-
Copy-Item "./target/$env:TARGET/release/ahqstore" "./dist/ahqstore" -ErrorAction
|
|
7
|
-
Copy-Item "./target/$env:TARGET/release/ahqstore" "./dist/ahqstore_cli_rs" -ErrorAction
|
|
6
|
+
Copy-Item "./target/$env:TARGET/release/ahqstore" "./dist/ahqstore" -ErrorAction SilentlyContinue
|
|
7
|
+
Copy-Item "./target/$env:TARGET/release/ahqstore" "./dist/ahqstore_cli_rs" -ErrorAction SilentlyContinue
|
|
8
8
|
|
|
9
9
|
compress-archive ./dist/* ./ahqstore_cli_rs-$env:TARGET
|
|
10
10
|
|
|
11
|
-
Copy-Item "./target/$env:TARGET/release/ahqstore_cli_rs.dll" "./ahqstore_cli_rs-$env:TARGET.dll" -ErrorAction
|
|
12
|
-
Copy-Item "./target/$env:TARGET/release/libahqstore_cli_rs.so" "./libahqstore_cli_rs-$env:TARGET.so" -ErrorAction
|
|
13
|
-
Copy-Item "./target/$env:TARGET/release/libahqstore_cli_rs.dylib" "./libahqstore_cli_rs-$env:TARGET.dylib" -ErrorAction
|
|
11
|
+
Copy-Item "./target/$env:TARGET/release/ahqstore_cli_rs.dll" "./ahqstore_cli_rs-$env:TARGET.dll" -ErrorAction SilentlyContinue
|
|
12
|
+
Copy-Item "./target/$env:TARGET/release/libahqstore_cli_rs.so" "./libahqstore_cli_rs-$env:TARGET.so" -ErrorAction SilentlyContinue
|
|
13
|
+
Copy-Item "./target/$env:TARGET/release/libahqstore_cli_rs.dylib" "./libahqstore_cli_rs-$env:TARGET.dylib" -ErrorAction SilentlyContinue
|
package/go/ahqstore.go
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"io"
|
|
6
|
+
"net/http"
|
|
7
|
+
"os"
|
|
8
|
+
"path"
|
|
9
|
+
"runtime"
|
|
10
|
+
|
|
11
|
+
"github.com/ebitengine/purego"
|
|
12
|
+
"github.com/schollz/progressbar/v3"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
const version = "0.10.2"
|
|
16
|
+
|
|
17
|
+
func main() {
|
|
18
|
+
var bin = getBinary()
|
|
19
|
+
|
|
20
|
+
var libahqstore, err = openLibrary(bin)
|
|
21
|
+
|
|
22
|
+
if err != nil {
|
|
23
|
+
Download(bin)
|
|
24
|
+
libahqstore, err = openLibrary(bin)
|
|
25
|
+
|
|
26
|
+
if err != nil {
|
|
27
|
+
os.Exit(1)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
var get_ver func() string
|
|
32
|
+
purego.RegisterLibFunc(&get_ver, libahqstore, "get_ver")
|
|
33
|
+
|
|
34
|
+
if get_ver() != version {
|
|
35
|
+
unloadLibrary(libahqstore)
|
|
36
|
+
|
|
37
|
+
os.Remove(bin)
|
|
38
|
+
|
|
39
|
+
Download(bin)
|
|
40
|
+
libahqstore, err = openLibrary(bin)
|
|
41
|
+
|
|
42
|
+
if err != nil {
|
|
43
|
+
os.Exit(1)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
var init_args func()
|
|
48
|
+
purego.RegisterLibFunc(&init_args, libahqstore, "init_args")
|
|
49
|
+
|
|
50
|
+
init_args()
|
|
51
|
+
|
|
52
|
+
var add_arg func(string)
|
|
53
|
+
purego.RegisterLibFunc(&add_arg, libahqstore, "add_arg")
|
|
54
|
+
|
|
55
|
+
for i := 1; i < len(os.Args); i++ {
|
|
56
|
+
add_arg(os.Args[i])
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
var node_entrypoint func(bool)
|
|
60
|
+
purego.RegisterLibFunc(&node_entrypoint, libahqstore, "node_entrypoint")
|
|
61
|
+
|
|
62
|
+
node_entrypoint(
|
|
63
|
+
os.Getenv("CI") == "true",
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
func Download(file string) {
|
|
68
|
+
var prefix, suffix = GetPrefixSuffix()
|
|
69
|
+
var triple, _ = GetRustTargetTriple()
|
|
70
|
+
|
|
71
|
+
var url = fmt.Sprintf("https://github.com/ahqstore/cli/releases/download/%s/%sahqstore_cli_rs-%s%s", version, prefix, triple, suffix)
|
|
72
|
+
|
|
73
|
+
var req, _ = http.NewRequest("GET", url, nil)
|
|
74
|
+
var resp, err = http.DefaultClient.Do(req)
|
|
75
|
+
|
|
76
|
+
if err != nil {
|
|
77
|
+
fmt.Println("Could not connect to download the required dynamic library")
|
|
78
|
+
os.Exit(1)
|
|
79
|
+
}
|
|
80
|
+
defer resp.Body.Close()
|
|
81
|
+
|
|
82
|
+
bar := progressbar.DefaultBytes(
|
|
83
|
+
resp.ContentLength,
|
|
84
|
+
"Downloading...",
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
defer bar.Finish()
|
|
88
|
+
|
|
89
|
+
var f, _ = os.OpenFile(file, os.O_WRONLY|os.O_CREATE, os.ModePerm)
|
|
90
|
+
defer f.Close()
|
|
91
|
+
|
|
92
|
+
io.Copy(io.MultiWriter(f, bar), resp.Body)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
func GetPrefixSuffix() (string, string) {
|
|
96
|
+
switch runtime.GOOS {
|
|
97
|
+
case "windows":
|
|
98
|
+
return "", ".dll"
|
|
99
|
+
case "darwin":
|
|
100
|
+
return "lib", ".dylib"
|
|
101
|
+
default:
|
|
102
|
+
return "lib", ".so"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
func GetRustTargetTriple() (string, error) {
|
|
107
|
+
// Use runtime.GOOS for the operating system and runtime.GOARCH for the architecture.
|
|
108
|
+
switch runtime.GOOS {
|
|
109
|
+
case "windows":
|
|
110
|
+
switch runtime.GOARCH {
|
|
111
|
+
case "386":
|
|
112
|
+
return "i686-pc-windows-msvc", nil
|
|
113
|
+
case "amd64":
|
|
114
|
+
return "x86_64-pc-windows-msvc", nil
|
|
115
|
+
case "arm64":
|
|
116
|
+
return "aarch64-pc-windows-msvc", nil
|
|
117
|
+
}
|
|
118
|
+
case "darwin":
|
|
119
|
+
switch runtime.GOARCH {
|
|
120
|
+
case "amd64":
|
|
121
|
+
return "x86_64-apple-darwin", nil
|
|
122
|
+
case "arm64":
|
|
123
|
+
return "aarch64-apple-darwin", nil
|
|
124
|
+
}
|
|
125
|
+
case "linux":
|
|
126
|
+
switch runtime.GOARCH {
|
|
127
|
+
case "386":
|
|
128
|
+
return "i686-unknown-linux-gnu", nil
|
|
129
|
+
case "amd64":
|
|
130
|
+
return "x86_64-unknown-linux-gnu", nil
|
|
131
|
+
case "arm":
|
|
132
|
+
return "armv7-unknown-linux-gnueabihf", nil
|
|
133
|
+
case "arm64":
|
|
134
|
+
return "aarch64-unknown-linux-gnu", nil
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return "", fmt.Errorf("whoa there, this platform is not on the list: %s %s", runtime.GOOS, runtime.GOARCH)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
func binName() string {
|
|
142
|
+
var prefix, suffix = GetPrefixSuffix()
|
|
143
|
+
|
|
144
|
+
return fmt.Sprintf("%sahqstore_cli_rs%s", prefix, suffix)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
func getBinary() string {
|
|
148
|
+
var dir, err = os.UserHomeDir()
|
|
149
|
+
|
|
150
|
+
if err != nil {
|
|
151
|
+
fmt.Println(err)
|
|
152
|
+
os.Exit(1)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
dir = path.Join(dir, "ahqstore-go")
|
|
156
|
+
|
|
157
|
+
_, err = os.ReadDir(dir)
|
|
158
|
+
|
|
159
|
+
if err != nil {
|
|
160
|
+
os.MkdirAll(dir, os.ModePerm)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
var file = path.Join(dir, binName())
|
|
164
|
+
|
|
165
|
+
return file
|
|
166
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//go:build darwin || freebsd || linux || netbsd
|
|
2
|
+
|
|
3
|
+
package main
|
|
4
|
+
|
|
5
|
+
import (
|
|
6
|
+
"syscall"
|
|
7
|
+
|
|
8
|
+
"github.com/ebitengine/purego"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
func openLibrary(name string) (uintptr, error) {
|
|
12
|
+
return purego.Dlopen(name, purego.RTLD_NOW|purego.RTLD_GLOBAL)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
func unloadLibrary(library uintptr) {
|
|
16
|
+
purego.Dlclose(syscall.Handle(library))
|
|
17
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//go:build windows
|
|
2
|
+
|
|
3
|
+
package main
|
|
4
|
+
|
|
5
|
+
import "syscall"
|
|
6
|
+
|
|
7
|
+
func openLibrary(name string) (uintptr, error) {
|
|
8
|
+
// Use [syscall.LoadLibrary] here to avoid external dependencies (#270).
|
|
9
|
+
// For actual use cases, [golang.org/x/sys/windows.NewLazySystemDLL] is recommended.
|
|
10
|
+
handle, err := syscall.LoadLibrary(name)
|
|
11
|
+
return uintptr(handle), err
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
func unloadLibrary(library uintptr) {
|
|
15
|
+
syscall.FreeLibrary(syscall.Handle(library))
|
|
16
|
+
}
|
package/go/go.mod
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module github.com/ahqstore
|
|
2
|
+
|
|
3
|
+
go 1.25.1
|
|
4
|
+
|
|
5
|
+
require (
|
|
6
|
+
github.com/ebitengine/purego v0.8.4
|
|
7
|
+
github.com/schollz/progressbar/v3 v3.18.0
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
require (
|
|
11
|
+
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
|
12
|
+
github.com/rivo/uniseg v0.4.7 // indirect
|
|
13
|
+
golang.org/x/sys v0.36.0 // indirect
|
|
14
|
+
golang.org/x/term v0.35.0 // indirect
|
|
15
|
+
)
|
package/go/go.sum
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM=
|
|
2
|
+
github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY=
|
|
3
|
+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
4
|
+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
5
|
+
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
|
|
6
|
+
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
|
7
|
+
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
|
8
|
+
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
|
9
|
+
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
|
|
10
|
+
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
|
|
11
|
+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
12
|
+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
13
|
+
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
|
14
|
+
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
|
15
|
+
github.com/schollz/progressbar/v3 v3.18.0 h1:uXdoHABRFmNIjUfte/Ex7WtuyVslrw2wVPQmCN62HpA=
|
|
16
|
+
github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec=
|
|
17
|
+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
|
18
|
+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
|
19
|
+
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
|
20
|
+
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
21
|
+
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
|
22
|
+
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
|
23
|
+
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
|
24
|
+
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
|
25
|
+
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
|
|
26
|
+
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
|
|
27
|
+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
28
|
+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
package/js/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
// @ts-check
|
|
3
3
|
|
|
4
|
-
import { existsSync, mkdirSync, rmSync } from "node:fs";
|
|
5
4
|
import { join } from "node:path";
|
|
5
|
+
import { existsSync, mkdirSync, rmSync } from "node:fs";
|
|
6
6
|
import { argv, env, platform } from "node:process";
|
|
7
7
|
|
|
8
8
|
import { downloadModuleWithProgress } from "./download.js";
|
|
@@ -47,23 +47,48 @@ function getLibraryFilename(name) {
|
|
|
47
47
|
return `${prefix}${name}${suffix}`;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
console.log(import.meta.dirname);
|
|
51
|
-
|
|
52
50
|
const dylibDir = join(import.meta.dirname, "lib");
|
|
51
|
+
const dylib = join(dylibDir, getLibraryFilename("ahqstore_cli_rs"));
|
|
53
52
|
|
|
54
|
-
if (!existsSync(dylibDir)) {
|
|
53
|
+
if (!(existsSync(dylibDir) && existsSync(dylib))) {
|
|
55
54
|
console.warn(
|
|
56
55
|
c.red.redBright(
|
|
57
56
|
"Binary not found, downloading AHQ Store CLI Binary for this version",
|
|
58
57
|
),
|
|
59
58
|
);
|
|
60
59
|
|
|
61
|
-
|
|
60
|
+
try {
|
|
61
|
+
rmSync(dylib);
|
|
62
|
+
} catch(_) {}
|
|
63
|
+
try {
|
|
64
|
+
mkdirSync(dylibDir);
|
|
65
|
+
} catch (_) {}
|
|
66
|
+
|
|
67
|
+
await downloadModuleWithProgress(dylib);
|
|
62
68
|
}
|
|
63
69
|
|
|
64
|
-
|
|
70
|
+
let dlib;
|
|
65
71
|
|
|
66
|
-
|
|
72
|
+
try {
|
|
73
|
+
dlib = koffi.load(dylib);
|
|
74
|
+
} catch (_) {
|
|
75
|
+
console.warn(
|
|
76
|
+
c.red.redBright(
|
|
77
|
+
"Binary is corrupted, downloading AHQ Store CLI Binary for this version",
|
|
78
|
+
),
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
rmSync(dylib);
|
|
83
|
+
} catch(_) {}
|
|
84
|
+
try {
|
|
85
|
+
mkdirSync(dylibDir);
|
|
86
|
+
} catch (_) {}
|
|
87
|
+
|
|
88
|
+
await downloadModuleWithProgress(dylib);
|
|
89
|
+
|
|
90
|
+
dlib = koffi.load(dylib);
|
|
91
|
+
}
|
|
67
92
|
|
|
68
93
|
const ver = dlib.func("get_ver", "str", []);
|
|
69
94
|
|
|
@@ -79,10 +104,15 @@ if (output != pkg.version) {
|
|
|
79
104
|
// Unload current one
|
|
80
105
|
dlib.unload();
|
|
81
106
|
|
|
82
|
-
|
|
107
|
+
try {
|
|
108
|
+
rmSync(dylib);
|
|
109
|
+
} catch(_) {}
|
|
110
|
+
try {
|
|
111
|
+
mkdirSync(dylibDir);
|
|
112
|
+
} catch (_) {}
|
|
83
113
|
|
|
84
114
|
/// Download
|
|
85
|
-
|
|
115
|
+
await downloadModuleWithProgress(dylib);
|
|
86
116
|
|
|
87
117
|
// Load newer
|
|
88
118
|
dlib = koffi.load(dylib);
|
|
@@ -96,4 +126,7 @@ argv.slice(2).forEach((a) => {
|
|
|
96
126
|
pushArg(a);
|
|
97
127
|
});
|
|
98
128
|
|
|
129
|
+
// Clear the console output
|
|
130
|
+
console.clear();
|
|
131
|
+
|
|
99
132
|
dlib.func("node_entrypoint", "void", ["bool"])(env["CI"] == "true");
|
package/js/download.js
CHANGED
|
@@ -1,29 +1,87 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
import { SingleBar } from "cli-progress";
|
|
4
|
-
import c from "ansi-colors";
|
|
5
|
-
|
|
6
|
-
import pkg from "../package.json" with { type: "json" };
|
|
7
4
|
import { getPrefixSuffix } from "./cli.js";
|
|
8
5
|
import { getRustTarget } from "./rust.js";
|
|
6
|
+
import { createWriteStream } from "node:fs";
|
|
7
|
+
|
|
8
|
+
import c from "ansi-colors";
|
|
9
|
+
import pkg from "../package.json" with { type: "json" };
|
|
9
10
|
|
|
10
11
|
const bar = new SingleBar({
|
|
11
12
|
format:
|
|
12
|
-
"Downloading |" + c.cyan("{bar}") + "| {percentage}%
|
|
13
|
+
"Downloading |" + c.cyan("{bar}") + "| {percentage}% | {value}/{total} KB",
|
|
13
14
|
barCompleteChar: "\u2588",
|
|
14
15
|
barIncompleteChar: "\u2591",
|
|
15
16
|
hideCursor: true,
|
|
16
17
|
});
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
bar.increment();
|
|
21
|
-
bar.update(20);
|
|
22
|
-
|
|
23
|
-
async function getDownload() {
|
|
19
|
+
function getDownload() {
|
|
24
20
|
const { prefix, suffix } = getPrefixSuffix();
|
|
25
21
|
|
|
26
|
-
return `https://github.com/ahqstore/cli/releases/download/${pkg.version}/${prefix}ahqstore_cli_rs-${getRustTarget()}
|
|
22
|
+
return `https://github.com/ahqstore/cli/releases/download/${pkg.version}/${prefix}ahqstore_cli_rs-${getRustTarget()}${suffix}`;
|
|
27
23
|
}
|
|
28
24
|
|
|
29
|
-
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* @param {number} ms
|
|
28
|
+
* @returns {Promise<undefined>}
|
|
29
|
+
*/
|
|
30
|
+
const delay = (ms) => new Promise((resolve) => setTimeout(() => resolve(undefined), ms));
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param {string} file
|
|
35
|
+
* @returns {Promise<undefined>}
|
|
36
|
+
*/
|
|
37
|
+
export async function downloadModuleWithProgress(file) {
|
|
38
|
+
const download = getDownload();
|
|
39
|
+
|
|
40
|
+
const stream = createWriteStream(file, {
|
|
41
|
+
autoClose: true,
|
|
42
|
+
flush: true
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const res = await fetch(
|
|
46
|
+
download,
|
|
47
|
+
{
|
|
48
|
+
headers: {
|
|
49
|
+
"user-agent": "Downloader"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const bytes = parseInt(res.headers.get("content-length") || "0");
|
|
55
|
+
const kb = Math.round(bytes / 1024);
|
|
56
|
+
|
|
57
|
+
bar.start(kb, 0);
|
|
58
|
+
|
|
59
|
+
const reader = res.body?.getReader()
|
|
60
|
+
|
|
61
|
+
let curr = 0;
|
|
62
|
+
|
|
63
|
+
while (true) {
|
|
64
|
+
const buf = await reader?.read();
|
|
65
|
+
|
|
66
|
+
if (!buf || !buf.value) {
|
|
67
|
+
bar.update(kb);
|
|
68
|
+
bar.stop();
|
|
69
|
+
|
|
70
|
+
await new Promise((resolve) => {
|
|
71
|
+
stream.on('close', () => resolve(undefined));
|
|
72
|
+
stream.end();
|
|
73
|
+
});
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const toAdd = buf.value.length || 0;
|
|
78
|
+
|
|
79
|
+
curr += Math.round(toAdd / 1024);
|
|
80
|
+
|
|
81
|
+
bar.update(curr);
|
|
82
|
+
|
|
83
|
+
stream.write(buf.value);
|
|
84
|
+
|
|
85
|
+
await delay(1);
|
|
86
|
+
}
|
|
87
|
+
}
|
package/package.json
CHANGED
package/python/cli.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
from cffi import FFI
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from requests import get
|
|
4
|
+
|
|
5
|
+
import importlib.metadata
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import platform
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
ffi = FFI()
|
|
12
|
+
|
|
13
|
+
ffi.cdef("""
|
|
14
|
+
char* get_ver();
|
|
15
|
+
void init_args();
|
|
16
|
+
void add_arg(char*);
|
|
17
|
+
void node_entrypoint(bool);
|
|
18
|
+
""")
|
|
19
|
+
|
|
20
|
+
ver = importlib.metadata.version("ahqstore-cli")
|
|
21
|
+
|
|
22
|
+
def rust_target():
|
|
23
|
+
os = platform.system().lower()
|
|
24
|
+
arch = platform.machine().lower()
|
|
25
|
+
|
|
26
|
+
if os == "windows":
|
|
27
|
+
if arch == "i686":
|
|
28
|
+
return "i686-pc-windows-msvc"
|
|
29
|
+
elif arch in ("x86_64", "amd64"):
|
|
30
|
+
return "x86_64-pc-windows-msvc"
|
|
31
|
+
elif arch == "aarch64":
|
|
32
|
+
return "aarch64-pc-windows-msvc"
|
|
33
|
+
elif os == "darwin":
|
|
34
|
+
if arch in ("x86_64", "amd64"):
|
|
35
|
+
return "x86_64-apple-darwin"
|
|
36
|
+
elif arch == "aarch64":
|
|
37
|
+
return "aarch64-apple-darwin"
|
|
38
|
+
elif os == "linux":
|
|
39
|
+
if arch == "i686":
|
|
40
|
+
return "i686-unknown-linux-gnu"
|
|
41
|
+
elif arch in ("x86_64", "amd64"):
|
|
42
|
+
return "x86_64-unknown-linux-gnu"
|
|
43
|
+
elif arch == "armv7l":
|
|
44
|
+
return "armv7-unknown-linux-gnueabihf"
|
|
45
|
+
elif arch == "aarch64":
|
|
46
|
+
return "aarch64-unknown-linux-gnu"
|
|
47
|
+
|
|
48
|
+
# Error out for unsupported systems
|
|
49
|
+
print(f"Error: Unsupported platform: {os} {arch}")
|
|
50
|
+
sys.exit(1)
|
|
51
|
+
|
|
52
|
+
def get_prefix_suffix():
|
|
53
|
+
os = platform.system().lower()
|
|
54
|
+
prefix = ""
|
|
55
|
+
suffix = ""
|
|
56
|
+
|
|
57
|
+
if os == "windows":
|
|
58
|
+
suffix = ".dll"
|
|
59
|
+
elif os == "darwin":
|
|
60
|
+
prefix = "lib"
|
|
61
|
+
suffix = ".dylib"
|
|
62
|
+
elif os == "linux":
|
|
63
|
+
prefix = "lib"
|
|
64
|
+
suffix = ".so"
|
|
65
|
+
else:
|
|
66
|
+
# Default to a generic UNIX-like system
|
|
67
|
+
prefix = "lib"
|
|
68
|
+
suffix = ".so"
|
|
69
|
+
|
|
70
|
+
return (prefix, suffix)
|
|
71
|
+
|
|
72
|
+
def dlib():
|
|
73
|
+
(prefix, suffix) = get_prefix_suffix()
|
|
74
|
+
|
|
75
|
+
return f"{prefix}ahqstore_cli_rs{suffix}"
|
|
76
|
+
|
|
77
|
+
dylib = Path.home().joinpath("ahqstore-py")
|
|
78
|
+
|
|
79
|
+
if not dylib.exists():
|
|
80
|
+
dylib.mkdir()
|
|
81
|
+
|
|
82
|
+
dylib = dylib.joinpath(dlib())
|
|
83
|
+
|
|
84
|
+
def dwnl():
|
|
85
|
+
(prefix, suffix) = get_prefix_suffix()
|
|
86
|
+
|
|
87
|
+
return f"https://github.com/ahqstore/cli/releases/download/{ver}/{prefix}ahqstore_cli_rs-{rust_target()}{suffix}"
|
|
88
|
+
|
|
89
|
+
def dwn():
|
|
90
|
+
url = dwnl()
|
|
91
|
+
|
|
92
|
+
resp = get(url)
|
|
93
|
+
|
|
94
|
+
resp.raise_for_status()
|
|
95
|
+
|
|
96
|
+
with open(dylib, "wb") as f:
|
|
97
|
+
f.write(resp.content)
|
|
98
|
+
|
|
99
|
+
def main():
|
|
100
|
+
C = None
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
C = ffi.dlopen(str(dylib))
|
|
104
|
+
|
|
105
|
+
ver_ptr = C.get_ver()
|
|
106
|
+
|
|
107
|
+
version = ffi.string(ver_ptr)
|
|
108
|
+
|
|
109
|
+
if not version == bytes(ver, "utf-8"):
|
|
110
|
+
raise BufferError("This was an error comapring them")
|
|
111
|
+
except:
|
|
112
|
+
dwn()
|
|
113
|
+
C = ffi.dlopen(str(dylib))
|
|
114
|
+
|
|
115
|
+
C.init_args()
|
|
116
|
+
|
|
117
|
+
for item in sys.argv[1:]:
|
|
118
|
+
arg = ffi.new("char[]", bytes(item, "ascii"))
|
|
119
|
+
|
|
120
|
+
C.add_arg(arg)
|
|
121
|
+
|
|
122
|
+
C.node_entrypoint(
|
|
123
|
+
os.environ.get("CI") == "true"
|
|
124
|
+
)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ahqstore-cli"
|
|
7
|
+
version = "0.10.2"
|
|
8
|
+
authors = [{ name = "AHQ Softwares", email = "ahqsecret@gmail.com" }]
|
|
9
|
+
description = "A modern Python wrapper for the ahqstore CLI"
|
|
10
|
+
readme = "../README.md"
|
|
11
|
+
requires-python = ">=3.8"
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Programming Language :: Python :: 3",
|
|
14
|
+
"License :: OSI Approved :: MIT License",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
]
|
|
17
|
+
dependencies = [
|
|
18
|
+
# List your Python dependencies here, e.g.,
|
|
19
|
+
"requests>=2.25.1",
|
|
20
|
+
"cffi>=1.17.0",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[tool.hatch.build.targets.wheel]
|
|
24
|
+
packages = ["."]
|
|
25
|
+
|
|
26
|
+
[project.scripts]
|
|
27
|
+
ahqstore = "cli:main"
|
package/python/setup.py
ADDED