阅读 242

node实现比较git两个不同分支的组件差异(新增、删除、更新)及获取组件版本号????????????,踩坑之旅!!!

引言

大家好,我是学习了吗,我给大家分享使用node比较git分支差异和踩坑过程中的解决思路,希望大家在类似的需求上面可以迎刃而解和帮助到大家

如何在node中执行git命令

查看git方法是否有比较两个分支差异的方法

git diff [<options>] <commit>…<commit> [--] [<path>…] 复制代码

问题:如何在node中执行该命令行

node内置库child_process

child_process中有个方法可以执行命令行

方法一

child_process.spawn()

const spawn = require("child_process").spawn; const ret = await spawn('git', ['diff', '1.0.1.4', '1.0.1.5', '--stat'], {     cwd: process.cwd(),     stdio: "inherit", }); 复制代码

方法二

child_process.exec()

const cmdStr = `git diff 1.0.1.4 1.0.1.5 --stat`; const exec = require("child_process").execSync; const ret = exec(cmdStr) 复制代码

stat参数的作用是,只获取文件的变化,不会具体到文件中内容的差异

获取变更的组件名

不同的项目中目录不同,实现原理是使用正则匹配对应路径中是组件的名称,并使用数组存储起来

有些项目可以是把不同类型的组件放在一个文件下形成组件库,只需要比较组件库的变更就行,同理,使用正则匹配对应的组件库,但是有一种情况需要考虑,使用diff获取的路径中不存在组件库名称,需要我们反解析

遍历文件获取组件库中的组件

数据格式 {组件库: [组件,组件]}

技术glob

   require("glob")(`${paths}/*`, (err, files) => {      // 存储对象      let pkgNameObj = {};      // 使用glob返回的paths路径下的第一层文件,为组件库      files.forEach((item) => {           // 获取组件库名生成新链接           let pkgName = getPkgName(item)[0];           let nowPath = path.resolve(paths, pkgName + "\\components");           pkgNameObj[pkgName] = [];           let nowfiles = require("glob").sync(`${nowPath}/*`);           //遍历对应组件库的组件           nowfiles.forEach((nowItem) => {             let cmpName = getCmpName(nowItem)[0];             pkgNameObj[pkgName].push(cmpName);           });           resolve(pkgNameObj);         });     }); 复制代码

反解析

通过diff获取的路径,通过正则拿不到组件库名称,但是获取的到组件名,通过上一步骤得到的组件库与组件的映射关系来获取组件库名

注意

不同的分支下相同的组件可能修改了不同地方,通过diff获取的路径可能有相同的组件名,需要去重

获取不同分支下相同组件的版本号变更

方法一

思路

  • 存储当前分支

  • 新建对象,存储版本号

  • 通过命令行切换分支,然后读取组件下的版本号

  • 第一个分支读取完成后,又切换到第二个分支上,读取组件版本号

  • 切回到原分支

使用上面所说的child_process执行切换分支命令行

这个方法比较简单不细说了

注意

如果当前分支有代码未提交,通过命令行切换分支会报错,提示有修改的内容未提交不能切换

方法二

思路

  • 直接在本地获取其他分支下组件的内容、版本号

git restore获取其他分支内容

git restore -s [branch] -- [path]

执行完这个命令之后,此时在当前分支下,path下的文件的还没有处于「暂存」(staged)状态。 该分支下已经有已修改的状态,需求我们获取完版本号后重置更改,也是该命令行

  1. 当前分支没有path下的组件文件夹和文件名,需要创建

  2. 创建文件夹后,使用restore重置更改,报错

  3. 使用fs.unlink删除文件夹,告诉我没有权限

  4. 既然fs.unlink不行,那我就直接删除我创建的文件夹,使用rmdir,本以为也会删除该文件夹下的文件名,抱歉,是我想多了,必须删除完该文件夹下的所有文件才能删除

问题2 出现的原因

当发现当前分支没有其他分支的文件夹时,在当前分支创建,但是获取第二个分支的当前文件夹时,执行命令行git restore拿不到文件会直接报错

代码

function openCommand(command) {     var exec = require("child_process").execSync;     return exec(command);  }  function delFile(path, reservePath) {     if (fs.existsSync(path)) {       if (fs.statSync(path).isDirectory()) {         let files = fs.readdirSync(path);         files.forEach((file, index) => {           let currentPath = path + "/" + file;           if (fs.statSync(currentPath).isDirectory()) {             delFile(currentPath, reservePath);           } else {             fs.unlinkSync(currentPath);           }         });         if (path != reservePath) {           fs.rmdirSync(path);         }       } else {         fs.unlinkSync(path);       }     }   }  // 写在一个类中,其中this指向实例 let paths = path.resolve(process.cwd(), `uicomponents/src/componentlibs/${item}/libSetting.json`);     if (pathExists(paths)) {       let nowData;       // 问题2 需要try catch捕获 这种情况是传参第二个参数没有对应的组件库       try {         await this.openCommand(`git restore -s ${branch} -- uicomponents/src/componentlibs/${item}/libSetting.json`);         nowData = fs.readFileSync(path.resolve(process.cwd(), `uicomponents/src/componentlibs/${item}/libSetting.json`));         // 直接还原文件夹更改         // 问题:当前分支没有该文件夹会直接报错         if (this.createDirPath[item]) {           // 不能直接删除文件夹,必须先删除文件夹中对应的文件然后才能删除           this.delFile(this.createDirPath[item]);         } else {           await this.openCommand(`git restore uicomponents/src/componentlibs/${item}/libSetting.json`);         }       } catch (e) {         // 首先判断的第一个分支有代码库,本分支创建了文件夹,获取第二个分支没有该代码库,就会报错         // 所以在这里也要删除新建的文件夹         if (this.createDirPath[item]) {           // 不能直接删除文件夹,必须先删除文件夹中对应的文件然后才能删除           this.delFile(this.createDirPath[item]);         }         console.log(`当前分支${branch}没有代码库${item}`);       }       return nowData && JSON.parse(nowData.toString()).version;     } else {       // 如果不创建文件夹的话,在当前分支没有该代码块,获取其他分支代码块,会报错找不到该文件夹,如果用try catch 就比较不了两个分支的版本差异,直接undefined       let paths = path.resolve(process.cwd(), `uicomponents/src/componentlibs/${item}`);       let createOk = this.createDir(paths);       // 这样存储目录的目的是,可能新的分支创建了多个代码块,所以使用对象存储代码库的名称和对应的目录地址,方便删除       createOk && (this.createDirPath[item] = paths);       if (createOk) {         let paths = path.resolve(process.cwd(), `uicomponents/src/componentlibs/${item}/libSetting.json`);         fs.writeFileSync(paths, "{}");         if (pathExists(paths)) {           // 比较的两个分支有新建代码库,但是某个分支没有该代码库,但是已经新建了文件夹           // 当前分支获取其他其他分支的当前文件时拿不到路径会直接报错           // 这种情况是传参的第一个分支中没有对应的组件库           try {             await this.openCommand(`git restore -s ${branch} -- uicomponents/src/componentlibs/${item}/libSetting.json`);             let nowData = fs.readFileSync(path.resolve(process.cwd(), `uicomponents/src/componentlibs/${item}/libSetting.json`));             // await this.openCommand(`git restore uicomponents/src/componentlibs/${item}/libSetting.json`);             return JSON.parse(nowData.toString()).version;           } catch (e) {             return undefined;           }         }       }     }


作者:不学习吗
链接:https://juejin.cn/post/7025404534335733797


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