添加 kit 子目录

This commit is contained in:
Cheney
2024-03-07 15:50:13 +08:00
parent e0c2ab8c1e
commit 5fd50792a0
24 changed files with 3143 additions and 0 deletions
+228
View File
@@ -0,0 +1,228 @@
/**
* remote 模块用来处理远程仓库相关事务
*/
const path = require("path")
const fs = require("fs")
const JSON5 = require('json5')
const { pipeline, Transform} = require("node:stream/promises");
module.exports = class Remote {
constructor() {
this.init()
this.func_publish = require("./publish")
this.func_install = require("./install")
}
async init() {
this.webdav = await import("webdav");
const uConfig = await $context.get("uConfig");
if ( uConfig.get("remoteServer") ){
let server = uConfig.get("remoteServer");
if ( server.startsWith("webdav") ) {
server = "http" + server.substring(6)
}
if ( uConfig.get("remoteAuth") ) {
let up = uConfig.get("remoteAuth");
up = up.split(":", 2)
this.client = this.webdav.createClient(
server,
{
username: up[0],
password: up[1]
}
);
} else {
this.client = this.webdav.createClient(
server
);
}
}
}
async check() {
if ( ! this.webdav ) {
return false
}
if ( ! this.client ) {
return false
}
try {
// Get directory contents
const directoryItems = await this.client.getDirectoryContents("/");
// 是否包含 index.json ?
// 不包含尝试创建
// 包含了尝试下载
const indexJsonFile = this.getIndexJson( directoryItems );
if ( indexJsonFile ) {
// 包含了尝试下载
// 下载有缓存
this.download(indexJsonFile)
} else {
// 不包含尝试创建
await this.affireRemoteStore()
}
return true
}catch ( e ) {
$logger.error("remote check 过程中出错", e)
return false
}
}
/**
* 先对比时间和长度,有不同才会真正下载,否则使用本地缓存。
* 本地缓存路径即本地仓库路径
* @param rFile
*/
download(rFile){
const lFilePath = path.resolve($sConfig.getLocalStorePath(), rFile.filename);
if ( fs.existsSync( lFilePath ) ) {
const lFileInfo = fs.statSync(lFilePath);
if ( lFileInfo.size === rFile.length
&& lFileInfo.mtime === rFile.lastmod
) {
// 使用缓存
$logger.debug("use cache")
return true
}
}
// 下载并覆盖
// 不知道是同步还是异步
this.wDownload( rFile.filename, lFilePath );
}
async affireRemoteStore(){
// Get directory contents
const directoryItems = await this.client.getDirectoryContents("/");
// 是否包含 index.json ?
// 不包含尝试创建
// 包含了尝试下载
const indexJsonFile = this.getIndexJson( directoryItems );
if ( ! indexJsonFile ) {
// 创建 index
await this.client.putFileContents("/index.json", JSON5.stringify({
modules : [],
tmpls : [],
lists : []
}, null, 4) , { overwrite: false });
}
const modulesFolder = this.getFileInfoByName(directoryItems, "modules")
if ( ! modulesFolder ) {
// 创建文件夹
await this.client.createDirectory("/modules");
}
const tmplsFolder = this.getFileInfoByName(directoryItems, "tmpls")
if ( ! tmplsFolder ) {
// 创建文件夹
await this.client.createDirectory("/tmpls");
}
const listsFolder = this.getFileInfoByName(directoryItems, "lists")
if ( ! listsFolder ) {
// 创建文件夹
await this.client.createDirectory("/lists");
}
}
getIndexJson(items){
return this.getFileInfoByName( items, "index.json" );
}
getFileInfoByName(items, name){
if ( ! items || items.length < 1 ) {
return false;
}
for ( let item of items ) {
if ( item.basename === name ) {
return item;
}
}
return false;
}
async publish(){
return this.func_publish( this )
}
async install(id){
return this.func_install( this, id )
}
async wUpload(from, to){
const totalSize = fs.statSync(from).size;
const rs = fs.createReadStream( from );
let wSize = 0;
let rSize = 0;
rs.on("data", (r)=>{
rSize += r.length;
// console.log("r", rSize * 100 / totalSize)
})
const ws = this.client.createWriteStream(to)
ws.on("data", (r)=>{
wSize += r.length;
// console.log("w", wSize * 100 / totalSize)
})
return pipeline( rs, ws);
}
async wDownload(from, to){
$logger.info("download", from, to )
const stat = await this.client.stat(from);
const totalSize = stat.size;
let wSize = 0;
let rSize = 0;
const rs = this.client.createReadStream(from);
rs.on("data", (r)=>{
rSize += r.length;
// console.log("r", rSize * 100 / totalSize)
})
const ws = fs.createWriteStream(to);
ws.on("data", (r)=>{
wSize += r.length;
// console.log("w", wSize * 100 / totalSize)
})
return pipeline(
rs, ws
)
}
async wMkdir(folder){
const folderfather = path.dirname( folder );
if ( ! await this.client.exists( folderfather ) ) {
// await remote.client.createDirectory( folderfather )
await this.wMkdir( folderfather )
}
if ( await this.client.exists( folder ) ) {
return
} else {
await this.client.createDirectory( folder )
}
}
async wGetModuleInfo(id){
let meta = await this.client.getFileContents("/modules/" + id + "/meta.json", { format: "text" });
let metaJson = JSON5.parse( meta );
return metaJson
}
}
+53
View File
@@ -0,0 +1,53 @@
const os = require('os');
const fs = require("fs");
const osutil = require("../util/osutil")
function matchDistName(cur, dists){
const list = []
for (let dist of dists) {
if ( cur.curOS === dist.os && cur.curPlatform === dist.platform) {
list.push( dist )
}
else if ( cur.curOS === dist.os && "cross" === dist.platform) {
list.unshift( dist )
}
else if ( "cross" === dist.os && cur.curPlatform === dist.platform) {
list.unshift( dist )
}
}
return list
}
module.exports = async function install(remote, id){
const cur = osutil.cur();
if ( ! id ) {
id = "kit"
}
// 获取本地版本
const localInfo = osutil.choise([
require("../windows/local").getModuleInfo,
require("../linux/local").getModuleInfo,
])( id )
$logger.info("local version", localInfo.version)
// 确认远程版本文件是否存在
const remoteInfo = await remote.wGetModuleInfo(id)
$logger.info("remote latest version", remoteInfo.latest.version)
const dists = matchDistName(cur, remoteInfo.latest.dist)
const dist = dists.pop()
await remote.wDownload(
"/modules/" + id + "/" + remoteInfo.latest.version + "/" + cur.curOS + "/" + cur.curPlatform + "/" + dist.filename,
localInfo.homeDir + "/" + dist.filename,
)
fs.writeFileSync( localInfo.homeDir + "/version", remoteInfo.latest.version );
$logger.info("当前版本", remoteInfo.latest.version )
}
+79
View File
@@ -0,0 +1,79 @@
const path = require("path")
const fs = require("fs")
const JSON5 = require('json5')
const { pipeline } = require('node:stream/promises');
const objutil = require("../util/objutil")
module.exports = async function publish(remote, meta){
let curPath = process.cwd();
const metaFilePath = path.resolve( curPath, "meta.json" );
if ( ! fs.existsSync( metaFilePath ) ) {
$logger.error("当前路径不包含 meta.json")
return
}
const metaFile = fs.readFileSync(metaFilePath);
const localMeta = JSON5.parse( metaFile );
// 更新版本
const date = new Date();
localMeta.version = `${localMeta.version}.${date.getFullYear()}${(date.getMonth() + 1).toString().padStart(2, '0')}${date.getDate().toString().padStart(2, '0')}${date.getHours().toString().padStart(2, '0')}${date.getMinutes().toString().padStart(2, '0')}${date.getSeconds().toString().padStart(2, '0')}`;
// 确认目录
// const directoryItems = await remote.getDirectoryContents("/modules");
// const modulesFolder = remote.getFileInfoByName(directoryItems, localMeta.id)
if ( ! await remote.client.exists("/modules/" + localMeta.id) ) {
// 创建文件夹
await remote.client.createDirectory("/modules/" + localMeta.id);
}
// 先更新文件
for (let dist of localMeta.dist ) {
const folder = "/modules/" + localMeta.id + "/" + localMeta.version + "/" + dist.os + "/" + dist.platform
await remote.wMkdir( folder );
$logger.info("upload dist", dist.path, fs.existsSync(dist.path))
await remote.wUpload( dist.path , folder + "/" + dist.filename );
}
// remote meta
let remoteMeta = {
"versions" : []
}
try {
const remoteMetaStr = await remote.client.getFileContents("/modules/" + localMeta.id + "/meta.json", { format: "text" });
remoteMeta = JSON5.parse( remoteMetaStr )
} catch (e) {
}
remoteMeta.id = localMeta.id;
remoteMeta.name = localMeta.name;
remoteMeta.desc = localMeta.desc;
remoteMeta.type = localMeta.type;
remoteMeta.vcs = localMeta.vcs;
// 废弃
// remoteMeta.platform = "cross" === localMeta.platform ? ["X86_64", "ARM64"] : localMeta.platform;
// remoteMeta.os = "cross" === localMeta.os ? ["Windows", "Linux", "Alpine"] : localMeta.os;
const dist = objutil.copy(localMeta.dist)
for (let d of dist) {
delete dist.path
}
remoteMeta.latest = {
version : localMeta.version,
dist
}
remoteMeta.versions.push(remoteMeta.latest)
if ( remoteMeta.versions.length >= 20 ) {
remoteMeta.versions = remoteMeta.versions.slice(0, 20);
}
await remote.client.putFileContents("/modules/" + localMeta.id + "/meta.json", JSON5.stringify(remoteMeta, null, 4) , { overwrite: true });
$logger.info("发布成功")
}