Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

FIRST!

  • Loading branch information...
commit ee3275e6341b40ec181209e2fd6bb69d53dccbd2 0 parents
Kris Kowal authored
Showing with 366 additions and 0 deletions.
  1. +19 −0 LICENSE
  2. +19 −0 README
  3. +299 −0 fs-boot.js
  4. +29 −0 package.json
19 LICENSE
@@ -0,0 +1,19 @@
+
+Copyright 2009, 2010 Kristopher Michael Kowal. All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
19 README
@@ -0,0 +1,19 @@
+
+API
+
+ ROOT
+ SEPARATOR
+ ALT_SEPARATOR
+ SEPARATORS_RE()
+ split(path)
+ join(...path)
+ resolve(...path)
+ normal(...path)
+ isAbsolute(path)
+ isRelative(path)
+ isRoot(path)
+ root(path)
+ directory(path)
+ base(path, extension_opt)
+ extension(path)
+
299 fs-boot.js
@@ -0,0 +1,299 @@
+
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson TODO
+
+/**
+ * Pure JavaScript implementations of file system path
+ * manipulation.
+ *
+ * This module depends on the non CommonJS "engine" module,
+ * particularly for an "os" property that has the words
+ * "windows" or "winnt" to distinguish Windows from Unix
+ * file systems.
+ */
+
+// NOTE: this file may be used is the engine bootstrapping
+// process, so any "requires" must be accounted for in
+// narwhal.js
+
+/*whatsupdoc*/
+/*markup markdown*/
+
+var os = typeof process !== "undefined"?
+ process.platform :
+ require("narwhal/engine").os;
+var isWindows = /\bwind?(nt|ows)\b/i.test(os);
+
+/**
+ * @name ROOT
+ * * `/` on Unix
+ * * `\` on Windows
+ */
+
+/**
+ * @name SEPARATOR
+ * * `/` on Unix
+ * * `\` on Windows
+ */
+
+/**
+ * @name ALT_SEPARATOR
+ * * undefined on Unix
+ * * `/` on Windows
+ */
+
+if (isWindows) {
+ exports.ROOT = "\\";
+ exports.SEPARATOR = "\\";
+ exports.ALT_SEPARATOR = "/";
+} else {
+ exports.ROOT = "/";
+ exports.SEPARATOR = "/";
+ exports.ALT_SEPARATOR = undefined;
+}
+
+// we need to make sure the separator regex is always in sync with the separators.
+// this caches the generated regex and rebuild if either separator changes.
+var separatorCached, altSeparatorCached, separatorReCached;
+/**
+ * @function
+ */
+exports.SEPARATORS_RE = function () {
+ if (
+ separatorCached !== exports.SEPARATOR ||
+ altSeparatorCached !== exports.ALT_SEPARATOR
+ ) {
+ separatorCached = exports.SEPARATOR;
+ altSeparatorCached = exports.ALT_SEPARATOR;
+ separatorReCached = new RegExp("[" +
+ (separatorCached || '').replace(/[-[\]{}()*+?.\\^$|,#\s]/g, "\\$&") +
+ (altSeparatorCached || '').replace(/[-[\]{}()*+?.\\^$|,#\s]/g, "\\$&") +
+ "]", "g");
+ }
+ return separatorReCached;
+}
+
+/**
+ * separates a path into components. If the path is
+ * absolute, the first path component is the root of the
+ * file system, indicated by an empty string on Unix, and a
+ * drive letter followed by a colon on Windows.
+ * @returns {Array * String}
+ */
+exports.split = function (path) {
+ var parts;
+ try {
+ parts = String(path).split(exports.SEPARATORS_RE());
+ } catch (exception) {
+ throw new Error("Cannot split " + (typeof path) + ', "' + path + '"');
+ }
+ // this special case helps isAbsolute
+ // distinguish an empty path from an absolute path
+ // "" -> [] NOT [""]
+ if (parts.length == 1 && parts[0] == "")
+ return [];
+ // "a" -> ["a"]
+ // "/a" -> ["", "a"]
+ return parts;
+};
+
+/**
+ * Takes file system paths as variadic arguments and treats
+ * each as a file or directory path and returns the path
+ * arrived by traversing into the those paths. All
+ * arguments except for the last must be paths to
+ * directories for the result to be meaningful.
+ * @returns {String} path
+ */
+exports.join = function () {
+ if (arguments.length === 1 && typeof arguments[0] === "object")
+ return exports.normal.apply(exports, arguments[0]);
+ return exports.normal.apply(exports, arguments);
+};
+
+/**
+ * Takes file system paths as variadic arguments and treats
+ * each path as a location, in the URL sense, resolving each
+ * new location based on the previous. For example, if the
+ * first argument is the absolute path of a JSON file, and
+ * the second argument is a path mentioned in that JSON
+ * file, `resolve` returns the absolute path of the
+ * mentioned file.
+ * @returns {String} path
+ */
+exports.resolve = function () {
+ var root = "";
+ var parents = [];
+ var children = [];
+ var leaf = "";
+ for (var i = 0; i < arguments.length; i++) {
+ var path = String(arguments[i]);
+ if (path == "")
+ continue;
+ var parts = path.split(exports.SEPARATORS_RE());
+ if (exports.isAbsolute(path)) {
+ root = parts.shift() + exports.SEPARATOR;
+ parents = [];
+ children = [];
+ }
+ leaf = parts.pop();
+ if (leaf == "." || leaf == "..") {
+ parts.push(leaf);
+ leaf = "";
+ }
+ for (var j = 0; j < parts.length; j++) {
+ var part = parts[j];
+ if (part == "." || part == '') {
+ } else if (part == "..") {
+ if (children.length) {
+ children.pop();
+ } else {
+ if (root) {
+ } else {
+ parents.push("..");
+ }
+ }
+ } else {
+ children.push(part);
+ }
+ };
+ }
+ path = parents.concat(children).join(exports.SEPARATOR);
+ if (path) leaf = exports.SEPARATOR + leaf;
+ return root + path + leaf;
+};
+
+/**
+ * Takes paths as any number of arguments and reduces them
+ * into a single path in normal form, removing all "." path
+ * components, and reducing ".." path components by removing
+ * the previous path component if possible.
+ * @returns {String} path
+ */
+exports.normal = function () {
+ var root = "";
+ var parents = [];
+ var children = [];
+ for (var i = 0, ii = arguments.length; i < ii; i++) {
+ var path = String(arguments[i]);
+ // empty paths have no affect
+ if (path === "")
+ continue;
+ var parts = path.split(exports.SEPARATORS_RE());
+ if (exports.isAbsolute(path)) {
+ root = parts.shift() + exports.SEPARATOR;
+ parents = [];
+ children = [];
+ }
+ for (var j = 0, jj = parts.length; j < jj; j++) {
+ var part = parts[j];
+ if (part == "." || part == '') {
+ } else if (part == "..") {
+ if (children.length) {
+ children.pop();
+ } else {
+ if (root) {
+ } else {
+ parents.push("..");
+ }
+ }
+ } else {
+ children.push(part);
+ }
+ }
+ }
+ path = parents.concat(children).join(exports.SEPARATOR);
+ return root + path;
+};
+
+/***
+ * @returns {Boolean} whether the given path begins at the
+ * root of the file system or a drive letter.
+ */
+exports.isAbsolute = function (path) {
+ // for absolute paths on any operating system,
+ // the first path component always determines
+ // whether it is relative or absolute. On Unix,
+ // it is empty, so ['', 'foo'].join('/') == '/foo',
+ // '/foo'.split('/') == ['', 'foo'].
+ var parts = exports.split(path);
+ // split('') == []. '' is not absolute.
+ // split('/') == ['', ''] is absolute.
+ // split(?) == [''] does not occur.
+ if (parts.length == 0)
+ return false;
+ return exports.isRoot(parts[0]);
+};
+
+/**
+ * @returns {Boolean} whether the given path does not begin
+ * at the root of the file system or a drive letter.
+ */
+exports.isRelative = function (path) {
+ return !exports.isAbsolute(path);
+};
+
+/**
+ * @returns {Boolean} whether the given path component
+ * corresponds to the root of the file system or a drive
+ * letter, as applicable.
+ */
+exports.isRoot = function (first) {
+ if (isWindows) {
+ return /:$/.test(first);
+ } else {
+ return first == "";
+ }
+};
+
+/**
+ * @returns {String} the Unix root path or corresponding
+ * Windows drive for a given path.
+ */
+exports.root = function (path) {
+ if (!exports.isAbsolute(path))
+ path = require("./fs").absolute(path);
+ var parts = exports.split(path);
+ return exports.join(parts[0], '');
+};
+
+/**
+ * @returns {String} the parent directory of the given path.
+ */
+exports.directory = function (path) {
+ var parts = exports.split(path);
+ // XXX needs to be sensitive to the root for
+ // Windows compatibility
+ parts.pop();
+ return parts.join(exports.SEPARATOR) || ".";
+};
+
+/**
+ * @returns {String} the last component of a path, without
+ * the given extension if the extension is provided and
+ * matches the given file.
+ * @param {String} path
+ * @param {String} extention an optional extention to detect
+ * and remove if it exists.
+ */
+exports.base = function (path, extension) {
+ var base = path.split(exports.SEPARATORS_RE()).pop();
+ if (extension)
+ base = base.replace(
+ new RegExp(RegExp.escape(extension) + '$'),
+ ''
+ );
+ return base;
+};
+
+/**
+ * @returns {String} the extension (e.g., `txt`) of the file
+ * at the given path.
+ */
+exports.extension = function (path) {
+ path = exports.base(path);
+ path = path.replace(/^\.*/, '');
+ var index = path.lastIndexOf(".");
+ return index <= 0 ? "" : path.substring(index);
+};
+
29 package.json
@@ -0,0 +1,29 @@
+{
+ "name": "fs-boot",
+ "description": "Pure JavaScript implementation of common file-system API components",
+ "version": "0.0.0",
+ "homepage": "http://github.com/kriskowal/fs-boot/",
+ "author": "Kris Kowal <kris@cixar.com> (http://github.com/kriskowal/)",
+ "bugs": {
+ "mail": "kris@cixar.com",
+ "web": "http://github.com/kriskowal/fs-boot/issues"
+ },
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "http://github.com/kriskowal/fs-boot/raw/master/LICENSE"
+ }
+ ],
+ "main": "fs-boot.js",
+ "dependencies": {
+ "util": ">=0.0.0",
+ "q": ">=0.0.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/kriskowal/fs-boot.git"
+ },
+ "engines": {
+ "node": ">=0.2.0"
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.