auto-package-lock
Advanced tools
Comparing version 1.0.0 to 1.0.1
#!/usr/bin/env node | ||
const fs = require('fs') | ||
const struct_length = require('./utils').struct_length | ||
const struct_delete = require('./utils').struct_delete | ||
const DEPENDENCIES = 'dependencies' | ||
const PACKAGES = 'packages' | ||
const LOCKFILEVERSION = 'lockfileVersion' | ||
const REQUIRES = 'requires' | ||
const fs = require("fs"); | ||
const struct_length = require("./utils").struct_length; | ||
const struct_delete = require("./utils").struct_delete; | ||
const DEPENDENCIES = "dependencies"; | ||
const PACKAGES = "packages"; | ||
const LOCKFILEVERSION = "lockfileVersion"; | ||
const REQUIRES = "requires"; | ||
function apkl(temp_path,project_path,targetModule){ | ||
if (targetModule.length > 2) { | ||
console.error('依赖包信息错误') | ||
return | ||
} | ||
const module_name = targetModule[0] | ||
let module_tag = targetModule[1] | ||
let temp_data | ||
let temp_pkl | ||
function apkl(temp_path, project_path, targetModule) { | ||
if (targetModule.length > 2) { | ||
console.error("依赖包信息错误"); | ||
return; | ||
} | ||
const module_name = targetModule[0]; | ||
let module_tag = targetModule[1]; | ||
let temp_data; | ||
let temp_pkl; | ||
//读取temp目录下的package-lock.json文件,找出目标库的配置信息 | ||
let dependencies_data | ||
let packages_name | ||
let packages_data | ||
try { | ||
temp_data = fs.readFileSync(temp_path) | ||
temp_pkl = JSON.parse(temp_data.toString()) | ||
//读取temp目录下的package-lock.json文件,找出目标库的配置信息 | ||
let dependencies_data; | ||
let packages_name; | ||
let packages_data; | ||
try { | ||
temp_data = fs.readFileSync(temp_path); | ||
temp_pkl = JSON.parse(temp_data.toString()); | ||
//处理dependencies部分配置 | ||
for (const key in temp_pkl[DEPENDENCIES]) { | ||
if (key === module_name) { | ||
dependencies_data = temp_pkl[DEPENDENCIES][key] | ||
} | ||
//处理dependencies部分配置 | ||
for (const key in temp_pkl[DEPENDENCIES]) { | ||
if (key === module_name) { | ||
dependencies_data = temp_pkl[DEPENDENCIES][key]; | ||
} | ||
} | ||
if (dependencies_data === undefined) { | ||
console.error( | ||
"temp路径下package-lock.json解析dependencies出错,", | ||
temp_path | ||
); | ||
return; | ||
} | ||
module_tag = dependencies_data["version"]; | ||
//npm为v6版本及以下 | ||
if (temp_pkl[LOCKFILEVERSION] === 1) { | ||
let temp_child_module = {}; | ||
for (const key in temp_pkl[DEPENDENCIES]) { | ||
if (key !== module_name) { | ||
temp_child_module[key] = temp_pkl[DEPENDENCIES][key]; | ||
} | ||
if (dependencies_data === undefined) { | ||
console.error('temp路径下package-lock.json解析dependencies出错,',temp_path) | ||
return | ||
} | ||
module_tag = dependencies_data['version'] | ||
//npm为v6版本及以下 | ||
if (temp_pkl[LOCKFILEVERSION] === 1){ | ||
let temp_child_module = {} | ||
for (const key in temp_pkl[DEPENDENCIES]) { | ||
if (key !== module_name) { | ||
temp_child_module[key] = temp_pkl[DEPENDENCIES][key] | ||
} | ||
} | ||
if (struct_length(temp_child_module) > 0){ | ||
dependencies_data[DEPENDENCIES] = temp_child_module | ||
} | ||
} | ||
} | ||
if (struct_length(temp_child_module) > 0) { | ||
dependencies_data[DEPENDENCIES] = temp_child_module; | ||
} | ||
} | ||
if (temp_pkl[LOCKFILEVERSION] ===2 && temp_pkl[PACKAGES] !== undefined) { | ||
for (const key in temp_pkl[PACKAGES]) { | ||
const temp_key = key.split('/') | ||
if (temp_key[temp_key.length - 1] === module_name) { | ||
packages_name = key | ||
packages_data = temp_pkl[PACKAGES][key] | ||
} | ||
} | ||
if (packages_data === undefined) { | ||
console.error('temp路径下package-lock.json解析packages出错,',temp_path) | ||
} | ||
if (temp_pkl[LOCKFILEVERSION] === 2 && temp_pkl[PACKAGES] !== undefined) { | ||
for (const key in temp_pkl[PACKAGES]) { | ||
const temp_key = key.split("/"); | ||
if (temp_key[temp_key.length - 1] === module_name) { | ||
packages_name = key; | ||
packages_data = temp_pkl[PACKAGES][key]; | ||
} | ||
} catch (err) { | ||
console.error('temp路径package-lock.json读取失败', err) | ||
return | ||
} | ||
if (packages_data === undefined) { | ||
console.error( | ||
"temp路径下package-lock.json解析packages出错,", | ||
temp_path | ||
); | ||
} | ||
} | ||
} catch (err) { | ||
console.error("temp路径package-lock.json读取失败", err); | ||
return; | ||
} | ||
//读取目标项目的package-lock.json文件,将目标库的配置信息修改完毕 | ||
try { | ||
temp_data = fs.readFileSync(project_path) | ||
temp_pkl = JSON.parse(temp_data.toString()) | ||
let flag = false | ||
//读取目标项目的package-lock.json文件,将目标库的配置信息修改完毕 | ||
try { | ||
temp_data = fs.readFileSync(project_path); | ||
temp_pkl = JSON.parse(temp_data.toString()); | ||
let flag = false; | ||
//修改dependencies部分配置 | ||
for (const key in temp_pkl[DEPENDENCIES]) { | ||
if (key === module_name) { | ||
temp_pkl[DEPENDENCIES][key] = dependencies_data | ||
flag = true | ||
} | ||
//更改requires中的依赖版本 | ||
if (temp_pkl[DEPENDENCIES][key][REQUIRES] !== undefined) { | ||
if (temp_pkl[DEPENDENCIES][key][REQUIRES][module_name] !== undefined) { | ||
temp_pkl[DEPENDENCIES][key][REQUIRES][module_name] = module_tag | ||
} | ||
} | ||
//去除可能存在的第二层dependencies中的依赖软件信息 | ||
if (temp_pkl[DEPENDENCIES][key][DEPENDENCIES] !== undefined) { | ||
if (temp_pkl[DEPENDENCIES][key][DEPENDENCIES][module_name] !== undefined) { | ||
temp_pkl[DEPENDENCIES][key][DEPENDENCIES] = struct_delete(temp_pkl[DEPENDENCIES][key][DEPENDENCIES],module_name) | ||
} | ||
if (struct_length(temp_pkl[DEPENDENCIES][key][DEPENDENCIES]) === 0){ | ||
temp_pkl[DEPENDENCIES][key] = struct_delete(temp_pkl[DEPENDENCIES][key],DEPENDENCIES) | ||
} | ||
} | ||
//修改dependencies部分配置 | ||
for (const key in temp_pkl[DEPENDENCIES]) { | ||
if (key === module_name) { | ||
temp_pkl[DEPENDENCIES][key] = dependencies_data; | ||
flag = true; | ||
} | ||
//更改requires中的依赖版本 | ||
if (temp_pkl[DEPENDENCIES][key][REQUIRES] !== undefined) { | ||
if (temp_pkl[DEPENDENCIES][key][REQUIRES][module_name] !== undefined) { | ||
temp_pkl[DEPENDENCIES][key][REQUIRES][module_name] = module_tag; | ||
} | ||
if (flag) { | ||
flag = false | ||
} else { | ||
console.error('project路径下package-lock.json解析dependencies出错,',project_path) | ||
return | ||
} | ||
//去除可能存在的第二层dependencies中的依赖软件信息 | ||
if (temp_pkl[DEPENDENCIES][key][DEPENDENCIES] !== undefined) { | ||
if ( | ||
temp_pkl[DEPENDENCIES][key][DEPENDENCIES][module_name] !== undefined | ||
) { | ||
temp_pkl[DEPENDENCIES][key][DEPENDENCIES] = struct_delete( | ||
temp_pkl[DEPENDENCIES][key][DEPENDENCIES], | ||
module_name | ||
); | ||
} | ||
//修改packages部分配置 | ||
if (temp_pkl[LOCKFILEVERSION] ===2 && temp_pkl[PACKAGES] !== undefined && packages_data !== undefined) { | ||
if (temp_pkl[PACKAGES][''][DEPENDENCIES][module_name] !== undefined){ | ||
temp_pkl[PACKAGES][''][DEPENDENCIES][module_name] = module_tag | ||
flag = true | ||
} | ||
for (const key in temp_pkl[PACKAGES]) { | ||
if (key === packages_name) { | ||
temp_pkl[PACKAGES][key] = packages_data | ||
flag = true | ||
} | ||
if (temp_pkl[PACKAGES][key][DEPENDENCIES] !== undefined) { | ||
if (temp_pkl[PACKAGES][key][DEPENDENCIES][module_name] !== undefined) { | ||
temp_pkl[PACKAGES][key][DEPENDENCIES][module_name] = module_tag | ||
} | ||
} | ||
} | ||
if (!flag) { | ||
console.error('temp路径下package-lock.json解析packages出错,',project_path) | ||
return | ||
} | ||
if (struct_length(temp_pkl[DEPENDENCIES][key][DEPENDENCIES]) === 0) { | ||
temp_pkl[DEPENDENCIES][key] = struct_delete( | ||
temp_pkl[DEPENDENCIES][key], | ||
DEPENDENCIES | ||
); | ||
} | ||
} catch (err) { | ||
console.error('project路径package-lock.json读取失败\n',err) | ||
return | ||
} | ||
} | ||
if (flag) { | ||
flag = false; | ||
} else { | ||
console.error( | ||
"project路径下package-lock.json解析dependencies出错,", | ||
project_path | ||
); | ||
return; | ||
} | ||
//修改后的package-lock配置信息写回目标项目文件 | ||
try{ | ||
fs.writeFileSync(project_path,JSON.stringify(temp_pkl,null,2)+'\n') | ||
}catch (err){ | ||
console.error('project路径package-lock.json写入失败\n',err) | ||
return | ||
//修改packages部分配置 | ||
if ( | ||
temp_pkl[LOCKFILEVERSION] === 2 && | ||
temp_pkl[PACKAGES] !== undefined && | ||
packages_data !== undefined | ||
) { | ||
if (temp_pkl[PACKAGES][""][DEPENDENCIES][module_name] !== undefined) { | ||
temp_pkl[PACKAGES][""][DEPENDENCIES][module_name] = module_tag; | ||
flag = true; | ||
} | ||
for (const key in temp_pkl[PACKAGES]) { | ||
if (key === packages_name) { | ||
temp_pkl[PACKAGES][key] = packages_data; | ||
flag = true; | ||
} | ||
if (temp_pkl[PACKAGES][key][DEPENDENCIES] !== undefined) { | ||
if ( | ||
temp_pkl[PACKAGES][key][DEPENDENCIES][module_name] !== undefined | ||
) { | ||
temp_pkl[PACKAGES][key][DEPENDENCIES][module_name] = module_tag; | ||
} | ||
} | ||
} | ||
if (!flag) { | ||
console.error( | ||
"temp路径下package-lock.json解析packages出错,", | ||
project_path | ||
); | ||
return; | ||
} | ||
} | ||
} catch (err) { | ||
console.error("project路径package-lock.json读取失败\n", err); | ||
return; | ||
} | ||
if (temp_pkl[LOCKFILEVERSION] ===1){ | ||
return 1 | ||
}else if(temp_pkl[LOCKFILEVERSION] ===2){ | ||
return 2 | ||
}else { | ||
console.error('package-lock.json文件配置出错,lockfileVersion不为1或2') | ||
} | ||
//修改后的package-lock配置信息写回目标项目文件 | ||
try { | ||
fs.writeFileSync(project_path, JSON.stringify(temp_pkl, null, 2) + "\n"); | ||
} catch (err) { | ||
console.error("project路径package-lock.json写入失败\n", err); | ||
return; | ||
} | ||
if (temp_pkl[LOCKFILEVERSION] === 1) { | ||
return 1; | ||
} else if (temp_pkl[LOCKFILEVERSION] === 2) { | ||
return 2; | ||
} else { | ||
console.error("package-lock.json文件配置出错,lockfileVersion不为1或2"); | ||
} | ||
} | ||
exports.apkl = apkl | ||
exports.apkl = apkl; |
84
index.js
#!usr/bin/env node | ||
const shell = require('shelljs') | ||
const utils = require('./utils') | ||
const apkl = require('./auto-package-lock').apkl | ||
const path = require('path') | ||
const shell = require("shelljs"); | ||
const utils = require("./utils"); | ||
const apkl = require("./auto-package-lock").apkl; | ||
const path = require("path"); | ||
const args = require('minimist')(process.argv.slice(2), { | ||
string: ["p", "m"] | ||
const args = require("minimist")(process.argv.slice(2), { | ||
string: ["p", "m"], | ||
}); | ||
let exit = false | ||
let exit = false; | ||
if (utils.notExist(args.p)) { | ||
console.error('缺少project路径信息') | ||
exit = true | ||
console.error("缺少project路径信息"); | ||
exit = true; | ||
} | ||
if (utils.notExist(args.m)) { | ||
console.error('缺少module信息') | ||
exit = true | ||
console.error("缺少module信息"); | ||
exit = true; | ||
} | ||
if (exit) { | ||
return | ||
return; | ||
} | ||
shell.cd(args.p) | ||
const project = shell.pwd().stdout | ||
const targetModule = args.m.split('@') | ||
const temp = path.join(__dirname,'temp') | ||
shell.cd(args.p); | ||
const project = shell.pwd().stdout; | ||
const targetModule = args.m.split("@"); | ||
const temp = path.join(__dirname, "temp"); | ||
const project_path = path.join(project,'package-lock.json') | ||
const temp_path = path.join(temp,'package-lock.json') | ||
const project_path = path.join(project, "package-lock.json"); | ||
const temp_path = path.join(temp, "package-lock.json"); | ||
//temp目录npm安装module以取得配置信息 | ||
shell.cd(temp) | ||
shell.exec(`npm install ${args.m}`) | ||
shell.exec(`npm install --package-lock-only --ignore-scripts`) | ||
shell.cd(temp); | ||
shell.exec(`npm install ${args.m}`); | ||
shell.exec(`npm install --package-lock-only --ignore-scripts`); | ||
//目标project生成package-lock.json | ||
shell.cd(project) | ||
shell.exec(`npm install --no-save`) | ||
shell.exec(`npm install --package-lock-only --ignore-scripts`) | ||
shell.cd(project); | ||
shell.exec(`npm install --no-save`); | ||
shell.exec(`npm install --package-lock-only --ignore-scripts`); | ||
//修改目标project中package-lock.json配置 | ||
const result = apkl(temp_path,project_path,targetModule) | ||
if (result === undefined){ | ||
return | ||
const result = apkl(temp_path, project_path, targetModule); | ||
if (result === undefined) { | ||
return; | ||
} | ||
//temp目录npm卸载module | ||
shell.cd(temp) | ||
shell.exec(`npm uninstall ${targetModule[0]}`) | ||
shell.cd(temp); | ||
shell.exec(`npm uninstall ${targetModule[0]}`); | ||
if (result === 1){ | ||
//目标project更新npm install | ||
shell.cd(project) | ||
shell.exec(`npm install --no-save`) | ||
console.log('\npackage-lock配置成功') | ||
console.log('使用npm v6及以下版本,后续请务必使用npm install --no-save') | ||
}else { | ||
//目标project更新npm install | ||
shell.cd(project) | ||
shell.exec(`npm install`) | ||
console.log('\npackage-lock配置成功') | ||
console.log('使用npm v7及以上版本,后续可使用npm install --no-save 或直接使用 npm install') | ||
if (result === 1) { | ||
//目标project更新npm install | ||
shell.cd(project); | ||
shell.exec(`npm install --no-save`); | ||
console.log("\npackage-lock配置成功"); | ||
console.log("使用npm v6及以下版本,后续请务必使用npm install --no-save"); | ||
} else { | ||
//目标project更新npm install | ||
shell.cd(project); | ||
shell.exec(`npm install`); | ||
console.log("\npackage-lock配置成功"); | ||
console.log( | ||
"使用npm v7及以上版本,后续可使用npm install --no-save 或直接使用 npm install" | ||
); | ||
} |
{ | ||
"name": "auto-package-lock", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "", | ||
"main": "index.js", | ||
"bin": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"format": "prettier --write ../auto-package-lock" | ||
}, | ||
"author": "", | ||
"license": "ISC", | ||
"author": "Alan_scut", | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/Alanscut/auto-package-lock" | ||
}, | ||
"dependencies": { | ||
"minimist": "^1.2.6", | ||
"prettier": "^2.6.2", | ||
"shelljs": "^0.8.5" | ||
} | ||
} |
## 背景 | ||
1. 项目A安装了依赖软件B,B项目内自己依赖了上游库C。 | ||
2. 现C出现了CVE漏洞,社区发布了新版本修补了漏洞。 | ||
3. 但是B并未发布新版本引入C的无漏洞版本。 | ||
4. A想要避免项目中出现C的漏洞,但无法简单通过`npm install C@4.0.7`命令安装指定版本,因为在package.json中A只与B有依赖关系。 | ||
5. 因此需要手动修改A项目中的package-lock.json文件 | ||
1. 项目 A 安装了依赖软件 B,B 项目内自己依赖了上游库 C。 | ||
2. 现 C 出现了 CVE 漏洞,社区发布了新版本修补了漏洞。 | ||
3. 但是 B 并未发布新版本引入 C 的无漏洞版本。 | ||
4. A 想要避免项目中出现 C 的漏洞,但无法简单通过`npm install C@4.0.7`命令安装指定版本,因为在 package.json 中 A 只与 B 有依赖关系。 | ||
5. 因此需要手动修改 A 项目中的 package-lock.json 文件 | ||
## 用法 | ||
1. 使用npm安装`npm install -g auto-package-lock`,或克隆项目(下载release包)到本地 | ||
2. 使用npx运行工具`npx auto-package-lock -p 目标项目路径 -m 指定的库名及版本` | ||
3. 如果克隆项目本地,将npx后面的参数指向本地工具项目地址`npx ./auto-package-lock` | ||
1. 使用 npm 安装`npm install -g auto-package-lock`,或克隆项目(下载 release 包)到本地 | ||
2. 使用 npx 运行工具`npx auto-package-lock -p 目标项目路径 -m 指定的库名及版本` | ||
3. 如果克隆项目本地,将 npx 后面的参数指向本地工具项目地址`npx ./auto-package-lock` | ||
@@ -21,3 +22,3 @@ 举例: | ||
1. npm版本为v6及以下的项目,后续请务必使用`npm install --no-save`安装依赖。 | ||
2. npm版本为v7及以上的项目,后续请使用`npm install`安装依赖 | ||
1. npm 版本为 v6 及以下的项目,后续请务必使用`npm install --no-save`安装依赖。 | ||
2. npm 版本为 v7 及以上的项目,后续请使用`npm install`安装依赖 |
@@ -0,0 +0,0 @@ { |
37
utils.js
@@ -1,26 +0,25 @@ | ||
function notExist(str){ | ||
return str === undefined || str === "" | ||
function notExist(str) { | ||
return str === undefined || str === ""; | ||
} | ||
function struct_length(struct){ | ||
let num = 0 | ||
for (const structKey in struct) { | ||
num++ | ||
} | ||
return num | ||
function struct_length(struct) { | ||
let num = 0; | ||
for (const structKey in struct) { | ||
num++; | ||
} | ||
return num; | ||
} | ||
function struct_delete(struct, name){ | ||
let temp = {} | ||
for (const key in struct) { | ||
if (key !== name){ | ||
temp[key] = struct[key] | ||
} | ||
function struct_delete(struct, name) { | ||
let temp = {}; | ||
for (const key in struct) { | ||
if (key !== name) { | ||
temp[key] = struct[key]; | ||
} | ||
return temp | ||
} | ||
return temp; | ||
} | ||
exports.notExist = notExist | ||
exports.struct_length = struct_length | ||
exports.struct_delete = struct_delete | ||
exports.notExist = notExist; | ||
exports.struct_length = struct_length; | ||
exports.struct_delete = struct_delete; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
1
1
24
1
10511
3
7
243
1
+ Addedprettier@^2.6.2
+ Addedprettier@2.8.8(transitive)