Skip to content

Commit

Permalink
feat: add prune
Browse files Browse the repository at this point in the history
  • Loading branch information
likun7981 committed May 22, 2022
1 parent fbbf7c3 commit dcb6a29
Show file tree
Hide file tree
Showing 24 changed files with 292 additions and 300 deletions.
54 changes: 54 additions & 0 deletions docs/prune.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@

# hlink prune

## 详细说明
该命令翻译过来就是**修剪**,使用场景只有一个,**在源文件被删除了,但是硬链忘记删了。**
那么你使用该命令,hlink会帮你检测你指定的源文件目录和硬链目录文件做对比。
**筛选出来 硬链目录有的文件,但是源文件已删除的文件**
因为我们要检测所有对应关系,所以建议你列全所有的 源目录及硬链目录


## 举例

比如你的源目录有
- download
- download2

比如你的源目录有
- 电影
- 电视剧
- 动漫

硬链和源文件应该是一一对应的,如果所以你要这样使用该命令:

1. 检查所有的硬链目录
```bash
hlink prune /path/to/download,/path/to/download2 /path/to/电影,/path/to/电视剧,/path/to/动漫
```

当然你也可以 **检测部分硬链目录** 像下面这样

2. 检测部分

```bash
hlink /path/to/download,/path/to/download2 /path/to/电影
```

因为 prune 的作用是 寻找 **源目录没有而硬链目录有的情况,所以我建议你源目录一定一定列全量**,否则可能存在下面的情况:

源目录1 -> 硬链目录1
源目录2 -> 硬链目录2

如果你这时候只告诉hlink 部分源目录,比如源目录1
```bash
hlink prune /path/to/源目录1 /path/to/硬链目录1,/path/to/硬链目录2
```

那这样造成的结果就会检测出来 **硬链目录2** 的文件,全部都找不到,全都会被修剪掉,因为它里面的文件全是从 **源目录2** 来的。

所以你自己无法确认对应关系,那么建议你 **源目录一定一定要列全,硬链目录则可以随意**

更多使用配置可以见`hlink prune --help`

以上就是对 `hlink prune` 的所有介绍,有问题可以群里咨询

