UNPKG

@ethersphere/swarm-cli

Version:
88 lines (71 loc) 2.9 kB
import { MantarayNode, MerkleTree } from '@ethersphere/bee-js' import { Binary, Optional } from 'cafe-utility' import chalk from 'chalk' import { readFileSync } from 'fs' import { Argument, LeafCommand, Option } from 'furious-commander' import { join } from 'path' import { pickStamp } from '../../service/stamp' import { readdirDeepAsync } from '../../utils' import { BzzAddress } from '../../utils/bzz-address' import { stampProperties } from '../../utils/option' import { RootCommand } from '../root-command' export class Sync extends RootCommand implements LeafCommand { public readonly name = 'sync' public readonly description = 'Sync a local folder to an existing manifest' @Argument({ key: 'address', description: 'Root manifest reference', required: true }) public bzzUrl!: string @Argument({ key: 'folder', description: 'Local folder to be synced', required: true }) public folder!: string @Option(stampProperties) public stamp!: string @Option({ key: 'remove', type: 'boolean', description: 'Remove paths that do not exist locally', }) public remove!: boolean public async run(): Promise<void> { super.init() if (!this.stamp) { this.stamp = await pickStamp(this.bee, this.console) } const address = new BzzAddress(this.bzzUrl) const node = await MantarayNode.unmarshal(this.bee, address.hash) await node.loadRecursively(this.bee) const map = new Map<string, MantarayNode>() const nodes = node.collect() for (const node of nodes) { map.set(node.fullPathString, node) } const files = await readdirDeepAsync(this.folder, this.folder) for (const file of files) { const existing = map.get(file) if (existing) { const localData = readFileSync(join(this.folder, file)) const rootChunk = await MerkleTree.root(localData) if (Binary.equals(rootChunk.hash(), existing.targetAddress)) { this.console.log(chalk.gray(file) + ' ' + chalk.blue('UNCHANGED')) } else { const { reference } = await this.bee.uploadData(this.stamp, localData) node.addFork(file, reference) this.console.log(chalk.gray(file) + ' ' + chalk.yellow('CHANGED')) } } else { const { reference } = await this.bee.uploadData(this.stamp, readFileSync(join(this.folder, file))) node.addFork(file, reference) this.console.log(chalk.gray(file) + ' ' + chalk.green('NEW')) } } if (this.remove) { for (const n of nodes) { if (!files.includes(node.fullPathString)) { node.removeFork(n.fullPathString) this.console.log(chalk.gray(n.fullPathString) + ' ' + chalk.red('REMOVED')) } } } const root = await node.saveRecursively(this.bee, this.stamp) this.console.log(root.reference.toHex()) this.result = Optional.of(root.reference) } }