{
  "_args": [
    [
      {
        "raw": "fs-tree-diff@^0.5.3",
        "scope": null,
        "escapedName": "fs-tree-diff",
        "name": "fs-tree-diff",
        "rawSpec": "^0.5.3",
        "spec": ">=0.5.3 <0.6.0",
        "type": "range"
      },
      "/home/travis/build/lukesargeant/ember-sparkline/node_modules/broccoli-funnel"
    ]
  ],
  "_from": "fs-tree-diff@>=0.5.3 <0.6.0",
  "_id": "fs-tree-diff@0.5.7",
  "_inCache": true,
  "_location": "/fs-tree-diff",
  "_nodeVersion": "8.6.0",
  "_npmOperationalInternal": {
    "host": "s3://npm-registry-packages",
    "tmp": "tmp/fs-tree-diff-0.5.7.tgz_1508267324367_0.16028631874360144"
  },
  "_npmUser": {
    "name": "rwjblue",
    "email": "me@rwjblue.com"
  },
  "_npmVersion": "5.4.2",
  "_phantomChildren": {},
  "_requested": {
    "raw": "fs-tree-diff@^0.5.3",
    "scope": null,
    "escapedName": "fs-tree-diff",
    "name": "fs-tree-diff",
    "rawSpec": "^0.5.3",
    "spec": ">=0.5.3 <0.6.0",
    "type": "range"
  },
  "_requiredBy": [
    "/@ember/test-helpers/broccoli-funnel",
    "/broccoli-concat",
    "/broccoli-debug",
    "/broccoli-funnel",
    "/broccoli-merge-trees",
    "/broccoli-persistent-filter",
    "/ember-cli",
    "/ember-cli/broccoli-funnel",
    "/ember-qunit/broccoli-funnel",
    "/merge-trees",
    "/tree-sync"
  ],
  "_resolved": "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-0.5.7.tgz",
  "_shasum": "315e2b098d5fe7f622880ac965b1b051868ac871",
  "_shrinkwrap": null,
  "_spec": "fs-tree-diff@^0.5.3",
  "_where": "/home/travis/build/lukesargeant/ember-sparkline/node_modules/broccoli-funnel",
  "author": {
    "name": "Stefan Penner, David J. Hamilton, Chad Hietala"
  },
  "bugs": {
    "url": "https://github.com/stefanpenner/fs-tree-diff/issues"
  },
  "dependencies": {
    "heimdalljs-logger": "^0.1.7",
    "object-assign": "^4.1.0",
    "path-posix": "^1.0.0",
    "symlink-or-copy": "^1.1.8"
  },
  "description": "Backs out file tree changes",
  "devDependencies": {
    "chai": "^3.3.0",
    "fs-extra": "^1.0.0",
    "mocha": "^2.3.3",
    "walk-sync": "^0.3.1"
  },
  "directories": {},
  "dist": {
    "integrity": "sha512-dJwDX6NBH7IfdfFjZAdHCZ6fIKc8LwR7kzqUhYRFJuX4g9ctG/7cuqJuwegGQsyLEykp6Z4krq+yIFMQlt7d9Q==",
    "shasum": "315e2b098d5fe7f622880ac965b1b051868ac871",
    "tarball": "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-0.5.7.tgz"
  },
  "files": [
    "lib"
  ],
  "gitHead": "33b445c387104a3d8eec8f06c64383c7464b36b2",
  "homepage": "https://github.com/stefanpenner/fs-tree-diff#readme",
  "keywords": [
    "broccoli"
  ],
  "license": "MIT",
  "main": "lib/index.js",
  "maintainers": [
    {
      "name": "chadhietala",
      "email": "chadhietala@gmail.com"
    },
    {
      "name": "hjdivad",
      "email": "npm@hjdivad.com"
    },
    {
      "name": "rwjblue",
      "email": "me@rwjblue.com"
    },
    {
      "name": "stefanpenner",
      "email": "stefan.penner@gmail.com"
    }
  ],
  "name": "fs-tree-diff",
  "optionalDependencies": {},
  "readme": "# fs-tree-diff [![Build Status](https://travis-ci.org/stefanpenner/fs-tree-diff.svg?branch=master)](https://travis-ci.org/stefanpenner/fs-tree-diff) [![Build status](https://ci.appveyor.com/api/projects/status/qmhx48hrquq08fam/branch/master?svg=true)](https://ci.appveyor.com/project/embercli/fs-tree-diff/branch/master)\n\n\nFSTree provides the means to calculate a patch (set of operations) between one file system tree and another.\n\nThe possible operations are:\n\n* `unlink` – remove the specified file\n* `rmdir` – remove the specified folder\n* `mkdir` – create the specified folder\n* `create` – create the specified file\n* `change` – update the specified file to reflect changes\n\nThe operations chosen aim to minimize the amount of IO required to apply a given patch.\nFor example, a naive `rm -rf` of a directory tree is actually quite costly, as child directories\nmust be recursively traversed, entries stated.. etc, all to figure out what first must be deleted.\nSince we patch from tree to tree, discovering new files is both wasteful and un-needed.\n\nThe operations will also be provided in a correct order, allowing us to safely\nreplay operations without having to first confirm the FS is as we expect.  For\nexample, `unlink`s for files will occur before a `rmdir` of those files' parent\ndir.  Although the ordering will be safe, a specific order is not guaranteed.\n\nA simple example:\n\n```js\nvar FSTree = require('fs-tree-diff');\nvar current = FSTree.fromPaths([\n  'a.js'\n]);\n\nvar next = FSTree.fromPaths([\n  'b.js'\n]);\n\ncurrent.calculatePatch(next) === [\n  ['unlink', 'a.js', entryA],\n  ['create', 'b.js', entryB]\n];\n```\n\nA slightly more complicated example:\n\n```js\nvar FSTree = require('fs-tree-diff');\nvar current = FSTree.fromPaths([\n  'a.js',\n  'b/',\n  'b/f.js'\n]);\n\nvar next = FSTree.fromPaths([\n  'b.js',\n  'b/',\n  'b/c/',\n  'b/c/d.js',\n  'b/e.js'\n]);\n\ncurrent.calculatePatch(next) === [\n  ['unlink', 'a.js', entryA],\n  ['create', 'b.js', entryB],\n  ['mkdir', 'b/c', entryBC],\n  ['create', 'b/c/d.js', entryBCD],\n  ['create', 'b/e.js', entryBE]\n  ['unlink', 'b/f.js', entryBF],\n]\n```\n\nNow, the above examples do not demonstrate `change` operations. This is because\nwhen providing only paths, we do not have sufficient information to check if\none entry is merely different from another with the same relativePath.\n\nFor this, FSTree supports more complex input structure. To demonstrate, we\nwill use the [walk-sync](https://github.com/joliss/node-walk-sync) module,\nwhich provides higher fidelity input, allowing FSTree to also detect changes.\n(See also the documentation for\n[walkSync.entries](https://github.com/joliss/node-walk-sync#entries).)\n\n```js\nvar walkSync = require('walk-sync');\n\n// path/to/root/foo.js\n// path/to/root/bar.js\nvar current = new FSTree({\n  entries: walkSync.entries('path/to/root')\n});\n\nwriteFileSync('path/to/root/foo.js', 'new content');\nwriteFileSync('path/to/root/baz.js', 'new file');\n\nvar next = new FSTree({\n  entries: walkSync.entries('path/to/root')\n});\n\ncurrent.calculatePatch(next) === [\n  ['change', 'foo.js', entryFoo], // mtime + size changed, so this input is stale and needs updating.\n  ['create', 'baz.js', entryBaz]  // new file, so we should create it\n  /* bar stays the same and is left inert*/\n];\n```\n\nThe entry objects provided depend on the operation.  For `rmdir` and `unlink`\noperations, the current entry is provided.  For `mkdir`, `change` and `create`\noperations the new entry is provided.\n\n## API\n\nThe public API is:\n\n- `FSTree.fromPaths` initialize a tree from an array of string paths.\n- `FSTree.fromEntries` initialize a tree from an array of `Entry` objects.\n  Each entry must have the following properties (but may have more):\n\n    - `relativePath`\n    - `mode`\n    - `size`\n    - `mtime`\n- `FSTree.applyPatch(inputDir, outputDir, patch, delegate)` applies the given\n  patch from the input directory to the output directory. You can optionally\n  provide a delegate object to handle individual types of patch operations.\n- `FSTree.prototype.calculatePatch(newTree, isEqual)` calculate a patch against\n  `newTree`.  Optionally specify a custom `isEqual` (see Change Calculation).\n- `FSTree.prototype.calculateAndApplyPatch(newTree, inputDir, outputDir, delegate)`\n  does a `calculatePatch` followed by `applyPatch`.\n- `FSTree.prototype.addEntries(entries, options)` adds entries to an\n  existing tree. Options are the same as for `FSTree.fromEntries`.\n  Entries added with the same path will overwrite any existing entries.\n- `FSTree.prototype.addPaths(paths, options)` adds paths to an\n  existing tree. Options are the same as for `FSTree.fromPaths`.\n  If entries already exist for any of the paths added, those entries will\n  be updated.\n- `Entry.fromStat(relativePath, stat)` creates an `Entry` from a given path and\n  [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object. It can\n  then be used with `fromEntries` or `addEntries`.\n\n\nThe trees returned from `fromPaths` and `fromEntries` are relative to some base\ndirectory.  `calculatePatch`, `applyPatch` and `calculateAndApplyPatch` all\nassume that the base directory has not changed.\n\n## Input\n\n`FSTree.fromPaths`, `FSTree.fromEntries`, `FSTree.prototype.addPaths`,\nand `FSTree.prototype.addEntries` all validate their inputs.  Inputs\nmust be sorted, path-unique (i.e. two entries with the same `relativePath` but\ndifferent `size`s would still be illegal input) and include intermediate\ndirectories.\n\nFor example, the following input is **invalid**\n\n```js\nFSTree.fromPaths([\n  // => missing a/ and a/b/\n  'a/b/c.js'\n]);\n```\n\nTo have FSTree sort and expand (include intermediate directories) for you, add\nthe option `sortAndExpand`).\n\n```js\nFStree.fromPaths([\n\t'a/b/q/r/bar.js',\n\t'a/b/c/d/foo.js',\n], { sortAndExpand: true });\n\n// The above is equivalent to\n\nFSTree.fromPaths([\n\t'a/',\n\t'a/b/',\n\t'a/b/c/',\n\t'a/b/c/d/',\n\t'a/b/c/d/foo.js',\n\t'a/b/q/',\n\t'a/b/q/r/',\n\t'a/b/q/r/bar.js',\n]);\n```\n\n## Entry\n\n`FSTree.fromEntries` requires you to supply your own `Entry` objects.  Your\nentry objects **must** contain the following properties:\n\n  - `relativePath`\n  - `mode`\n  - `size`\n  - `mtime`\n\nThey must also implement the following API:\n\n  - `isDirectory()` `true` *iff* this entry is a directory\n\n`FSTree.fromEntries` composes well with the output of `walkSync.entries`:\n\n```js\nvar walkSync = require('walk-sync');\n\n// path/to/root/foo.js\n// path/to/root/bar.js\nvar current = FSTree.fromEntries(walkSync.entries('path/to/root'));\n```\n\n## Change Calculation\n\nWhen a prior entry has a `relativePath` that matches that of a current entry, a\nchange operation is included if the new entry is different from the previous\nentry.  This is determined by calling `isEqual`, the optional second argument\nto `calculatePatch`.  If no `isEqual` is provided, a default `isEqual` is used.\n\nThe default `isEqual` treats directories as always equal and files as different\nif any of the following properties have changed.\n\n  - `mode`\n  - `size`\n  - `mtime`\n\nUser specified `isEqual` will often want to use the default `isEqual`, so it is exported on `FSTree`.\n\nExample\n\n```js\nvar defaultIsEqual = FSTtreeDiff.isEqual;\n\nfunction isEqualCheckingMeta(a, b) {\n  return defaultIsEqual(a, b) && isMetaEqual(a, b);\n}\n\nfunction isMetaEqual(a, b) {\n  // ...\n}\n```\n\n## Patch Application\n\nWhen you want to apply changes from one tree to another easily, you can use the\n`FSTree.applyPatch` method. For example, given:\n\n```js\nvar patch = oldInputTree.calculatePatch(newInputTree);\nvar inputDir = 'src';\nvar outputDir = 'dist';\nFSTree.applyPatch(inputDir, outputDir, patch);\n```\n\nIt will apply the patch changes to `dist` while using `src` as a reference for\nnon-destructive operations (`mkdir`, `create`, `change`). If you want to calculate\nand apply a patch without any intermediate operations, you can do:\n\n```js\nvar inputDir = 'src';\nvar outputDir = 'dist';\noldInputTree.calculateAndApplyPatch(newInputTree, inputDir, outputDir);\n```\n\nYou can optionally provide a delegate object to handle applying specific types\nof operations:\n\n```js\nvar createCount = 0;\nFSTree.applyPatch(inputDir, outputDir, patch, {\n  create: function(inputPath, outputPath, relativePath) {\n    createCount++;\n    copy(inputPath, outputPath);\n  }\n});\n```\n\nThe available delegate functions are the same as the supported operations:\n`unlink`, `rmdir`, `mkdir`, `create`, and `change`. Each delegate function\nreceives the reference `inputPath`, the `outputPath`, and `relativePath` of the file\nor directory for which to apply the operation.\n\n",
  "readmeFilename": "README.md",
  "repository": {
    "type": "git",
    "url": "git://github.com/stefanpenner/fs-tree-diff.git"
  },
  "scripts": {
    "test": "mocha tests/",
    "test:debug": "mocha debug tests/"
  },
  "version": "0.5.7"
}
