From 95e6b18e5d05d0c81648d75e47b1c0bc2f4a3942 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Mon, 2 Mar 2020 10:18:39 +0000 Subject: [PATCH] fix: only ignore raw-leaves when file is small and metadata is present Following further conversation in https://github.com/ipfs/go-ipfs/issues/6940 it seems for small files it would be better to only ignore the `--raw-leaves` flag when metadata is actually present. --- .../src/dag-builder/file/index.js | 5 +- .../test/chunker-custom.spec.js | 2 +- .../test/importer.spec.js | 85 +++++++++++++++++-- 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/packages/ipfs-unixfs-importer/src/dag-builder/file/index.js b/packages/ipfs-unixfs-importer/src/dag-builder/file/index.js index f44c5e51..973ac439 100644 --- a/packages/ipfs-unixfs-importer/src/dag-builder/file/index.js +++ b/packages/ipfs-unixfs-importer/src/dag-builder/file/index.js @@ -53,8 +53,9 @@ const reduce = (file, ipld, options) => { if (leaves.length === 1 && leaves[0].single && options.reduceSingleLeafToSelf) { const leaf = leaves[0] - if (leaf.cid.codec === 'raw') { - // only one leaf node which is a buffer + if (leaf.cid.codec === 'raw' && (file.mtime !== undefined || file.mode !== undefined)) { + // only one leaf node which is a buffer - we have metadata so convert it into a + // UnixFS entry otherwise we'll have nowhere to store the metadata const buffer = await ipld.get(leaf.cid) leaf.unixfs = new UnixFS({ diff --git a/packages/ipfs-unixfs-importer/test/chunker-custom.spec.js b/packages/ipfs-unixfs-importer/test/chunker-custom.spec.js index 8bc80dda..2dd00f0f 100644 --- a/packages/ipfs-unixfs-importer/test/chunker-custom.spec.js +++ b/packages/ipfs-unixfs-importer/test/chunker-custom.spec.js @@ -69,5 +69,5 @@ describe('custom chunker', function () { cid: await inmem.put(Buffer.from('hello world'), mc.RAW) } } - it('works with single part', fromPartsTest(single, 19)) + it('works with single part', fromPartsTest(single, 11)) }) diff --git a/packages/ipfs-unixfs-importer/test/importer.spec.js b/packages/ipfs-unixfs-importer/test/importer.spec.js index 0f5b6589..29ea8f01 100644 --- a/packages/ipfs-unixfs-importer/test/importer.spec.js +++ b/packages/ipfs-unixfs-importer/test/importer.spec.js @@ -140,12 +140,22 @@ const strategyOverrides = { size: 2669627, type: 'directory' }, - '200Bytes.txt with raw leaves': { + '200Bytes.txt with raw leaves': extend({}, baseFiles['200Bytes.txt'], { cid: 'QmagyRwMfYhczYNv5SvcJc8xxXjZQBTTHS2jEqNMva2mYT', - size: 200, - path: '200Bytes.txt', - type: 'file' - }, + size: 200 + }), + '200Bytes.txt with raw leaves and mode': extend({}, baseFiles['200Bytes.txt'], { + cid: 'QmRYYSoRkL9bh5gzbgHndWjt81TYnM4W7MjzTp8WWioLGB', + size: 200 + }), + '200Bytes.txt with raw leaves and mtime': extend({}, baseFiles['200Bytes.txt'], { + cid: 'QmQ1QHqXqgxJ4qjJZouRdYG7pdS6yzdhSAq7dYAu9bN6h4', + size: 200 + }), + '200Bytes.txt with raw leaves and metadata': extend({}, baseFiles['200Bytes.txt'], { + cid: 'QmWUpftnvHN1Ey5iGoaWwMUZPnViXeJctDSUkcvunkahFo', + size: 200 + }), 'foo/bar': { cid: 'QmTGMxKPzSGNBDp6jhTwnZxGW6w1S9ciyycRJ4b2qcQaHK', size: 0, @@ -260,7 +270,18 @@ strategies.forEach((strategy) => { type: 'directory' }, '200Bytes.txt with raw leaves': extend({}, baseFiles['200Bytes.txt'], { - cid: 'QmQmZQxSKQppbsWfVzBvg59Cn3DKtsNVQ94bjAxg2h3Lb8', + cid: 'zb2rhXrz1gkCv8p4nUDZRohY6MzBE9C3HVTVDP72g6Du3SD9Q' + }), + '200Bytes.txt with raw leaves and mode': extend({}, baseFiles['200Bytes.txt'], { + cid: 'QmWXbKV9BKJqd8x1NUw1myH987bURrn9Rna3rszYJgQwtX', + size: 200 + }), + '200Bytes.txt with raw leaves and mtime': extend({}, baseFiles['200Bytes.txt'], { + cid: 'QmYfLToWgeJwrFFKideGNaS1zkmrow1a9o862sUL43NapC', + size: 200 + }), + '200Bytes.txt with raw leaves and metadata': extend({}, baseFiles['200Bytes.txt'], { + cid: 'QmVfHowk2oKuWFyVwSRt8H1dQ3v272jyWSwhfQnTtWNmfw', size: 200 }) }, strategyOverrides[strategy]) @@ -443,6 +464,58 @@ strategies.forEach((strategy) => { ]) }) + it('small file (smaller than a chunk) with raw leaves and mode', async () => { + const files = await all(importer([{ + path: '200Bytes.txt', + content: smallFile, + mode: 0o123 + }], ipld, { + ...options, + rawLeaves: true + })) + + expectFiles(files, [ + '200Bytes.txt with raw leaves and mode' + ]) + }) + + it('small file (smaller than a chunk) with raw leaves and mtime', async () => { + const files = await all(importer([{ + path: '200Bytes.txt', + content: smallFile, + mtime: { + secs: 10, + nsecs: 0 + } + }], ipld, { + ...options, + rawLeaves: true + })) + + expectFiles(files, [ + '200Bytes.txt with raw leaves and mtime' + ]) + }) + + it('small file (smaller than a chunk) with raw leaves and metadata', async () => { + const files = await all(importer([{ + path: '200Bytes.txt', + content: smallFile, + mode: 0o123, + mtime: { + secs: 10, + nsecs: 0 + } + }], ipld, { + ...options, + rawLeaves: true + })) + + expectFiles(files, [ + '200Bytes.txt with raw leaves and metadata' + ]) + }) + it('small file (smaller than a chunk) inside a dir', async () => { const files = await all(importer([{ path: 'foo/bar/200Bytes.txt',