嗨,大家好!这里是道长王jj
~ 🎩🧙♂️
在当今社交媒体的浸染下,焦虑感似乎无处不在,coder
们经常被各种视频和帖子灌输着高效、快速且毫不费力地编写代码的观念。
比如:“一个下午做出一个微信小程序”,“一个下午搞定业务方案”。
这似乎给了老板们一种错觉,觉得我们写代码的效率也应该像视频里那样高、快、不费吹灰之力。某短视频平台上还有人晒出程序员每天写1000行代码的成绩,仿佛这是标配了。
这种现象直接让我们的可爱老板们也开始感到焦虑了。在网络上,别人一个下午就能完成的工作,为什么现实中需要三天或甚至七天?
更有一种“地狱笑话”是这样说的:“每个程序员每天必须提交至少1000行代码,否则就会被认定为低绩效员工,面临降薪或者开除的风险。”
针对这个笑话,上期我们整活了【定时推送每位研发的代码量到server酱】。
从技术角度来看,这个简单的的脚本确实可以为许多领导和老板提供这类特殊需求的支持。
如果你还不知道如何实现,欢迎查看上一期的整活内容噢!
那既然世界总是难免打工人为难打工人的情况,那我们如何才能在这纷扰的世界进行自保呢?
🕹️1. 脚本前置准备:准备可独立运行的模板文件
首先,我们需要准备一些可以独立运行并且能够通过eslint
检查的代码文件。现在的规范工具都非常严格,如果检测到明显的语法错误,是无法进行提交的。
在这个例子中,我准备了一些工具类函数作为本次实验需要复制的代码文件,放在了src
目录下。
/******************************
* 我这里也举些单独文件的例子
* src/function-utils.js
******************************/
module.exports = {
/**
* 循环遍历包含异步事件的函数数组
* @param {*} fns 例子:[
next => { console.log('0 seconds'); setTimeout(next, 1000); },
next => { console.log('1 second'); setTimeout(next, 1000); },
next => { console.log('2 seconds'); }]
*/
functionChainAsync: fns => {
let curr = 0;
const next = () => {
fns[curr++](next);
};
next();
},
/**
* 转换异步函数的callback返回成promise
* @param func
* @returns {function(...[*]): Promise<unknown>}
*/
functionPromisify: func => {
return (...args) => {
return new Promise((resolve, reject) => {
func(...args, (err, result) => {
err ? reject(err) : resolve(result);
});
});
};
},
/**
* 传入一个函数数组,使每一个函数运行结束后再进入下一个函数
* @param arr 例子:[() => return new Promise, () => return new Promise]
* @returns {*}
*/
functionPromisesInSeries: arr => {
return arr.reduce((previousValue, currentValue) => {
previousValue.then(currentValue);
return Promise.resolve();
});
},
};
🕹️2. 利用fs
库新增代码量
既然我们想要增加代码量,那就让我们调用 Node.js
的强大库 fs
来搞点事情吧!
我们的目标是将一些准备好的文件复制到一个临时文件夹中,这样一来,既不会对仓库本身的代码结构造成影响,又能实现增加代码量的效果。
/******************************
* add-code.cjs
******************************/
// 引入fs模块
const path = require('path');
const fs = require('fs');
const needLoadFilePath = './src'; // 需要加载文件的路径
const TempFolder = './temp'; // 临时文件夹路径
// 定义一个async函数,接收一个文件夹路径作为参数
const readFolder = async (folderPath) => {
try {
// 使用fs.promises.readdir()方法异步地读取文件夹下的所有文件名,并使用await等待结果
const files = await fs.promises.readdir(folderPath);
// 返回文件名数组
return files;
} catch (err) {
// 如果出错,打印错误信息
console.error(err);
}
};
// 读写文件
const fileOperation = async (filePath, content, operation) => {
try {
if (operation === 'write') {
// 如果操作是写入文件,使用fs.promises.writeFile()方法异步地写入文件,并返回Promise对象
return await fs.promises.writeFile(filePath, content);
} else if (operation === 'read') {
// 如果操作是读取文件,使用fs.promises.readFile()方法异步地读取文件内容,并返回Promise对象
return await fs.promises.readFile(filePath, 'utf8');
}
} catch (e) {
console.error(operation + 'File', e);
}
};
const getCode = async (randomFileName) => {
// 获取需要加载的文件的完整路径
const filePath = path.resolve(__dirname, `${needLoadFilePath}/${randomFileName}`);
// 调用fileOperation函数,传入文件路径、空内容和操作类型为读取
return fileOperation(filePath, '', 'read');
};
// 创建新的代码文件
const createRandomFile = async (TempFolder) => {
// 读取需要加载文件的文件名列表
const fileNames = await readFolder(needLoadFilePath);
// 随机选择一个文件名
const randomIndex = Math.floor(Math.random() * fileNames.length);
const randomFileName = fileNames[randomIndex];
// 构建临时文件的完整路径
const filePath = `${TempFolder}/${randomFileName}`;
// 获取文件内容
const content = await getCode(randomFileName);
// 创建临时文件夹,如果已存在则不会重复创建
await fs.promises.mkdir(TempFolder, {
recursive: true });
// 调用fileOperation函数,传入临时文件路径、文件内容和操作类型为写入
fileOperation(filePath, content, 'write');
};
// 调用async函数,并使用then()方法处理返回的Promise对象
const main = () => {
createRandomFile(TempFolder);
};
main();
把上面的代码拷贝复制下来,放在项目的根目录下,创建一个 JS 文件,拷贝上去运行。然后运行它。
你会发现,这段代码能够随机复制我们 src 文件夹下的一个文件到 temp 文件夹中,而 Git 居然也察觉到了我增加了一个文件的代码。
🕹️3. 利用fs
库删除我们刚刚复制的代码
既然我们已经成功增加了代码量,那就让我们来处理一下 temp
这家伙吧!这东西可不能随便提交到我们重要的master
分支,否则就会像泼了一盆墨水在白衬衫上一样污染我们整洁的代码仓库。所以,我们必须来个手动大扫除!
/******************************
* remove-code.cjs
******************************/
// 引入fs模块
const fs = require('fs')
// 引入path模块
const path = require('path')
// 定义要删除的文件夹路径
const dirPath = './temp'
// 定义一个异步函数,用于删除文件夹中的所有文件和子文件夹
async function deleteDir(dir) {
// 读取文件夹中的内容
let files = await fs.promises.readdir(dir)
// 遍历文件数组
for (let file of files) {
// 拼接文件路径
let filePath = path.join(dir, file)
// 判断文件类型
let stats = await fs.promises.stat(filePath)
// 如果是文件,删除文件
if (stats.isFile()) {
await fs.promises.unlink(filePath)
console.log('删除文件:' + filePath)
}
// 如果是文件夹,递归调用函数
if (stats.isDirectory()) {
await deleteDir(filePath)
}
}
// 删除空文件夹
await fs.promises.rmdir(dir)
console.log('删除文件夹:' + dir)
}
// 调用函数,删除整个文件夹
deleteDir(dirPath)
将上面的代码拷贝到我们的项目根目录下的一个js
文件中,并执行它。
你会惊奇地发现,这段代码能够瞬间把我们刚刚复制过来的那个名叫 temp
的文件夹彻底消失!🎩🔮
如果你之前不小心提交了这个 temp
文件夹,别担心!运行这个脚本后,Git 会重新记录一次我们对 temp
文件夹的消失操作🪄💥✨。
🕹️4. 使用shell
进行整合,想要多少代码量都可以。
上面的两个脚本是我们使用shell
的基础。
通过shell
脚本,在新增和删除文件的过程中,循环遍历,不断制造出一系列无意义的提交事件,但对仓库本身没有任何影响(当然啦,肯定会出现提交记录的)!
现在我们可以调整 count
参数,掌控执行脚本的次数,让代码量增加得飞起!🎩🌟✨
让我们直接看代码:
#! /bin/bash
git pull
# 进入脚本所在的目录
cd {
mathJaxContainer[2]}0)
# 执行次数
count=1
# 循环执行
for((i=0;i<$count;i++))
do
node ./add-code.js
git add .
msg="fix: 函数文件调整"
git commit -m "$msg"
node ./remove-code.js
git add .
msg="fix: 删除函数文件调整"
git commit -m "$msg"
git push
done
📊运行效果&源码
到这里,编码部分就全部结束了。
这个时候就应该会看到自己项目的根目录下应该要多出这3个文件。
直接在控制台执行./main,sh
后,您的git提交记录如果运气好的话会出现下面这样的效果:
哇哦,我们只改了一个文件,但是通过巧妙地合并两个提交,git log 居然显示出了大量的代码操作记录,而实际上并没有任何文件的变更。
如果你想亲自运行一遍,但又不想深入研究其中的奥秘,别担心,你可以下载源码到本地,然后尽情玩耍🥰
📌后记
这个问题真的很有意思啊!我特地向某个知名问答平台请教了一下,看看他们有什么建议:
在整活的同时,最最重要的,还是别忘了过好自己的生活哦,下一家更乖。
🎉 希望本次整活儿能够帮助你练习使用Node
和shell
, 并能从中感受到玩代码的乐趣。如果你有任何疑问或者想进一步讨论相关话题,请随时告诉我。🚀✨