forked from likun7981/hlink
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
24 changed files
with
292 additions
and
300 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 删除前是否需确认? 默认需要确认。 | ||
如果你使用计划任务,建议设置为无需确认 | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.