This repository was archived by the owner on Oct 30, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 214
/
Copy pathutil.js
129 lines (113 loc) · 3.65 KB
/
util.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
* Copyright (c) 2013, Yahoo! Inc. All rights reserved.
* Copyrights licensed under the New BSD License.
* See the accompanying LICENSE file for terms.
*/
/*jslint node:true, nomen: true, stupid:true*/
'use strict';
var libfs = require('fs'),
libpath = require('path'),
libyaml = require('js-yaml');
/**
Extends object with properties from other objects.
var a = { foo: 'bar' }
, b = { bar: 'baz' }
, c = { baz: 'xyz' };
utils.extends(a, b, c);
// a => { foo: 'bar', bar: 'baz', baz: 'xyz' }
@method extend
@param {Object} obj the receiver object to be extended
@param {Object*} supplier objects
@return {Object} The extended object
**/
function extend(obj) {
Array.prototype.slice.call(arguments, 1).forEach(function (source) {
var key;
if (!source) { return; }
for (key in source) {
if (source.hasOwnProperty(key)) {
obj[key] = source[key];
}
}
});
return obj;
}
/**
Produces a normalized web path by joining all the parts and normalizing the
filesystem-like path into web compatible url. This is useful when you have to
generate urls based on filesystem path where unix uses `/` and windows uses `\\`.
Node is pretty smart and it will do the heavy lifting, we just need to adjust
the separtor so it uses the `/`. This method also support relative and absolute
paths.
util.webpath('foo/bar' ,'baz');
// => foo/bar/baz
util.webpath('foo\\bar', 'baz/');
// => foo/bar/baz/
util.webpath('./foo/bar', './baz');
// => foo/bar/baz
util.webpath(['foo', 'bar', 'baz']);
// => foo/bar/baz
@method webpath
@param {Array|String*} url the list of parts to be joined and normalized
@return {String} The joined and normalized url
**/
function webpath(url) {
var args = [].concat.apply([], arguments),
parts = libpath.join.apply(libpath, args).split(libpath.sep);
return parts.join('/');
}
/**
* Reads and parses a JSON or YAML structured file.
*
* NOTE: Does not parse YCB bundles.
*
* @method readConfig
* @param {string} fullPath path to JSON or YAML file
* @return {user-defined} contents of file as an object
*/
function readConfig(fullPath) {
var extensions = ['.yml', '.yaml', '.json'],
basename, // everything except the extension
i,
json = false,
raw,
obj;
basename = fullPath;
if (libpath.extname(fullPath)) {
basename = fullPath.slice(0, libpath.extname(fullPath).length * -1);
}
for (i = extensions.length - 1; i >= 0; i -= 1) {
try {
fullPath = basename + extensions[i];
raw = libfs.readFileSync(fullPath, 'utf8');
try {
if (i === 2) { // json
obj = JSON.parse(raw);
json = true;
} else { // yaml or yml
obj = libyaml.load(raw);
if (json) {
console.warn('WARN: ' + basename + extensions[2] + ' exists but ' + extensions[i] + ' file will be used instead');
}
}
// TODO: what happen when one of them exists?
// and what then more than one exists?
} catch (parseErr) {
throw new Error(parseErr);
}
} catch (err) {
if (err.code !== 'ENOENT') { // if the error was not "no such file or directory" report it
throw new Error("Error parsing file: " + fullPath + "\n" + err);
}
}
}
if (!obj) {
obj = {};
}
return obj;
}
module.exports = {
extend: extend,
readConfig: readConfig,
webpath: webpath
};