Skip to content

Commit

Permalink
feat: 重建record记录的格式
Browse files Browse the repository at this point in the history
  • Loading branch information
likun7981 committed May 21, 2022
1 parent a0dec21 commit a97d108
Show file tree
Hide file tree
Showing 12 changed files with 123 additions and 38 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ node_modules
/lib/
destDir*
/.hlink
/hlink
sourceDir*
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
"cp": "cp src/hlink.config.tpl lib/hlink.config.tpl",
"build": "npm run clean && tsc && npm run cp",
"prepublishOnly": "npm run build",
"rm": "rm /usr/local/bin/hlink ",
"env": "npm run rm && 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:next": "np --tag=next --any-branch --no-cleanup --no-tests --no-yarn",
"postinstall": "hlink rebuild"
},
"files": [
"lib"
Expand Down
22 changes: 22 additions & 0 deletions src/bins/rebuild.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { fileRecord, newFileRecord } from '../paths.js'
import { findParent } from '../utils.js'

async function rebuild() {
if (await fileRecord.exist()) {
fileRecord.backup()
try {
const newRecord = fileRecord.read().map(item => {
return {
inode: item.inode,
dest: findParent(item.dest),
source: findParent(item.source)
}
})
newFileRecord.write(newRecord)
} catch (e) {
fileRecord.restore()
}
}
}

export default rebuild;
15 changes: 1 addition & 14 deletions src/bins/rm/deleteEmptyDir.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
import { execa } from 'execa'
import path from 'path'
import { findParent } from '../../utils.js'

function findParent(_paths: string[]) {
let paths = [..._paths]
if (!paths.length) return ''
paths = paths.sort(
(a, b) => a.split(path.sep).length - b.split(path.sep).length
)
const firstItem = paths.shift() as string
let dirname = path.join(path.dirname(firstItem), '/')
while (!paths.every(p => p.includes(dirname))) {
dirname = path.join(path.dirname(dirname), '/')
}
return dirname
}

async function deleteEmptyDir(dir: string | string[]) {
if (Array.isArray(dir)) {
Expand Down
5 changes: 5 additions & 0 deletions src/cli-dev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env node

process.env.NODE_ENV = 'development'

import('./cli.js')
4 changes: 4 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import chalk from 'chalk'
import meow from 'meow'
import rm from './bins/rm/index.js'
import { restore, backup } from './bins/qnap.js'
import rebuild from './bins/rebuild.js'
import hlink from './bins/main/index.js'
import { log } from './utils.js'

Expand Down Expand Up @@ -79,6 +80,9 @@ switch (_command) {
case 'restore':
restore(inputs[0])
break
case 'rebuild':
rebuild();
break
case 'remove':
case 'rm':
rm(inputs, {
Expand Down
37 changes: 33 additions & 4 deletions src/config/Config.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import { execa } from 'execa'
import fs from 'fs-extra'
import path from 'path'
import os from 'os'
import { hlinkHomeDir } from '../paths.js'
import { checkPathExist } from '../utils.js'

class Config<T extends Array<any> | Record<string, any>> {
private jsonPath: string
private backupPath: string
private saveDir: string
private defaultValue: T
private cacheRead?: T
private timeoutHandle?: NodeJS.Timeout
constructor(filename: string, defaultValue: T, saveDir?: string) {
saveDir = saveDir || path.join(os.homedir(), '.hlink')
saveDir = saveDir || hlinkHomeDir
if (process.env.NODE_ENV === 'development') {
saveDir = path.resolve('hlink')
}
this.jsonPath = path.join(saveDir, filename)
this.backupPath = this.jsonPath + '_backup'
this.saveDir = saveDir
this.defaultValue = defaultValue
}
Expand All @@ -20,13 +27,13 @@ class Config<T extends Array<any> | Record<string, any>> {
fs.ensureDirSync(saveDir)
}
this.cacheRead = content
if(this.timeoutHandle) {
if (this.timeoutHandle) {
clearTimeout(this.timeoutHandle)
}
this.timeoutHandle = setTimeout(() => {
this.cacheRead = undefined
fs.writeJSONSync(this.jsonPath, content, {
spaces: 2
spaces: 0
})
}, 20)
}
Expand All @@ -43,6 +50,28 @@ class Config<T extends Array<any> | Record<string, any>> {
this.cacheRead = fs.readJSONSync(mapJson)
return fs.readJSONSync(mapJson)
}

async backup() {
if (!(await this.exist(true)) && (await this.exist())) {
try {
await execa('cp', [this.jsonPath, this.backupPath])
await execa('rm', [this.jsonPath])
} catch (e) {}
}
}

async restore() {
if (await this.exist(true)) {
try {
execa('cp', [this.backupPath, this.jsonPath])
await execa('rm', [this.backupPath])
} catch(e) {}
}
}

async exist(backup: boolean = false): Promise<boolean> {
return checkPathExist(backup ? this.backupPath : this.jsonPath, true)
}
}

export default Config
34 changes: 17 additions & 17 deletions src/config/recordHelp.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fileRecord, RecordType } from '../paths.js'
import { fileRecord, RecordType } from '../paths.js';
import { makeOnly } from '../utils.js'

export function saveFileRecord(
Expand Down Expand Up @@ -29,26 +29,26 @@ export function saveFileRecord(
fileRecord.write(records)
}

function filter(records: RecordType[], pathOrNumber: string): RecordType[] {
if (Number.isNaN(Number(pathOrNumber))) {
function filter(records: RecordType[], pathOrINode: string): RecordType[] {
if (Number.isNaN(Number(pathOrINode))) {
return records.filter(
({ source, dest }) =>
makeOnly([...source, ...dest]).indexOf(pathOrNumber) === -1
makeOnly([...source, ...dest]).indexOf(pathOrINode) === -1
)
} else {
return records.filter(({ inode }) => inode !== pathOrNumber)
return records.filter(({ inode }) => inode !== pathOrINode)
}
}

export function deleteRecord(filePathOrNumber: string | string[]) {
export function deleteRecord(filepathOrINode: string | string[]) {
let records = fileRecord.read()

if (Array.isArray(filePathOrNumber)) {
filePathOrNumber.forEach(n => {
if (Array.isArray(filepathOrINode)) {
filepathOrINode.forEach(n => {
records = filter(records, n)
})
} else {
records = records = filter(records, filePathOrNumber)
records = records = filter(records, filepathOrINode)
}

fileRecord.write(records)
Expand All @@ -58,16 +58,16 @@ type FindResultType = { files: string[]; inodes: string[] }

function find(
records: RecordType[],
pathOrNumber: string,
pathOrINode: string,
delAll: boolean
): FindResultType {
const inodes: string[] = []
const files = makeOnly(
records.reduce((result, { source, dest, inode }) => {
if (
Number.isNaN(Number(pathOrNumber))
? makeOnly([...source, ...dest]).indexOf(pathOrNumber) > -1
: inode === pathOrNumber
Number.isNaN(Number(pathOrINode))
? makeOnly([...source, ...dest]).indexOf(pathOrINode) > -1
: inode === pathOrINode
) {
inodes.push(inode)
result = result.concat(dest)
Expand All @@ -86,12 +86,12 @@ function find(
}

export function findFilesFromRecord(
filePathOrNumber: string | string[],
filepathOrINode: string | string[],
delAll: boolean = false
) {
const record = fileRecord.read()
if (Array.isArray(filePathOrNumber)) {
return filePathOrNumber.reduce(
if (Array.isArray(filepathOrINode)) {
return filepathOrINode.reduce(
(result, file) => {
const re = find(record, file, delAll)
result.files = result.files.concat(makeOnly(re.files))
Expand All @@ -101,6 +101,6 @@ export function findFilesFromRecord(
{ files: [], inodes: [] } as FindResultType
)
} else {
return find(record, filePathOrNumber, delAll)
return find(record, filepathOrINode, delAll)
}
}
3 changes: 3 additions & 0 deletions src/paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ export const cacheRecord = new Config<Array<string>>('cache-array.json', [])

export type RecordType = { source: string[]; dest: string[], inode: string }
export const fileRecord = new Config<RecordType[]>('files.json', [])

export type newRecordType = { source: string; dest: string, inode: string }
export const newFileRecord = new Config<newRecordType[]>('record-files.json', [])
2 changes: 2 additions & 0 deletions src/types/inquirer.confirm.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ interface IConfig {
default?: boolean
}

type IDone = (answer: boolean) => void;

declare module '@inquirer/confirm' {
export default function confirm(config: IConfig, done?: IDone): Promise<boolean>
}
27 changes: 27 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,30 @@ export async function rmFiles(files: string[]) {
}
return
}

/**
*
* @param _paths 路劲集合
* @returns 返回_paths的公共父目录
*
* _paths = ['/a/c/d/e', '/a/b/c/d/e']
* result = '/a/'
*
*/
export function findParent(_paths: string[]) {
let paths = [..._paths]
if (!paths.length) return ''
/**
* 排序,把最短的路劲排到最前面
*/
paths = paths.sort(
(a, b) => a.split(path.sep).length - b.split(path.sep).length
)
const firstItem = paths.shift() as string // 这里必有
let dirname = path.join(path.dirname(firstItem), '/')
// 如果paths里面每个都包含了最短路劲,说明最短路劲就算所有路劲的目录了
while (!paths.every(p => p.includes(dirname))) {
dirname = path.join(path.dirname(dirname), '/')
}
return dirname
}
5 changes: 3 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"include": ["src", "src/types/*"],
"include": ["src"],
"exclude": ["test", "example"],
"compilerOptions": {
"module": "esnext",
Expand All @@ -12,6 +12,7 @@
"lib": ["esnext", "DOM"],
"moduleResolution": "node",
"outDir": "lib",
"skipLibCheck": true
"skipLibCheck": true,
"resolveJsonModule": true
}
}

0 comments on commit a97d108

Please sign in to comment.