File renamed without changes.
9 changes: 4 additions & 5 deletions hlink.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/**
*
* !!!重要提醒:这是开发时使用的调试配置文件,不要直接使用,
Expand All @@ -12,11 +11,11 @@ export default {
/**
* 源地址
*/
source: '/Users/likun/Projects/github/hlink/node_modules',
source: '/Users/likun/Code/my-github/hlink/sourceDir1',
/**
* 目标地址
*/
dest: '/Users/likun/Projects/github/hlink/destDir88',
dest: '/Users/likun/Code/my-github/hlink/destDir1',
/**
* 需要包含的后缀名,如果不配置该项,会采用以下策略
* 1. 配置了excludeExtname,则链接文件为排除后的其他文件
Expand All @@ -42,6 +41,6 @@ export default {
*/
saveMode: 0,
openCache: false,
mkdirIfSingle: true,
delete: true,
mkdirIfSingle: false,
delete: true
}
6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hlink",
"version": "0.6.3-test.4",
"version": "0.6.3-test.6",
"description": "hlink",
"license": "MIT",
"repository": "likun7981/hlink",
Expand All @@ -26,9 +26,7 @@
"env": "ln -s $PWD/lib/cli-dev.js /usr/local/bin/hlink && chmod +x ./lib/cli-dev.js",
"np": "np --no-cleanup --no-tests --no-yarn",
"np:beta": "np --tag=beta --any-branch --no-cleanup --no-tests --no-yarn",
"np:next": "np --tag=next --any-branch --no-cleanup --no-tests --no-yarn",
"np:test": "np --tag=test --any-branch --no-cleanup --no-tests --no-yarn",
"postinstall": "chmod +x $PWD/lib/doctor.js && $PWD/lib/doctor.js"
"np:next": "np --tag=next --any-branch --no-cleanup --no-tests --no-yarn"
},
"files": [
"lib"
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ $ hlink --help
<img src="https://user-images.githubusercontent.com/13427467/148171766-ccbe2a1a-c30c-4e1a-868c-4e2c69617d29.png" width="520"/>

## 教程
- [威联通开机启动添加环境变量](./qnap.md)
- [威联通开机启动添加环境变量](./docs/qnap.md)

## 更新日志
- [新版本0.6.x改动](https://github.com/likun7981/hlink/pull/42)
Expand Down
47 changes: 47 additions & 0 deletions src/bins/doctor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env node
import chalk from 'chalk'
import { execaSync } from 'execa'
import path from 'path'
import { fileURLToPath } from 'url'
import fs from 'fs-extra'
import { log } from '../utils.js'

const currentDir = path.resolve(fileURLToPath(import.meta.url), '../..')
const cli = process.env.NODE_ENV === 'development' ? 'cli-dev.js' : 'cli.js'
function check() {
execaSync('type', ['hlink'])
log.info('如果看到这个消息,说明hlink已经安装成功并已经添加到环境变量中')
log.info(`你可以使用 ${chalk.cyan('hlink --help')} 查看帮助文档`)
log.info(`有任何问题,还原到qq群反馈,群号${chalk.cyan('807101297')}`)
}

function doctor() {
try {
check()
} catch (e) {
log.warn('检查到hlink没有添加到环境变量中, 开始为你自动添加')
try {
fs.ensureDirSync('/usr/local/bin')
execaSync('ln', [
'-s',
path.resolve(currentDir, cli),
'/usr/local/bin/hlink'
])
execaSync('chmod', ['+x', path.resolve(currentDir, cli)])
log.success('添加到环境变量成功~')
check()
} catch (e) {
console.log(e)
// 自动创建hlink硬链失败
log.error('抱歉添加hlink到环境变量失败了,请手动添加~')
log.info('如何添加环境变量请自行搜索~')
let full = currentDir
log.info(
'或者你可以全局路劲使用hlink, 路劲为',
chalk.cyan(path.resolve(full, '../../../../bin/hlink'))
)
}
}
}

export default doctor
5 changes: 0 additions & 5 deletions src/bins/index.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/bins/main/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ QQ反馈群号:${chalk.cyanBright('807101297')}
--mkdirIfSingle,-m 是否为独立文件创建同名文件夹,默认为true,会创建
--openCache,-o 是否打开缓存,默认为true, 会打开
--openCache,-o 是否打开缓存,默认为false, 不会会打开
${chalk.gray('打开后,每次硬链后会把对应文件存入缓存,就算下次删除硬链,也不会进行硬链')}
--configPath,-c 指定配置文件路径,请使用绝对路径
Expand Down
4 changes: 2 additions & 2 deletions src/bins/main/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ function checkSaveMode(saveMode: number) {
)
}

function checkDirectory(source: string, dest: string) {
export function checkDirectory(source?: string, dest?: string) {
warning(!source || !dest, '必须指定原地址和目标地址')
warning(!fs.existsSync(source), '源地址不存在,请检查路径是否正确')
warning(!!source && !fs.existsSync(source), '源地址不存在,请检查路径是否正确')
warning(source === dest, '源地址和目标地址不能相同')
}

Expand Down
File renamed without changes.
29 changes: 29 additions & 0 deletions src/bins/prune/help.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import chalk from 'chalk'

export default `
QQ反馈群号:${chalk.cyanBright('807101297')}
说明:
详细说明见 https://github.com/likun7981/hlink/blob/master/docs/prune.md
注意:
因为我们采用 ${chalk.cyan(',(英文逗号)')} 来进行多项输入。
所以你的路劲一定不要包含 ${chalk.cyan(',(英文逗号)')}
否则会导致未知错误,后果自负~
用法:
${chalk.gray('# 修剪多余硬链文件')}
$ hlink prune sourceDir1,sourceDir2 destDir1,destDir2
${chalk.gray('# 修剪多余硬链所在目录')}
$ hlink prune -p sourceDir1,sourceDir2 destDir1,destDir2
${chalk.gray('# 修剪时无需确认,一般使用于计划任务')}
$ hlink prune -w sourceDir1,sourceDir2 destDir1,destDir2
可配置选项:
--pruneDir,-p 是否删除硬链文件及所在目录。
如果给了这个选项则会 否则只会删除 硬链文件
--withoutConfirm,-w 删除前是否需确认? 默认需要确认。
如果你使用计划任务,建议设置为无需确认
`
92 changes: 92 additions & 0 deletions src/bins/prune/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import chalk from 'chalk'
import path from 'path'
import confirm from '@inquirer/confirm'
import parseLsirf from '../../core/parseLsirf.js'
import { createTimeLog, log, makeOnly, rmFiles, warning } from '../../utils.js'
import helpText from './help.js'

const timeLog = createTimeLog()
export type Flags = Pick<IHlink.Flags, 'help' | 'pruneDir' | 'withoutConfirm'>

async function prune(sourceStr: string, destStr: string, flags: Flags) {
const { help, pruneDir, withoutConfirm } = flags
if (help) {
console.log(helpText)
process.exit(0)
}
warning(!sourceStr || !destStr, '必须指定要检测的源目录和硬链目录集合')
timeLog.start()
const sourceArr = sourceStr.split(',').map((s) => path.resolve(s))
const destArr = destStr.split(',').map((d) => path.resolve(d))
log.info('开始执行...')
log.info('指定的源目录有:')
sourceArr.forEach(s => {
console.log('', chalk.gray(s))
})
console.log()
log.info('指定的硬链目录有:')
destArr.forEach(d => {
console.log('', chalk.gray(d))
})
console.log()
log.info(
'删除模式:',
chalk.magenta(pruneDir ? '删除硬链所在目录' : '仅仅删除硬链文件')
)
log.info('开始分析目录集合...')
const inodes = makeOnly(
sourceArr.reduce<string[]>(
(result, source) =>
result.concat(parseLsirf(source, true).map(a => a.inode)),
[]
)
)
let pathsNeedDelete = makeOnly(
destArr.reduce<string[]>(
(result, dest) =>
result.concat(
parseLsirf(dest, true)
.filter(item => !inodes.includes(item.inode))
.map(item =>
pruneDir
? path.join(path.dirname(item.fullPath), '/')
: item.fullPath
)
),
[]
)
)
log.info('分析完毕')
if (pathsNeedDelete.length) {
// 如果是删除目录,则直接过滤掉二级目录
if (pruneDir) {
pathsNeedDelete = pathsNeedDelete.filter(p1 =>
pathsNeedDelete.every(p2 => !(p1.indexOf(p2) === 0 && p1 !== p2))
)
}
log.info(
`共计找到 ${chalk.cyan(pathsNeedDelete.length)} 个路劲需要删除,列表如下`
)
pathsNeedDelete.forEach(file => {
console.log('', chalk.gray(file))
})
console.log()
let answer = true
if (!withoutConfirm) {
answer = await confirm({
message: '确认是否继续?删除后无法恢复',
default: false
})
}
if (answer) {
await rmFiles(pathsNeedDelete)
log.success('删除完成')
} else {
log.info('已终止任务')
}
} else {
log.info('没有找到需要修剪的硬链,你的目录保持很干净')
}
}

export default prune
32 changes: 0 additions & 32 deletions src/bins/rebuild.ts

This file was deleted.

30 changes: 0 additions & 30 deletions src/bins/rm/help.ts

This file was deleted.

26 changes: 0 additions & 26 deletions src/bins/rm/index.ts

This file was deleted.

Loading

0 comments on commit dcb6a29

Please sign in to comment.