Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: destructuring assignment path module in fs #22834

Closed
wants to merge 2 commits into from

Conversation

ZYSzys
Copy link
Member

@ZYSzys ZYSzys commented Sep 13, 2018

Minor refactor: Use destructuring assignment at path module in fs instead of require the whole module.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • commit message follows commit guidelines

@nodejs-github-bot nodejs-github-bot added the fs Issues and PRs related to the fs subsystem / file system. label Sep 13, 2018
Trott
Trott previously requested changes Sep 13, 2018
Copy link
Member

@Trott Trott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we confirm that this will land cleanly on 8.x-staging and 6.x-staging? (If so, you can clear this request for changes.) The value here may be less than the cost of backporting the change.

@Trott
Copy link
Member

Trott commented Sep 13, 2018

I just confirmed that this has conflicts (with a big diff) on v8-x.staging:

``` diff --cc lib/fs.js index 8696d38e36,278b66ce8d..0000000000 --- a/lib/fs.js +++ b/lib/fs.js @@@ -24,37 -24,83 +24,58 @@@

'use strict';

++<<<<<<< HEAD
+const constants = process.binding('constants').fs;
+const { S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK } = constants;
+const util = require('util');
+const pathModule = require('path');
+const { isUint8Array } = require('internal/util/types');
+const { createPromise, promiseResolve } = process.binding('util');
+
++=======

  • const { fs: constants } = process.binding('constants');
  • const {
  • S_IFIFO,
  • S_IFLNK,
  • S_IFMT,
  • S_IFREG,
  • S_IFSOCK,
  • F_OK,
  • R_OK,
  • W_OK,
  • X_OK,
  • O_WRONLY,
  • O_SYMLINK
  • } = constants;
  • const { _extend } = require('util');
  • const { _makeLong, toNamespacedPath, resolve } = require('path');
  • const { isArrayBufferView } = require('internal/util/types');
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
    const binding = process.binding('fs');
    -const { Buffer, kMaxLength } = require('buffer');
    +const fs = exports;
    +const { Buffer } = require('buffer');
    const errors = require('internal/errors');
    -const {
  • ERR_FS_FILE_TOO_LARGE,
  • ERR_INVALID_ARG_VALUE,
  • ERR_INVALID_ARG_TYPE,
  • ERR_INVALID_CALLBACK
    -} = errors.codes;

-const { FSReqCallback, statValues } = binding;
-const internalFS = require('internal/fs/utils');
-const { toPathIfFileURL } = require('internal/url');
+const { Readable, Writable } = require('stream');
+const EventEmitter = require('events');
+const { FSReqWrap } = binding;
+const { FSEvent } = process.binding('fs_event_wrap');
+const internalFS = require('internal/fs');
+const { getPathFromURL } = require('internal/url');
const internalUtil = require('internal/util');
const {

  • copyObject,
  • Dirent,
  • getDirents,
  • getOptions,
  • nullCheck,
  • preprocessSymlinkDestination,
  • Stats,
  • getStatsFromBinding,
  • realpathCacheKey,
  • stringToFlags,
  • stringToSymlinkType,
  • toUnixTimestamp,
  • validateBuffer,
  • validateOffsetLengthRead,
  • validateOffsetLengthWrite,
  • validatePath
  • assertEncoding,
  • stringToFlags
    } = internalFS;
    -const {
  • CHAR_FORWARD_SLASH,
  • CHAR_BACKWARD_SLASH,
    -} = require('internal/constants');
    -const {
  • isUint32,
  • validateMode,
  • validateInteger,
  • validateInt32,
  • validateUint32
    -} = require('internal/validators');

-let promisesWarn = true;
-let truncateWarn = true;
-let fs;

-// Lazy loaded
-let promises;
-let watchers;
-let ReadFileContext;
-let ReadStream;
-let WriteStream;

-// These have to be separate because of how graceful-fs happens to do it's
-// monkeypatching.
-let FileReadStream;
-let FileWriteStream;
+
+Object.defineProperty(exports, 'constants', {

  • configurable: false,
  • enumerable: true,
  • value: constants
    +});

+const kMinPoolSpace = 128;
+const { kMaxLength } = require('buffer');

const isWindows = process.platform === 'win32';

@@@ -154,170 -163,60 +175,189 @@@ function makeStatsCallback(cb)
};
}

-const isFd = isUint32;
+function nullCheck(path, callback) {

  • if (('' + path).indexOf('\u0000') !== -1) {
  • var er = new Error('Path must be a string without null bytes');
  • er.code = 'ENOENT';
  • if (typeof callback !== 'function')
  •  throw er;
    
  • process.nextTick(callback, er);
  • return false;
  • }
  • return true;
    +}

+function isFd(path) {

  • return (path >>> 0) === path;
    +}

+// Constructor for file stats.
+function Stats(

  • dev,
  • mode,
  • nlink,
  • uid,
  • gid,
  • rdev,
  • blksize,
  • ino,
  • size,
  • blocks,
  • atim_msec,
  • mtim_msec,
  • ctim_msec,
  • birthtim_msec
    +) {
  • this.dev = dev;
  • this.mode = mode;
  • this.nlink = nlink;
  • this.uid = uid;
  • this.gid = gid;
  • this.rdev = rdev;
  • this.blksize = blksize;
  • this.ino = ino;
  • this.size = size;
  • this.blocks = blocks;
  • this.atimeMs = atim_msec;
  • this.mtimeMs = mtim_msec;
  • this.ctimeMs = ctim_msec;
  • this.birthtimeMs = birthtim_msec;
  • this.atime = new Date(atim_msec + 0.5);
  • this.mtime = new Date(mtim_msec + 0.5);
  • this.ctime = new Date(ctim_msec + 0.5);
  • this.birthtime = new Date(birthtim_msec + 0.5);
    +}
    +fs.Stats = Stats;

+Stats.prototype._checkModeProperty = function(property) {

  • return ((this.mode & S_IFMT) === property);
    +};

+Stats.prototype.isDirectory = function() {

  • return this._checkModeProperty(constants.S_IFDIR);
    +};

+Stats.prototype.isFile = function() {

  • return this._checkModeProperty(S_IFREG);
    +};

+Stats.prototype.isBlockDevice = function() {

  • return this._checkModeProperty(constants.S_IFBLK);
    +};

+Stats.prototype.isCharacterDevice = function() {

  • return this._checkModeProperty(constants.S_IFCHR);
    +};

+Stats.prototype.isSymbolicLink = function() {

  • return this._checkModeProperty(S_IFLNK);
    +};

+Stats.prototype.isFIFO = function() {

  • return this._checkModeProperty(S_IFIFO);
    +};

+Stats.prototype.isSocket = function() {

  • return this._checkModeProperty(S_IFSOCK);
    +};

+const statValues = binding.getStatValues();
+
+function statsFromValues() {

  • return new Stats(statValues[0], statValues[1], statValues[2], statValues[3],
  •               statValues[4], statValues[5],
    
  •               statValues[6] < 0 ? undefined : statValues[6], statValues[7],
    
  •               statValues[8], statValues[9] < 0 ? undefined : statValues[9],
    
  •               statValues[10], statValues[11], statValues[12],
    
  •               statValues[13]);
    

+}
+
+// Don't allow mode to accidentally be overwritten.
+Object.defineProperties(fs, {

  • F_OK: { enumerable: true, value: constants.F_OK || 0 },
  • R_OK: { enumerable: true, value: constants.R_OK || 0 },
  • W_OK: { enumerable: true, value: constants.W_OK || 0 },
  • X_OK: { enumerable: true, value: constants.X_OK || 0 },
    +});

-function isFileType(stats, fileType) {

  • // Use stats array directly to avoid creating an fs.Stats instance just for
  • // our internal use.
  • return (stats[1/* mode */] & S_IFMT) === fileType;
    +function handleError(val, callback) {
  • if (val instanceof Error) {
  • if (typeof callback === 'function') {
  •  process.nextTick(callback, val);
    
  •  return true;
    
  • } else throw val;
  • }
  • return false;
    }

-function access(path, mode, callback) {
+fs.access = function(path, mode, callback) {
if (typeof mode === 'function') {
callback = mode;

  • mode = F_OK;
  • mode = fs.F_OK;
  • } else if (typeof callback !== 'function') {
  • throw new TypeError('"callback" argument must be a function');
    }
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • if (handleError((path = getPathFromURL(path)), callback))
  • return;
  • if (!nullCheck(path, callback))
  • return;
mode = mode | 0;
  • const req = new FSReqCallback();
  • var req = new FSReqWrap();
    req.oncomplete = makeCallback(callback);
    ++<<<<<<< HEAD
  • binding.access(pathModule._makeLong(path), mode, req);
    +};
    ++=======
  • binding.access(toNamespacedPath(path), mode, req);
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function accessSync(path, mode) {

  • path = toPathIfFileURL(path);
  • validatePath(path);
    +fs.accessSync = function(path, mode) {
  • handleError((path = getPathFromURL(path)));

  • nullCheck(path);

    if (mode === undefined)

  • mode = F_OK;
  • mode = fs.F_OK;
    else
    mode = mode | 0;

++<<<<<<< HEAD

  • binding.access(pathModule._makeLong(path), mode);
    +};
    ++=======
  • const ctx = { path };
  • binding.access(toNamespacedPath(path), mode, undefined, ctx);
  • handleErrorFromBinding(ctx);
  • }
  • function exists(path, callback) {
  • maybeCallback(callback);
  • function suppressedCallback(err) {
  • callback(err ? false : true);
    
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
  • try {
  • fs.access(path, F_OK, suppressedCallback);
  • } catch (err) {
  • return callback(false);
    +fs.exists = function(path, callback) {
  • if (handleError((path = getPathFromURL(path)), cb))
  • return;
  • if (!nullCheck(path, cb)) return;
  • var req = new FSReqWrap();
  • req.oncomplete = cb;
  • binding.stat(pathModule._makeLong(path), req);
  • function cb(err) {
  • if (callback) callback(err ? false : true);
    }
    -}
    +};

-Object.defineProperty(exists, internalUtil.promisify.custom, {
+Object.defineProperty(fs.exists, internalUtil.promisify.custom, {
value: (path) => {

  • return new Promise((resolve) => fs.exists(path, resolve));
  • const promise = createPromise();
  • fs.exists(path, (exists) => promiseResolve(promise, exists));
  • return promise;
    }
    });

@@@ -463,52 -278,31 +503,61 @@@ function readFileAfterStat(err)
context.read();
}

-function readFile(path, options, callback) {

  • callback = maybeCallback(callback || options);
  • options = getOptions(options, { flag: 'r' });
  • if (!ReadFileContext)
  • ReadFileContext = require('internal/fs/read_file_context');
  • const context = new ReadFileContext(callback, options.encoding);
  • context.isUserFd = isFd(path); // file descriptor ownership
    +function readFileAfterRead(err, bytesRead) {
  • var context = this.context;
  • const req = new FSReqCallback();
  • req.context = context;
  • req.oncomplete = readFileAfterOpen;
  • if (err)
  • return context.close(err);
  • if (context.isUserFd) {
  • process.nextTick(function tick() {
  •  req.oncomplete(null, path);
    
  • });
  • return;
  • if (bytesRead === 0)
  • return context.close();
  • context.pos += bytesRead;
  • if (context.size !== 0) {
  • if (context.pos === context.size)
  •  context.close();
    
  • else
  •  context.read();
    
  • } else {
  • // unknown size, just read until we don't get bytes.
  • context.buffers.push(context.buffer.slice(0, bytesRead));
  • context.read();
    }
    +}

++<<<<<<< HEAD
+function readFileAfterClose(err) {

  • var context = this.context;

  • var buffer = null;

  • var callback = context.callback;

  • if (context.err || err)

  • return callback(context.err || err);

  • try {

  • if (context.size === 0)

  •  buffer = Buffer.concat(context.buffers, context.pos);
    
  • else if (context.pos < context.size)

  •  buffer = context.buffer.slice(0, context.pos);
    
  • else

  •  buffer = context.buffer;
    
  • if (context.encoding)

  •  buffer = buffer.toString(context.encoding);
    
  • } catch (err) {

  • return callback(err);

  • }

  • callback(null, buffer);
    ++=======

  • path = toPathIfFileURL(path);

  • validatePath(path);

  • binding.open(toNamespacedPath(path),

  •            stringToFlags(options.flag || 'r'),
    
  •            0o666,
    
  •            req);
    

++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
}

function tryStatSync(fd, isUserFd) {
@@@ -600,56 -391,70 +649,84 @@@ fs.readFileSync = function(path, option

if (options.encoding) buffer = buffer.toString(options.encoding);
return buffer;

-}
+};

-function close(fd, callback) {

  • validateUint32(fd, 'fd');
  • const req = new FSReqCallback();
    +fs.close = function(fd, callback) {
  • var req = new FSReqWrap();
    req.oncomplete = makeCallback(callback);
    binding.close(fd, req);
    -}
    +};

-function closeSync(fd) {

  • validateUint32(fd, 'fd');
    +fs.closeSync = function(fd) {
  • return binding.close(fd);
    +};
  • const ctx = {};
  • binding.close(fd, undefined, ctx);
  • handleErrorFromBinding(ctx);
    +function modeNum(m, def) {
  • if (typeof m === 'number')
  • return m;
  • if (typeof m === 'string')
  • return parseInt(m, 8);
  • if (def)
  • return modeNum(def);
  • return undefined;
    }

-function open(path, flags, mode, callback) {

  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const flagsNumber = stringToFlags(flags);
  • if (arguments.length < 4) {
  • callback = makeCallback(mode);
  • mode = 0o666;
  • } else {
  • mode = validateMode(mode, 'mode', 0o666);
  • callback = makeCallback(callback);
  • }
    +fs.open = function(path, flags, mode, callback_) {
  • var callback = makeCallback(arguments[arguments.length - 1]);
  • mode = modeNum(mode, 0o666);
  • const req = new FSReqCallback();
  • if (handleError((path = getPathFromURL(path)), callback))
  • return;
  • if (!nullCheck(path, callback)) return;
  • var req = new FSReqWrap();
    req.oncomplete = callback;

++<<<<<<< HEAD

  • binding.open(pathModule._makeLong(path),
  •           stringToFlags(flags),
    
  •           mode,
    
  •           req);
    

+};
++=======

  • binding.open(toNamespacedPath(path),
  •            flagsNumber,
    
  •            mode,
    
  •            req);
    
  • }
  • function openSync(path, flags, mode) {
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const flagsNumber = stringToFlags(flags);
  • mode = validateMode(mode, 'mode', 0o666);
  • const ctx = { path };
  • const result = binding.open(toNamespacedPath(path),
  •                           flagsNumber, mode,
    
  •                           undefined, ctx);
    
  • handleErrorFromBinding(ctx);
  • return result;
  • }
  • function read(fd, buffer, offset, length, position, callback) {
  • validateUint32(fd, 'fd');
  • validateBuffer(buffer);
  • callback = maybeCallback(callback);
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
  • offset |= 0;
  • length |= 0;
    +fs.openSync = function(path, flags, mode) {
  • mode = modeNum(mode, 0o666);
  • handleError((path = getPathFromURL(path)));
  • nullCheck(path);
  • return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
    +};

+fs.read = function(fd, buffer, offset, length, position, callback) {
if (length === 0) {

  • return process.nextTick(function tick() {
  •  callback(null, 0, buffer);
    
  • return process.nextTick(function() {
  •  callback && callback(null, 0, buffer);
    
    });
    }

@@@ -731,44 -569,49 +808,62 @@@ fs.writeSync = function(fd, buffer, off
if (typeof offset !== 'number')
offset = 0;
if (typeof length !== 'number')

  •  length = buffer.byteLength - offset;
    
  • validateOffsetLengthWrite(offset, length, buffer.byteLength);
  • result = binding.writeBuffer(fd, buffer, offset, length, position,
  •                             undefined, ctx);
    
  • } else {
  • if (typeof buffer !== 'string')
  •  buffer += '';
    
  • if (offset === undefined)
  •  offset = null;
    
  • result = binding.writeString(fd, buffer, offset, length,
  •                             undefined, ctx);
    
  •  length = buffer.length - offset;
    
  • return binding.writeBuffer(fd, buffer, offset, length, position);
    }
  • handleErrorFromBinding(ctx);
  • return result;
    -}
  • if (typeof buffer !== 'string')
  • buffer += '';
  • if (offset === undefined)
  • offset = null;
  • return binding.writeString(fd, buffer, offset, length, position);
    +};

-function rename(oldPath, newPath, callback) {
+fs.rename = function(oldPath, newPath, callback) {
callback = makeCallback(callback);

  • oldPath = toPathIfFileURL(oldPath);
  • validatePath(oldPath, 'oldPath');
  • newPath = toPathIfFileURL(newPath);
  • validatePath(newPath, 'newPath');
  • const req = new FSReqCallback();
  • if (handleError((oldPath = getPathFromURL(oldPath)), callback))
  • return;
  • if (handleError((newPath = getPathFromURL(newPath)), callback))
  • return;
  • if (!nullCheck(oldPath, callback)) return;
  • if (!nullCheck(newPath, callback)) return;
  • var req = new FSReqWrap();
    req.oncomplete = callback;
    ++<<<<<<< HEAD
  • binding.rename(pathModule._makeLong(oldPath),
  •             pathModule._makeLong(newPath),
    

++=======

  • binding.rename(toNamespacedPath(oldPath),
  •              toNamespacedPath(newPath),
    

++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
req);
-}
+};

++<<<<<<< HEAD
+fs.renameSync = function(oldPath, newPath) {

  • handleError((oldPath = getPathFromURL(oldPath)));
  • handleError((newPath = getPathFromURL(newPath)));
  • nullCheck(oldPath);
  • nullCheck(newPath);
  • return binding.rename(pathModule._makeLong(oldPath),
  •                    pathModule._makeLong(newPath));
    

+};
++=======

  • function renameSync(oldPath, newPath) {
  • oldPath = toPathIfFileURL(oldPath);
  • validatePath(oldPath, 'oldPath');
  • newPath = toPathIfFileURL(newPath);
  • validatePath(newPath, 'newPath');
  • const ctx = { path: oldPath, dest: newPath };
  • binding.rename(toNamespacedPath(oldPath),
  •              toNamespacedPath(newPath), undefined, ctx);
    
  • handleErrorFromBinding(ctx);
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function truncate(path, len, callback) {
+fs.truncate = function(path, len, callback) {
if (typeof path === 'number') {

  • showTruncateDeprecation();
    return fs.ftruncate(path, len, callback);
    }
    if (typeof len === 'function') {
    @@@ -815,426 -660,487 +910,656 @@@ fs.ftruncate = function(fd, len, callba
    if (typeof len === 'function') {
    callback = len;
    len = 0;
  • } else if (len === undefined) {
  • len = 0;
    }
  • validateUint32(fd, 'fd');
  • validateInteger(len, 'len');
  • len = Math.max(0, len);
  • const req = new FSReqCallback();
  • var req = new FSReqWrap();
    req.oncomplete = makeCallback(callback);
    binding.ftruncate(fd, len, req);
    -}
    +};

-function ftruncateSync(fd, len = 0) {

  • validateUint32(fd, 'fd');
  • validateInteger(len, 'len');
  • len = Math.max(0, len);
  • const ctx = {};
  • binding.ftruncate(fd, len, undefined, ctx);
  • handleErrorFromBinding(ctx);
    -}
    +fs.ftruncateSync = function(fd, len) {
  • if (len === undefined) {
  • len = 0;
  • }
  • return binding.ftruncate(fd, len);
    +};

-function rmdir(path, callback) {

  • callback = makeCallback(callback);
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const req = new FSReqCallback();
    +fs.rmdir = function(path, callback) {
  • callback = maybeCallback(callback);
  • if (handleError((path = getPathFromURL(path)), callback))
  • return;
  • if (!nullCheck(path, callback)) return;
  • var req = new FSReqWrap();
    req.oncomplete = callback;
    ++<<<<<<< HEAD
  • binding.rmdir(pathModule._makeLong(path), req);
    +};

+fs.rmdirSync = function(path) {

  • handleError((path = getPathFromURL(path)));
  • nullCheck(path);
  • return binding.rmdir(pathModule._makeLong(path));
    +};
    ++=======
  • binding.rmdir(toNamespacedPath(path), req);
  • }
  • function rmdirSync(path) {
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const ctx = { path };
  • binding.rmdir(toNamespacedPath(path), undefined, ctx);
  • handleErrorFromBinding(ctx);
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function fdatasync(fd, callback) {

  • validateUint32(fd, 'fd');
  • const req = new FSReqCallback();
    +fs.fdatasync = function(fd, callback) {
  • var req = new FSReqWrap();
    req.oncomplete = makeCallback(callback);
    binding.fdatasync(fd, req);
    -}
    +};

-function fdatasyncSync(fd) {

  • validateUint32(fd, 'fd');
  • const ctx = {};
  • binding.fdatasync(fd, undefined, ctx);
  • handleErrorFromBinding(ctx);
    -}
    +fs.fdatasyncSync = function(fd) {
  • return binding.fdatasync(fd);
    +};

-function fsync(fd, callback) {

  • validateUint32(fd, 'fd');
  • const req = new FSReqCallback();
    +fs.fsync = function(fd, callback) {
  • var req = new FSReqWrap();
    req.oncomplete = makeCallback(callback);
    binding.fsync(fd, req);
    -}
    +};

-function fsyncSync(fd) {

  • validateUint32(fd, 'fd');
  • const ctx = {};
  • binding.fsync(fd, undefined, ctx);
  • handleErrorFromBinding(ctx);
    -}
    +fs.fsyncSync = function(fd) {
  • return binding.fsync(fd);
    +};

-function mkdir(path, options, callback) {

  • if (typeof options === 'function') {
  • callback = options;
  • options = {};
  • } else if (typeof options === 'number' || typeof options === 'string') {
  • options = { mode: options };
  • }
  • const {
  • recursive = false,
  • mode = 0o777
  • } = options || {};
    +fs.mkdir = function(path, mode, callback) {
  • if (typeof mode === 'function') callback = mode;
    callback = makeCallback(callback);
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • if (typeof recursive !== 'boolean')
  • throw new ERR_INVALID_ARG_TYPE('recursive', 'boolean', recursive);
  • const req = new FSReqCallback();
  • if (handleError((path = getPathFromURL(path)), callback))
  • return;
  • if (!nullCheck(path, callback)) return;
  • var req = new FSReqWrap();
    req.oncomplete = callback;
    ++<<<<<<< HEAD
  • binding.mkdir(pathModule._makeLong(path),
  •            modeNum(mode, 0o777),
    
  •            req);
    

+};
+
+fs.mkdirSync = function(path, mode) {

  • handleError((path = getPathFromURL(path)));
  • nullCheck(path);
  • return binding.mkdir(pathModule._makeLong(path),
  •                   modeNum(mode, 0o777));
    

+};
++=======

  • binding.mkdir(toNamespacedPath(path),
  •             validateMode(mode, 'mode', 0o777), recursive, req);
    
  • }
  • function mkdirSync(path, options) {
  • if (typeof options === 'number' || typeof options === 'string') {
  • options = { mode: options };
    
  • }
  • path = toPathIfFileURL(path);
  • const {
  • recursive = false,
    
  • mode = 0o777
    
  • } = options || {};
  • validatePath(path);
  • if (typeof recursive !== 'boolean')
  • throw new ERR_INVALID_ARG_TYPE('recursive', 'boolean', recursive);
    
  • const ctx = { path };
  • binding.mkdir(toNamespacedPath(path),
  •             validateMode(mode, 'mode', 0o777), recursive, undefined,
    
  •             ctx);
    
  • handleErrorFromBinding(ctx);
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function readdir(path, options, callback) {
+fs.readdir = function(path, options, callback) {
callback = makeCallback(typeof options === 'function' ? options : callback);
options = getOptions(options, {});
++<<<<<<< HEAD

  • if (handleError((path = getPathFromURL(path)), callback))
  • return;
  • if (!nullCheck(path, callback)) return;
  • var req = new FSReqWrap();
  • req.oncomplete = callback;
  • binding.readdir(pathModule._makeLong(path), options.encoding, req);
    +};
    ++=======
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const req = new FSReqCallback();
  • if (!options.withFileTypes) {
  • req.oncomplete = callback;
    
  • } else {
  • req.oncomplete = (err, result) => {
    
  •   if (err) {
    
  •     callback(err);
    
  •     return;
    
  •   }
    
  •   getDirents(path, result, callback);
    
  • };
    
  • }
  • binding.readdir(toNamespacedPath(path), options.encoding,
  •               !!options.withFileTypes, req);
    
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function readdirSync(path, options) {
+fs.readdirSync = function(path, options) {
options = getOptions(options, {});
++<<<<<<< HEAD

  • handleError((path = getPathFromURL(path)));
  • nullCheck(path);
  • return binding.readdir(pathModule._makeLong(path), options.encoding);
    +};
    ++=======
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const ctx = { path };
  • const result = binding.readdir(toNamespacedPath(path),
  •                              options.encoding, !!options.withFileTypes,
    
  •                              undefined, ctx);
    
  • handleErrorFromBinding(ctx);
  • return options.withFileTypes ? getDirents(path, result) : result;
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function fstat(fd, options, callback) {

  • if (arguments.length < 3) {
  • callback = options;
  • options = {};
  • }
  • validateUint32(fd, 'fd');
  • const req = new FSReqCallback(options.bigint);
    +fs.fstat = function(fd, callback) {
  • var req = new FSReqWrap();
    req.oncomplete = makeStatsCallback(callback);
  • binding.fstat(fd, options.bigint, req);
    -}
  • binding.fstat(fd, req);
    +};

-function lstat(path, options, callback) {

  • if (arguments.length < 3) {
  • callback = options;
  • options = {};
  • }
    +fs.lstat = function(path, callback) {
    callback = makeStatsCallback(callback);
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const req = new FSReqCallback(options.bigint);
  • if (handleError((path = getPathFromURL(path)), callback))
  • return;
  • if (!nullCheck(path, callback)) return;
  • var req = new FSReqWrap();
    req.oncomplete = callback;
    ++<<<<<<< HEAD
  • binding.lstat(pathModule._makeLong(path), req);
    +};
    ++=======
  • binding.lstat(toNamespacedPath(path), options.bigint, req);
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function stat(path, options, callback) {

  • if (arguments.length < 3) {
  • callback = options;
  • options = {};
  • }
    +fs.stat = function(path, callback) {
    callback = makeStatsCallback(callback);
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const req = new FSReqCallback(options.bigint);
  • if (handleError((path = getPathFromURL(path)), callback))
  • return;
  • if (!nullCheck(path, callback)) return;
  • var req = new FSReqWrap();
    req.oncomplete = callback;
    ++<<<<<<< HEAD
  • binding.stat(pathModule._makeLong(path), req);
    +};
    ++=======
  • binding.stat(toNamespacedPath(path), options.bigint, req);
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function fstatSync(fd, options = {}) {

  • validateUint32(fd, 'fd');
  • const ctx = { fd };
  • const stats = binding.fstat(fd, options.bigint, undefined, ctx);
  • handleErrorFromBinding(ctx);
  • return getStatsFromBinding(stats);
    -}
    +fs.fstatSync = function(fd) {
  • binding.fstat(fd);
  • return statsFromValues();
    +};

++<<<<<<< HEAD
+fs.lstatSync = function(path) {

  • handleError((path = getPathFromURL(path)));
  • nullCheck(path);
  • binding.lstat(pathModule._makeLong(path));
  • return statsFromValues();
    +};

+fs.statSync = function(path) {

  • handleError((path = getPathFromURL(path)));
  • nullCheck(path);
  • binding.stat(pathModule._makeLong(path));
  • return statsFromValues();
    +};
    ++=======
  • function lstatSync(path, options = {}) {
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const ctx = { path };
  • const stats = binding.lstat(toNamespacedPath(path),
  •                           options.bigint, undefined, ctx);
    
  • handleErrorFromBinding(ctx);
  • return getStatsFromBinding(stats);
  • }
  • function statSync(path, options = {}) {
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const ctx = { path };
  • const stats = binding.stat(toNamespacedPath(path),
  •                          options.bigint, undefined, ctx);
    
  • handleErrorFromBinding(ctx);
  • return getStatsFromBinding(stats);
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function readlink(path, options, callback) {
+fs.readlink = function(path, options, callback) {
callback = makeCallback(typeof options === 'function' ? options : callback);
options = getOptions(options, {});

  • path = toPathIfFileURL(path);
  • validatePath(path, 'oldPath');
  • const req = new FSReqCallback();
  • if (handleError((path = getPathFromURL(path)), callback))
  • return;
  • if (!nullCheck(path, callback)) return;
  • var req = new FSReqWrap();
    req.oncomplete = callback;
    ++<<<<<<< HEAD
  • binding.readlink(pathModule._makeLong(path), options.encoding, req);
    +};
    ++=======
  • binding.readlink(toNamespacedPath(path), options.encoding, req);
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function readlinkSync(path, options) {
+fs.readlinkSync = function(path, options) {
options = getOptions(options, {});
++<<<<<<< HEAD

  • handleError((path = getPathFromURL(path)));
  • nullCheck(path);
  • return binding.readlink(pathModule._makeLong(path), options.encoding);
    +};

+function preprocessSymlinkDestination(path, type, linkPath) {

  • if (!isWindows) {
  • // No preprocessing is needed on Unix.
  • return path;
  • } else if (type === 'junction') {
  • // Junctions paths need to be absolute and \?-prefixed.
  • // A relative target is relative to the link's parent directory.
  • path = pathModule.resolve(linkPath, '..', path);
  • return pathModule._makeLong(path);
  • } else {
  • // Windows symlinks don't tolerate forward slashes.
  • return ('' + path).replace(///g, '\');
  • }
    ++=======
  • path = toPathIfFileURL(path);
  • validatePath(path, 'oldPath');
  • const ctx = { path };
  • const result = binding.readlink(toNamespacedPath(path),
  •                               options.encoding, undefined, ctx);
    
  • handleErrorFromBinding(ctx);
  • return result;
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
    }

-function symlink(target, path, type_, callback_) {

  • const type = (typeof type_ === 'string' ? type_ : null);
  • const callback = makeCallback(arguments[arguments.length - 1]);
    +fs.symlink = function(target, path, type_, callback_) {
  • var type = (typeof type_ === 'string' ? type_ : null);
  • var callback = makeCallback(arguments[arguments.length - 1]);
  • target = toPathIfFileURL(target);
  • path = toPathIfFileURL(path);
  • validatePath(target, 'target');
  • validatePath(path);
  • if (handleError((target = getPathFromURL(target)), callback))
  • return;
  • const flags = stringToSymlinkType(type);
  • const req = new FSReqCallback();
  • if (handleError((path = getPathFromURL(path)), callback))

  • return;

  • if (!nullCheck(target, callback)) return;

  • if (!nullCheck(path, callback)) return;

  • var req = new FSReqWrap();
    req.oncomplete = callback;

    binding.symlink(preprocessSymlinkDestination(target, type, path),
    ++<<<<<<< HEAD

  •              pathModule._makeLong(path),
    
  •              type,
    
  •              req);
    

+};
++=======

  •               toNamespacedPath(path), flags, req);
    
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function symlinkSync(target, path, type) {
+fs.symlinkSync = function(target, path, type) {
type = (typeof type === 'string' ? type : null);

  • target = toPathIfFileURL(target);
  • path = toPathIfFileURL(path);
  • validatePath(target, 'target');
  • validatePath(path);
  • const flags = stringToSymlinkType(type);
  • handleError((target = getPathFromURL(target)));
  • handleError((path = getPathFromURL(path)));
  • nullCheck(target);
  • nullCheck(path);
  • return binding.symlink(preprocessSymlinkDestination(target, type, path),
  •                     pathModule._makeLong(path),
    
  •                     type);
    

+};

++<<<<<<< HEAD
+fs.link = function(existingPath, newPath, callback) {

  • callback = makeCallback(callback);
    ++=======
  • const ctx = { path: target, dest: path };
  • binding.symlink(preprocessSymlinkDestination(target, type, path),
  •               toNamespacedPath(path), flags, undefined, ctx);
    

++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

  • handleErrorFromBinding(ctx);
    -}
  • if (handleError((existingPath = getPathFromURL(existingPath)), callback))
  • return;

-function link(existingPath, newPath, callback) {

  • callback = makeCallback(callback);
  • if (handleError((newPath = getPathFromURL(newPath)), callback))
  • return;
  • existingPath = toPathIfFileURL(existingPath);
  • newPath = toPathIfFileURL(newPath);
  • validatePath(existingPath, 'existingPath');
  • validatePath(newPath, 'newPath');
  • if (!nullCheck(existingPath, callback)) return;
  • if (!nullCheck(newPath, callback)) return;
  • const req = new FSReqCallback();
  • var req = new FSReqWrap();
    req.oncomplete = callback;

++<<<<<<< HEAD

  • binding.link(pathModule._makeLong(existingPath),
  •           pathModule._makeLong(newPath),
    

++=======

  • binding.link(toNamespacedPath(existingPath),
  •            toNamespacedPath(newPath),
    

++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
req);
-}
+};

++<<<<<<< HEAD
+fs.linkSync = function(existingPath, newPath) {

  • handleError((existingPath = getPathFromURL(existingPath)));
  • handleError((newPath = getPathFromURL(newPath)));
  • nullCheck(existingPath);
  • nullCheck(newPath);
  • return binding.link(pathModule._makeLong(existingPath),
  •                  pathModule._makeLong(newPath));
    

+};
++=======

  • function linkSync(existingPath, newPath) {
  • existingPath = toPathIfFileURL(existingPath);
  • newPath = toPathIfFileURL(newPath);
  • validatePath(existingPath, 'existingPath');
  • validatePath(newPath, 'newPath');
  • const ctx = { path: existingPath, dest: newPath };
  • const result = binding.link(toNamespacedPath(existingPath),
  •                           toNamespacedPath(newPath),
    
  •                           undefined, ctx);
    
  • handleErrorFromBinding(ctx);
  • return result;
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function unlink(path, callback) {
+fs.unlink = function(path, callback) {
callback = makeCallback(callback);

  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const req = new FSReqCallback();
  • if (handleError((path = getPathFromURL(path)), callback))
  • return;
  • if (!nullCheck(path, callback)) return;
  • var req = new FSReqWrap();
    req.oncomplete = callback;
    ++<<<<<<< HEAD
  • binding.unlink(pathModule._makeLong(path), req);
    +};
    ++=======
  • binding.unlink(toNamespacedPath(path), req);
  • }
  • function unlinkSync(path) {
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const ctx = { path };
  • binding.unlink(toNamespacedPath(path), undefined, ctx);
  • handleErrorFromBinding(ctx);
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function fchmod(fd, mode, callback) {

  • validateInt32(fd, 'fd', 0);
  • mode = validateMode(mode, 'mode');
  • callback = makeCallback(callback);
    +fs.unlinkSync = function(path) {
  • handleError((path = getPathFromURL(path)));
  • nullCheck(path);
  • return binding.unlink(pathModule._makeLong(path));
    +};
  • const req = new FSReqCallback();
  • req.oncomplete = callback;
  • binding.fchmod(fd, mode, req);
    -}
    +fs.fchmod = function(fd, mode, callback) {
  • var req = new FSReqWrap();
  • req.oncomplete = makeCallback(callback);
  • binding.fchmod(fd, modeNum(mode), req);
    +};

-function fchmodSync(fd, mode) {

  • validateInt32(fd, 'fd', 0);
  • mode = validateMode(mode, 'mode');
  • const ctx = {};
  • binding.fchmod(fd, mode, undefined, ctx);
  • handleErrorFromBinding(ctx);
    -}
    +fs.fchmodSync = function(fd, mode) {
  • return binding.fchmod(fd, modeNum(mode));
    +};

-function lchmod(path, mode, callback) {

  • callback = maybeCallback(callback);
  • fs.open(path, O_WRONLY | O_SYMLINK, function(err, fd) {
  • if (err) {
  •  callback(err);
    
  •  return;
    
  • }
  • // Prefer to return the chmod error, if one occurs,
  • // but still try to close, and report closing errors if they occur.
  • fs.fchmod(fd, mode, function(err) {
  •  fs.close(fd, function(err2) {
    
  •    callback(err || err2);
    

+if (constants.O_SYMLINK !== undefined) {

  • fs.lchmod = function(path, mode, callback) {
  • callback = maybeCallback(callback);
  • fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) {
  •  if (err) {
    
  •    callback(err);
    
  •    return;
    
  •  }
    
  •  // Prefer to return the chmod error, if one occurs,
    
  •  // but still try to close, and report closing errors if they occur.
    
  •  fs.fchmod(fd, mode, function(err) {
    
  •    fs.close(fd, function(err2) {
    
  •      callback(err || err2);
    
  •    });
     });
    
    });
  • });
    -}
  • };

-function lchmodSync(path, mode) {

  • const fd = fs.openSync(path, O_WRONLY | O_SYMLINK);
  • fs.lchmodSync = function(path, mode) {
  • const fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK);
  • // Prefer to return the chmod error, if one occurs,
  • // but still try to close, and report closing errors if they occur.
  • let ret;
  • try {
  • ret = fs.fchmodSync(fd, mode);
  • } finally {
  • fs.closeSync(fd);
  • }
  • return ret;
  • // Prefer to return the chmod error, if one occurs,
  • // but still try to close, and report closing errors if they occur.
  • let ret;
  • try {
  •  ret = fs.fchmodSync(fd, mode);
    
  • } finally {
  •  fs.closeSync(fd);
    
  • }
  • return ret;
  • };
    }

-function chmod(path, mode, callback) {

  • path = toPathIfFileURL(path);
  • validatePath(path);
  • mode = validateMode(mode, 'mode');
    +fs.chmod = function(path, mode, callback) {
    callback = makeCallback(callback);
  • const req = new FSReqCallback();
  • if (handleError((path = getPathFromURL(path)), callback))
  • return;
  • if (!nullCheck(path, callback)) return;
  • var req = new FSReqWrap();
    req.oncomplete = callback;
    ++<<<<<<< HEAD
  • binding.chmod(pathModule._makeLong(path),
  •            modeNum(mode),
    
  •            req);
    

+};
+
+fs.chmodSync = function(path, mode) {

  • handleError((path = getPathFromURL(path)));
  • nullCheck(path);
  • return binding.chmod(pathModule._makeLong(path), modeNum(mode));
    +};

+if (constants.O_SYMLINK !== undefined) {

  • fs.lchown = function(path, uid, gid, callback) {
  • callback = maybeCallback(callback);
  • fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) {
  •  if (err) {
    
  •    callback(err);
    
  •    return;
    
  •  }
    
  •  // Prefer to return the chown error, if one occurs,
    
  •  // but still try to close, and report closing errors if they occur.
    
  •  fs.fchown(fd, uid, gid, function(err) {
    
  •    fs.close(fd, function(err2) {
    
  •      callback(err || err2);
    
  •    });
    
  •  });
    
  • });
  • };
  • fs.lchownSync = function(path, uid, gid) {
  • const fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK);
  • let ret;
  • try {
  •  ret = fs.fchownSync(fd, uid, gid);
    
  • } finally {
  •  fs.closeSync(fd);
    
  • }
  • return ret;
  • };
    ++=======
  • binding.chmod(toNamespacedPath(path), mode, req);
  • }
  • function chmodSync(path, mode) {
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • mode = validateMode(mode, 'mode');
  • const ctx = { path };
  • binding.chmod(toNamespacedPath(path), mode, undefined, ctx);
  • handleErrorFromBinding(ctx);
  • }
  • function lchown(path, uid, gid, callback) {
  • callback = makeCallback(callback);
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • validateUint32(uid, 'uid');
  • validateUint32(gid, 'gid');
  • const req = new FSReqCallback();
  • req.oncomplete = callback;
  • binding.lchown(toNamespacedPath(path), uid, gid, req);
    -}

-function lchownSync(path, uid, gid) {

  • path = toPathIfFileURL(path);
  • validatePath(path);
  • validateUint32(uid, 'uid');
  • validateUint32(gid, 'gid');
  • const ctx = { path };
  • binding.lchown(toNamespacedPath(path), uid, gid, undefined, ctx);
  • handleErrorFromBinding(ctx);
    -}

-function fchown(fd, uid, gid, callback) {

  • validateUint32(fd, 'fd');
  • validateUint32(uid, 'uid');
  • validateUint32(gid, 'gid');
  • const req = new FSReqCallback();
  • req.oncomplete = makeCallback(callback);
  • binding.fchown(fd, uid, gid, req);
    -}

-function fchownSync(fd, uid, gid) {

  • validateUint32(fd, 'fd');
  • validateUint32(uid, 'uid');
  • validateUint32(gid, 'gid');
  • const ctx = {};
  • binding.fchown(fd, uid, gid, undefined, ctx);
  • handleErrorFromBinding(ctx);
    ++ validateUint32(gid, 'gid');
    ++ const req = new FSReqCallback();
    ++ req.oncomplete = callback;
    ++ binding.lchown(toNamespacedPath(path), uid, gid, req);
  • }

-function chown(path, uid, gid, callback) {

  • callback = makeCallback(callback);
    ++function lchownSync(path, uid, gid) {
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • validateUint32(uid, 'uid');
  • validateUint32(gid, 'gid');
    ++ const ctx = { path };
    ++ binding.lchown(toNamespacedPath(path), uid, gid, undefined, ctx);
    ++ handleErrorFromBinding(ctx);
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
    +}
  • const req = new FSReqCallback();
    +fs.fchown = function(fd, uid, gid, callback) {
  • var req = new FSReqWrap();
  • req.oncomplete = makeCallback(callback);
  • binding.fchown(fd, uid, gid, req);
    +};

+fs.fchownSync = function(fd, uid, gid) {

  • return binding.fchown(fd, uid, gid);
    +};

+fs.chown = function(path, uid, gid, callback) {

  • callback = makeCallback(callback);
  • if (handleError((path = getPathFromURL(path)), callback))
  • return;
  • if (!nullCheck(path, callback)) return;
  • var req = new FSReqWrap();
    req.oncomplete = callback;
    ++<<<<<<< HEAD
  • binding.chown(pathModule._makeLong(path), uid, gid, req);
    +};

+fs.chownSync = function(path, uid, gid) {

  • handleError((path = getPathFromURL(path)));
  • nullCheck(path);
  • return binding.chown(pathModule._makeLong(path), uid, gid);
    +};

+// converts Date or number to a fractional UNIX timestamp
+function toUnixTimestamp(time) {

  • // eslint-disable-next-line eqeqeq
  • if (typeof time === 'string' && +time == time) {
  • return +time;
  • }
  • if (Number.isFinite(time)) {
  • if (time < 0) {
  •  return Date.now() / 1000;
    
  • }
  • return time;
  • }
  • if (util.isDate(time)) {
  • // convert to 123.456 UNIX timestamp
  • return time.getTime() / 1000;
  • }
  • throw new Error('Cannot parse time: ' + time);
    ++=======
  • binding.chown(toNamespacedPath(path), uid, gid, req);
  • }
  • function chownSync(path, uid, gid) {
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • validateUint32(uid, 'uid');
  • validateUint32(gid, 'gid');
  • const ctx = { path };
  • binding.chown(toNamespacedPath(path), uid, gid, undefined, ctx);
  • handleErrorFromBinding(ctx);
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
    }

-function utimes(path, atime, mtime, callback) {

  • callback = makeCallback(callback);

  • path = toPathIfFileURL(path);

  • validatePath(path);
    +// exported for unit tests, not for public consumption
    +fs._toUnixTimestamp = toUnixTimestamp;

  • const req = new FSReqCallback();
    +fs.utimes = function(path, atime, mtime, callback) {

  • callback = makeCallback(callback);
  • if (handleError((path = getPathFromURL(path)), callback))
  • return;
  • if (!nullCheck(path, callback)) return;
  • var req = new FSReqWrap();
    req.oncomplete = callback;
    ++<<<<<<< HEAD
  • binding.utimes(pathModule._makeLong(path),
    ++=======
  • binding.utimes(toNamespacedPath(path),
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
    toUnixTimestamp(atime),
    toUnixTimestamp(mtime),
    req);
    -}
    +};

++<<<<<<< HEAD
+fs.utimesSync = function(path, atime, mtime) {

  • handleError((path = getPathFromURL(path)));
  • nullCheck(path);
  • atime = toUnixTimestamp(atime);
  • mtime = toUnixTimestamp(mtime);
  • binding.utimes(pathModule._makeLong(path), atime, mtime);
    +};
    ++=======
  • function utimesSync(path, atime, mtime) {
  • path = toPathIfFileURL(path);
  • validatePath(path);
  • const ctx = { path };
  • binding.utimes(toNamespacedPath(path),
  •              toUnixTimestamp(atime), toUnixTimestamp(mtime),
    
  •              undefined, ctx);
    
  • handleErrorFromBinding(ctx);
  • }
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

-function futimes(fd, atime, mtime, callback) {

  • validateUint32(fd, 'fd');
  • atime = toUnixTimestamp(atime, 'atime');
  • mtime = toUnixTimestamp(mtime, 'mtime');
  • const req = new FSReqCallback();
    +fs.futimes = function(fd, atime, mtime, callback) {
  • atime = toUnixTimestamp(atime);
  • mtime = toUnixTimestamp(mtime);
  • var req = new FSReqWrap();
    req.oncomplete = makeCallback(callback);
    binding.futimes(fd, atime, mtime, req);
    -}
    +};

-function futimesSync(fd, atime, mtime) {

  • validateUint32(fd, 'fd');
  • atime = toUnixTimestamp(atime, 'atime');
  • mtime = toUnixTimestamp(mtime, 'mtime');
  • const ctx = {};
  • binding.futimes(fd, atime, mtime, undefined, ctx);
  • handleErrorFromBinding(ctx);
    -}
    +fs.futimesSync = function(fd, atime, mtime) {
  • atime = toUnixTimestamp(atime);
  • mtime = toUnixTimestamp(mtime);
  • binding.futimes(fd, atime, mtime);
    +};

function writeAll(fd, isUserFd, buffer, offset, length, position, callback) {
// write(fd, buffer, offset, length, position, callback)
@@@ -1473,13 -1281,13 +1798,21 @@@ StatWatcher.prototype.stop = function(

const statWatchers = new Map();

++<<<<<<< HEAD
+fs.watchFile = function(filename, options, listener) {

  • handleError((filename = getPathFromURL(filename)));
  • nullCheck(filename);
  • filename = pathModule.resolve(filename);
  • var stat;
    ++=======
  • function watchFile(filename, options, listener) {
  • filename = toPathIfFileURL(filename);
  • validatePath(filename);
  • filename = resolve(filename);
  • let stat;
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
  • const defaults = {
  • var defaults = {
    // Poll interval in milliseconds. 5007 is what libev used to use. It's
    // a little on the slow side but let's stick with it for now to keep
    // behavioral changes to a minimum.
    @@@ -1508,13 -1318,13 +1841,21 @@@

    stat.addListener('change', listener);
    return stat;
    -}
    +};

++<<<<<<< HEAD
+fs.unwatchFile = function(filename, listener) {

  • handleError((filename = getPathFromURL(filename)));

  • nullCheck(filename);

  • filename = pathModule.resolve(filename);

  • var stat = statWatchers.get(filename);
    ++=======

  • function unwatchFile(filename, listener) {

  • filename = toPathIfFileURL(filename);

  • validatePath(filename);

  • filename = resolve(filename);

  • const stat = statWatchers.get(filename);
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

    if (stat === undefined) return;

@@@ -1581,15 -1393,14 +1922,20 @@@ fs.realpathSync = function realpathSync
options = emptyObj;
else
options = getOptions(options, emptyObj);

  • p = toPathIfFileURL(p);
    if (typeof p !== 'string') {
  • p += '';
  • }
  • handleError((p = getPathFromURL(p)));
  • if (typeof p !== 'string')
  •  p += '';
    
  • }
    ++<<<<<<< HEAD
  • nullCheck(p);
  • p = pathModule.resolve(p);
    ++=======
  • validatePath(p);
  • p = resolve(p);
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
  • const cache = options[realpathCacheKey];
  • const cache = options[internalFS.realpathCacheKey];
    const maybeCachedResult = cache && cache.get(p);
    if (maybeCachedResult) {
    return maybeCachedResult;
    @@@ -1614,7 -1425,9 +1960,13 @@@

    // On windows, check that the root exists. On unix there is no need.
    if (isWindows && !knownHard[base]) {
    ++<<<<<<< HEAD

  • binding.lstat(pathModule._makeLong(base));
    ++=======

  • const ctx = { path: base };
    
  • binding.lstat(toNamespacedPath(base), false, undefined, ctx);
    
  • handleErrorFromBinding(ctx);
    

++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
knownHard[base] = true;
}

@@@ -1653,10 -1466,12 +2005,17 @@@
// Use stats array directly to avoid creating an fs.Stats instance just
// for our internal use.

++<<<<<<< HEAD

  •  var baseLong = pathModule._makeLong(base);
    
  •  binding.lstat(baseLong);
    

++=======

  •   const baseLong = toNamespacedPath(base);
    
  •   const ctx = { path: base };
    
  •   const stats = binding.lstat(baseLong, false, undefined, ctx);
    
  •   handleErrorFromBinding(ctx);
    

++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

  •  if (!isFileType(stats, S_IFLNK)) {
    
  •  if ((statValues[1/*mode*/] & S_IFMT) !== S_IFLNK) {
       knownHard[base] = true;
       if (cache) cache.set(base, base);
       continue;
    

@@@ -1675,10 -1490,13 +2034,10 @@@
}
}
if (linkTarget === null) {

  •    const ctx = { path: base };
    
  •    binding.stat(baseLong, false, undefined, ctx);
    
  •    handleErrorFromBinding(ctx);
    
  •    linkTarget = binding.readlink(baseLong, undefined, undefined, ctx);
    
  •    handleErrorFromBinding(ctx);
    
  •    binding.stat(baseLong);
    
  •    linkTarget = binding.readlink(baseLong);
     }
    
  •   resolvedLink = pathModule.resolve(previous, linkTarget);
    
  •   resolvedLink = resolve(previous, linkTarget);
    
      if (cache) cache.set(base, resolvedLink);
      if (!isWindows) seenLinks[id] = linkTarget;
    

@@@ -1693,7 -1511,9 +2052,13 @@@

  // On windows, check that the root exists. On unix there is no need.
  if (isWindows && !knownHard[base]) {

++<<<<<<< HEAD

  •  binding.lstat(pathModule._makeLong(base));
    

++=======

  •   const ctx = { path: base };
    
  •   binding.lstat(toNamespacedPath(base), false, undefined, ctx);
    
  •   handleErrorFromBinding(ctx);
    

++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
knownHard[base] = true;
}
}
@@@ -1709,15 -1540,12 +2074,20 @@@ fs.realpath = function realpath(p, opti
options = emptyObj;
else
options = getOptions(options, emptyObj);

  • p = toPathIfFileURL(p);
    if (typeof p !== 'string') {
  • p += '';
  • if (handleError((p = getPathFromURL(p)), callback))

  •  return;
    
  • if (typeof p !== 'string')

  •  p += '';
    

    }
    ++<<<<<<< HEAD

  • if (!nullCheck(p, callback))

  • return;

  • p = pathModule.resolve(p);
    ++=======

  • validatePath(p);

  • p = resolve(p);
    ++>>>>>>> 401ae38... lib: destructuring assignment path module in fs

    const seenLinks = Object.create(null);
    const knownHard = Object.create(null);
    @@@ -1816,8 -1641,7 +2186,12 @@@
    function gotTarget(err, target, base) {
    if (err) return callback(err);

++<<<<<<< HEAD

  • var resolvedLink = pathModule.resolve(previous, target);
  • gotResolvedLink(resolvedLink);
    ++=======
  • gotResolvedLink(resolve(previous, target));
    

++>>>>>>> 401ae38... lib: destructuring assignment path module in fs
}

function gotResolvedLink(resolvedLink) {

@@@ -1875,388 -1707,198 +2249,388 @@@ fs.copyFile = function(src, dest, flags
callback = flags;
flags = 0;
} else if (typeof callback !== 'function') {

  • throw new ERR_INVALID_CALLBACK();
  • throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'callback', 'function');
    }
  • src = toPathIfFileURL(src);
  • dest = toPathIfFileURL(dest);
  • validatePath(src, 'src');
  • validatePath(dest, 'dest');
  • src = getPathFromURL(src);
  • if (handleError(src, callback))
  • return;
  • if (!nullCheck(src, callback))
  • return;
  • dest = getPathFromURL(dest);
  • if (handleError(dest, callback))
  • return;
  • if (!nullCheck(dest, callback))
  • return;
  • src = pathModule._makeLong(src);
  • dest = pathModule._makeLong(dest);
  • src = _makeLong(src);
  • dest = _makeLong(dest);
    flags = flags | 0;
  • const req = new FSReqCallback();
  • const req = new FSReqWrap();
    req.oncomplete = makeCallback(callback);
    binding.copyFile(src, dest, flags, req);
    -}
    +};

-function copyFileSync(src, dest, flags) {

  • src = toPathIfFileURL(src);
  • dest = toPathIfFileURL(dest);
  • validatePath(src, 'src');
  • validatePath(dest, 'dest');
    +fs.copyFileSync = function(src, dest, flags) {
  • src = getPathFromURL(src);
  • handleError(src);
  • nullCheck(src);
  • const ctx = { path: src, dest }; // non-prefixed
  • dest = getPathFromURL(dest);
  • handleError(dest);
  • nullCheck(dest);
  • src = pathModule._makeLong(src);
  • dest = pathModule._makeLong(dest);
  • src = _makeLong(src);
  • dest = _makeLong(dest);
    flags = flags | 0;
  • binding.copyFile(src, dest, flags, undefined, ctx);
  • handleErrorFromBinding(ctx);
  • binding.copyFile(src, dest, flags);
    +};

+var pool;
+
+function allocNewPool(poolSize) {

  • pool = Buffer.allocUnsafe(poolSize);
  • pool.used = 0;
    }

-function lazyLoadStreams() {

  • if (!ReadStream) {
  • ({ ReadStream, WriteStream } = require('internal/fs/streams'));
  • [ FileReadStream, FileWriteStream ] = [ ReadStream, WriteStream ];

+fs.createReadStream = function(path, options) {

  • return new ReadStream(path, options);
    +};

+util.inherits(ReadStream, Readable);
+fs.ReadStream = ReadStream;
+
+function ReadStream(path, options) {

  • if (!(this instanceof ReadStream))
  • return new ReadStream(path, options);
  • // a little bit bigger buffer and water marks by default
  • options = copyObject(getOptions(options, {}));
  • if (options.highWaterMark === undefined)
  • options.highWaterMark = 64 * 1024;
  • Readable.call(this, options);
  • handleError((this.path = getPathFromURL(path)));
  • this.fd = options.fd === undefined ? null : options.fd;
  • this.flags = options.flags === undefined ? 'r' : options.flags;
  • this.mode = options.mode === undefined ? 0o666 : options.mode;
  • this.start = options.start;
  • this.end = options.end;
  • this.autoClose = options.autoClose === undefined ? true : options.autoClose;
  • this.pos = undefined;
  • this.bytesRead = 0;
  • if (this.start !== undefined) {
  • if (typeof this.start !== 'number') {
  •  throw new TypeError('"start" option must be a Number');
    
  • }
  • if (this.end === undefined) {
  •  this.end = Infinity;
    
  • } else if (typeof this.end !== 'number') {
  •  throw new TypeError('"end" option must be a Number');
    
  • }
  • if (this.start > this.end) {
  •  throw new Error('"start" option must be <= "end" option');
    
  • }
  • this.pos = this.start;
    }
  • // Backwards compatibility: Make sure end is a number regardless of start.
  • // TODO(addaleax): Make the above typecheck not depend on start instead.
  • // (That is a semver-major change).
  • if (typeof this.end !== 'number')
  • this.end = Infinity;
  • if (typeof this.fd !== 'number')
  • this.open();
  • this.on('end', function() {
  • if (this.autoClose) {
  •  this.destroy();
    
  • }
  • });
    }

-function createReadStream(path, options) {

  • lazyLoadStreams();
  • return new ReadStream(path, options);
    +fs.FileReadStream = fs.ReadStream; // support the legacy name

+ReadStream.prototype.open = function() {

  • var self = this;
  • fs.open(this.path, this.flags, this.mode, function(er, fd) {
  • if (er) {
  •  if (self.autoClose) {
    
  •    self.destroy();
    
  •  }
    
  •  self.emit('error', er);
    
  •  return;
    
  • }
  • self.fd = fd;
  • self.emit('open', fd);
  • self.emit('ready');
  • // start the flow of data.
  • self.read();
  • });
    +};

+ReadStream.prototype._read = function(n) {

  • if (typeof this.fd !== 'number') {
  • return this.once('open', function() {
  •  this._read(n);
    
  • });
  • }
  • if (this.destroyed)
  • return;
  • if (!pool || pool.length - pool.used < kMinPoolSpace) {
  • // discard the old pool.
  • allocNewPool(this.readableHighWaterMark);
  • }
  • // Grab another reference to the pool in the case that while we're
  • // in the thread pool another read() finishes up the pool, and
  • // allocates a new one.
  • var thisPool = pool;
  • var toRead = Math.min(pool.length - pool.used, n);
  • var start = pool.used;
  • if (this.pos !== undefined)
  • toRead = Math.min(this.end - this.pos + 1, toRead);
  • else
  • toRead = Math.min(this.end - this.bytesRead + 1, toRead);
  • // already read everything we were supposed to read!
  • // treat as EOF.
  • if (toRead <= 0)
  • return this.push(null);
  • // the actual read.
  • fs.read(this.fd, pool, pool.used, toRead, this.pos, (er, bytesRead) => {
  • if (er) {
  •  if (this.autoClose) {
    
  •    this.destroy();
    
  •  }
    
  •  this.emit('error', er);
    
  • } else {
  •  var b = null;
    
  •  if (bytesRead > 0) {
    
  •    this.bytesRead += bytesRead;
    
  •    b = thisPool.slice(start, start + bytesRead);
    
  •  }
    
  •  this.push(b);
    
  • }
  • });
  • // move the pool positions, and internal position for reading.
  • if (this.pos !== undefined)
  • this.pos += toRead;
  • pool.used += toRead;
    +};

+ReadStream.prototype._destroy = function(err, cb) {

  • this.close(function(err2) {
  • cb(err || err2);
  • });
    +};

+ReadStream.prototype.close = function(cb) {

  • if (cb)
  • this.once('close', cb);
  • if (this.closed || typeof this.fd !== 'number') {
  • if (typeof this.fd !== 'number') {
  •  this.once('open', closeOnOpen);
    
  •  return;
    
  • }
  • return process.nextTick(() => this.emit('close'));
  • }
  • this.closed = true;
  • fs.close(this.fd, (er) => {
  • if (er)
  •  this.emit('error', er);
    
  • else
  •  this.emit('close');
    
  • });
  • this.fd = null;
    +};

+// needed because as it will be called with arguments
+// that does not match this.close() signature
+function closeOnOpen(fd) {

  • this.close();
    }

-function createWriteStream(path, options) {

  • lazyLoadStreams();
    +fs.createWriteStream = function(path, options) {
    return new WriteStream(path, options);
    +};

+util.inherits(WriteStream, Writable);
+fs.WriteStream = WriteStream;
+function WriteStream(path, options) {

  • if (!(this instanceof WriteStream))
  • return new WriteStream(path, options);
  • options = copyObject(getOptions(options, {}));
  • Writable.call(this, options);
  • handleError((this.path = getPathFromURL(path)));
  • this.fd = options.fd === undefined ? null : options.fd;
  • this.flags = options.flags === undefined ? 'w' : options.flags;
  • this.mode = options.mode === undefined ? 0o666 : options.mode;
  • this.start = options.start;
  • this.autoClose = options.autoClose === undefined ? true : !!options.autoClose;
  • this.pos = undefined;
  • this.bytesWritten = 0;
  • if (this.start !== undefined) {
  • if (typeof this.start !== 'number') {
  •  throw new TypeError('"start" option must be a Number');
    
  • }
  • if (this.start < 0) {
  •  throw new Error('"start" must be >= zero');
    
  • }
  • this.pos = this.start;
  • }
  • if (options.encoding)
  • this.setDefaultEncoding(options.encoding);
  • if (typeof this.fd !== 'number')
  • this.open();
  • // dispose on finish.
  • this.once('finish', function() {
  • if (this.autoClose) {
  •  this.close();
    
  • }
  • });
    }

+fs.FileWriteStream = fs.WriteStream; // support the legacy name
+
+
+WriteStream.prototype.open = function() {

  • fs.open(this.path, this.flags, this.mode, (er, fd) => {
  • if (er) {
  •  if (this.autoClose) {
    
  •    this.destroy();
    
  •  }
    
  •  this.emit('error', er);
    
  •  return;
    
  • }

-module.exports = fs = {

  • appendFile,
  • appendFileSync,
  • access,
  • accessSync,
  • chown,
  • chownSync,
  • chmod,
  • chmodSync,
  • close,
  • closeSync,
  • copyFile,
  • copyFileSync,
  • createReadStream,
  • createWriteStream,
  • exists,
  • existsSync,
  • fchown,
  • fchownSync,
  • fchmod,
  • fchmodSync,
  • fdatasync,
  • fdatasyncSync,
  • fstat,
  • fstatSync,
  • fsync,
  • fsyncSync,
  • ftruncate,
  • ftruncateSync,
  • futimes,
  • futimesSync,
  • lchown,
  • lchownSync,
  • lchmod: constants.O_SYMLINK !== undefined ? lchmod : undefined,
  • lchmodSync: constants.O_SYMLINK !== undefined ? lchmodSync : undefined,
  • link,
  • linkSync,
  • lstat,
  • lstatSync,
  • mkdir,
  • mkdirSync,
  • mkdtemp,
  • mkdtempSync,
  • open,
  • openSync,
  • readdir,
  • readdirSync,
  • read,
  • readSync,
  • readFile,
  • readFileSync,
  • readlink,
  • readlinkSync,
  • realpath,
  • realpathSync,
  • rename,
  • renameSync,
  • rmdir,
  • rmdirSync,
  • stat,
  • statSync,
  • symlink,
  • symlinkSync,
  • truncate,
  • truncateSync,
  • unwatchFile,
  • unlink,
  • unlinkSync,
  • utimes,
  • utimesSync,
  • watch,
  • watchFile,
  • writeFile,
  • writeFileSync,
  • write,
  • writeSync,
  • Dirent,
  • Stats,
  • get ReadStream() {
  • lazyLoadStreams();
  • return ReadStream;
  • },
  • set ReadStream(val) {
  • ReadStream = val;
  • },
  • get WriteStream() {
  • lazyLoadStreams();
  • return WriteStream;
  • },
  • set WriteStream(val) {
  • WriteStream = val;
  • },
  • // Legacy names... these have to be separate because of how graceful-fs
  • // (and possibly other) modules monkey patch the values.
  • get FileReadStream() {
  • lazyLoadStreams();
  • return FileReadStream;
  • },
  • set FileReadStream(val) {
  • FileReadStream = val;
  • },
  • get FileWriteStream() {
  • lazyLoadStreams();
  • return FileWriteStream;
  • },
  • set FileWriteStream(val) {
  • FileWriteStream = val;
  • },
  • // For tests
  • _toUnixTimestamp: toUnixTimestamp
  • this.fd = fd;
  • this.emit('open', fd);
  • this.emit('ready');
  • });
    };

-Object.defineProperties(fs, {

  • F_OK: { enumerable: true, value: F_OK || 0 },
  • R_OK: { enumerable: true, value: R_OK || 0 },
  • W_OK: { enumerable: true, value: W_OK || 0 },
  • X_OK: { enumerable: true, value: X_OK || 0 },
  • constants: {
  • configurable: false,
  • enumerable: true,
  • value: constants
  • },
  • promises: {
  • configurable: true,
  • enumerable: false,
  • get() {
  •  if (promisesWarn) {
    
  •    promises = require('internal/fs/promises');
    
  •    promisesWarn = false;
    
  •    process.emitWarning('The fs.promises API is experimental',
    
  •                        'ExperimentalWarning');
    

+WriteStream.prototype._write = function(data, encoding, cb) {

  • if (!(data instanceof Buffer))
  • return this.emit('error', new Error('Invalid data'));
  • if (typeof this.fd !== 'number') {
  • return this.once('open', function() {
  •  this._write(data, encoding, cb);
    
  • });
  • }
  • fs.write(this.fd, data, 0, data.length, this.pos, (er, bytes) => {
  • if (er) {
  •  if (this.autoClose) {
    
  •    this.destroy();
     }
    
  •  return promises;
    
  •  return cb(er);
    
    }
  • this.bytesWritten += bytes;
  • cb();
  • });
  • if (this.pos !== undefined)
  • this.pos += data.length;
    +};

+function writev(fd, chunks, position, callback) {

  • function wrapper(err, written) {
  • // Retain a reference to chunks so that they can't be GC'ed too soon.
  • callback(err, written || 0, chunks);
  • }
  • const req = new FSReqWrap();
  • req.oncomplete = wrapper;
  • binding.writeBuffers(fd, chunks, position, req);
    +}

+WriteStream.prototype._writev = function(data, cb) {

  • if (typeof this.fd !== 'number') {
  • return this.once('open', function() {
  •  this._writev(data, cb);
    
  • });
  • }
  • const self = this;
  • const len = data.length;
  • const chunks = new Array(len);
  • var size = 0;
  • for (var i = 0; i < len; i++) {
  • var chunk = data[i].chunk;
  • chunks[i] = chunk;
  • size += chunk.length;
    }
  • writev(this.fd, chunks, this.pos, function(er, bytes) {
  • if (er) {
  •  self.destroy();
    
  •  return cb(er);
    
  • }
  • self.bytesWritten += bytes;
  • cb();
  • });
  • if (this.pos !== undefined)
  • this.pos += size;
    +};

+WriteStream.prototype._destroy = ReadStream.prototype._destroy;
+WriteStream.prototype.close = ReadStream.prototype.close;
+
+// There is no shutdown() for files.
+WriteStream.prototype.destroySoon = WriteStream.prototype.end;
+
+// SyncWriteStream is internal. DO NOT USE.
+// This undocumented API was never intended to be made public.
+var SyncWriteStream = internalFS.SyncWriteStream;
+Object.defineProperty(fs, 'SyncWriteStream', {

  • configurable: true,
  • get: internalUtil.deprecate(() => SyncWriteStream,
  •                          'fs.SyncWriteStream is deprecated.', 'DEP0061'),
    
  • set: internalUtil.deprecate((val) => { SyncWriteStream = val; },
  •                          'fs.SyncWriteStream is deprecated.', 'DEP0061')
    

});

  • Unmerged path lib/internal/fs/promises.js
  • Unmerged path lib/internal/fs/utils.js
</details>

@ZYSzys
Copy link
Member Author

ZYSzys commented Sep 13, 2018

Can we just land this in the future version ?
Or maybe I can do refactor on v8.x-staging manually by making a PR ?

@apapirovski
Copy link
Member

@ZYSzys the problem is even if you backport this, it might interfere with other backports that haven't been done. Unless you want to make sure we're fully caught up on v8.x fs backports.

@ZYSzys
Copy link
Member Author

ZYSzys commented Sep 13, 2018

Oh, my fault😅. It seems there are such big works need to de done. I'm going to give up this refactor😬.

And by the way, do we have the plan to using destructuring assignment to refactor require modules ? Or maybe in the future ?

@@ -40,7 +40,7 @@ const {
} = constants;

const { _extend } = require('util');
const pathModule = require('path');
const { _makeLong, toNamespacedPath, resolve } = require('path');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that moving to this approach does have an impact on the ability to monkeypatch these methods. That, by itself is not a problem, but I believe it does make this PR semver-major

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you mean that we will handle this in the future ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, switching this now is fine, it just means there is a non-zero risk of breaking some code so it has to be treated as a semver-major.

@jasnell jasnell added the semver-major PRs that contain breaking changes and should be released in the next major version. label Sep 13, 2018
@Trott Trott dismissed their stale review September 13, 2018 17:25

Since it's semver-major, backporting is a non-issue so I'm dismissing my objection.

@Trott Trott added needs-ci PRs that need a full CI run. needs-citgm PRs that need a CITGM CI run. labels Sep 14, 2018
@addaleax addaleax added needs-ci PRs that need a full CI run. needs-citgm PRs that need a CITGM CI run. and removed needs-ci PRs that need a full CI run. needs-citgm PRs that need a CITGM CI run. labels Sep 16, 2018
@addaleax
Copy link
Member

@ZYSzys Can you rebase this PR?

@addaleax
Copy link
Member

@ZYSzys Sorry, but we need an update using git rebase, not git pull or git merge – otherwise CI won’t accept your patches :/

@ZYSzys
Copy link
Member Author

ZYSzys commented Sep 16, 2018

Sorry, I simply fixed the conflicts on my phone.
And I will change it tomorrow when I have my laptop.

@ZYSzys ZYSzys force-pushed the fs-refactor branch 2 times, most recently from f7744f5 to bbb5d2c Compare September 17, 2018 11:10
@ZYSzys
Copy link
Member Author

ZYSzys commented Sep 17, 2018

@addaleax Ha, is this OK ? (Sorry, I'm not so export in git😅)
screen shot 2018-09-17 at 7 22 45 pm

@addaleax
Copy link
Member

@addaleax addaleax removed needs-ci PRs that need a full CI run. needs-citgm PRs that need a CITGM CI run. labels Sep 17, 2018
@Trott
Copy link
Member

Trott commented Nov 30, 2018

@ZYSzys Sorry about this, but can you rebase again? There's one conflict.

@ZYSzys
Copy link
Member Author

ZYSzys commented Nov 30, 2018

@Trott I think it should be ok now :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fs Issues and PRs related to the fs subsystem / file system. semver-major PRs that contain breaking changes and should be released in the next major version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants