Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. var os = require('os');
  2. var fs = require('fs');
  3. var _ls = require('./ls');
  4. // Module globals
  5. var config = {
  6. silent: false,
  7. fatal: false
  8. };
  9. exports.config = config;
  10. var state = {
  11. error: null,
  12. currentCmd: 'shell.js',
  13. tempDir: null
  14. };
  15. exports.state = state;
  16. var platform = os.type().match(/^Win/) ? 'win' : 'unix';
  17. exports.platform = platform;
  18. function log() {
  19. if (!config.silent)
  20. console.log.apply(this, arguments);
  21. }
  22. exports.log = log;
  23. // Shows error message. Throws unless _continue or config.fatal are true
  24. function error(msg, _continue) {
  25. if (state.error === null)
  26. state.error = '';
  27. state.error += state.currentCmd + ': ' + msg + '\n';
  28. if (msg.length > 0)
  29. log(state.error);
  30. if (config.fatal)
  31. process.exit(1);
  32. if (!_continue)
  33. throw '';
  34. }
  35. exports.error = error;
  36. // In the future, when Proxies are default, we can add methods like `.to()` to primitive strings.
  37. // For now, this is a dummy function to bookmark places we need such strings
  38. function ShellString(str) {
  39. return str;
  40. }
  41. exports.ShellString = ShellString;
  42. // Returns {'alice': true, 'bob': false} when passed a dictionary, e.g.:
  43. // parseOptions('-a', {'a':'alice', 'b':'bob'});
  44. function parseOptions(str, map) {
  45. if (!map)
  46. error('parseOptions() internal error: no map given');
  47. // All options are false by default
  48. var options = {};
  49. for (var letter in map)
  50. options[map[letter]] = false;
  51. if (!str)
  52. return options; // defaults
  53. if (typeof str !== 'string')
  54. error('parseOptions() internal error: wrong str');
  55. // e.g. match[1] = 'Rf' for str = '-Rf'
  56. var match = str.match(/^\-(.+)/);
  57. if (!match)
  58. return options;
  59. // e.g. chars = ['R', 'f']
  60. var chars = match[1].split('');
  61. chars.forEach(function(c) {
  62. if (c in map)
  63. options[map[c]] = true;
  64. else
  65. error('option not recognized: '+c);
  66. });
  67. return options;
  68. }
  69. exports.parseOptions = parseOptions;
  70. // Expands wildcards with matching (ie. existing) file names.
  71. // For example:
  72. // expand(['file*.js']) = ['file1.js', 'file2.js', ...]
  73. // (if the files 'file1.js', 'file2.js', etc, exist in the current dir)
  74. function expand(list) {
  75. var expanded = [];
  76. list.forEach(function(listEl) {
  77. // Wildcard present on directory names ?
  78. if(listEl.search(/\*[^\/]*\//) > -1 || listEl.search(/\*\*[^\/]*\//) > -1) {
  79. var match = listEl.match(/^([^*]+\/|)(.*)/);
  80. var root = match[1];
  81. var rest = match[2];
  82. var restRegex = rest.replace(/\*\*/g, ".*").replace(/\*/g, "[^\\/]*");
  83. restRegex = new RegExp(restRegex);
  84. _ls('-R', root).filter(function (e) {
  85. return restRegex.test(e);
  86. }).forEach(function(file) {
  87. expanded.push(file);
  88. });
  89. }
  90. // Wildcard present on file names ?
  91. else if (listEl.search(/\*/) > -1) {
  92. _ls('', listEl).forEach(function(file) {
  93. expanded.push(file);
  94. });
  95. } else {
  96. expanded.push(listEl);
  97. }
  98. });
  99. return expanded;
  100. }
  101. exports.expand = expand;
  102. // Normalizes _unlinkSync() across platforms to match Unix behavior, i.e.
  103. // file can be unlinked even if it's read-only, see https://github.com/joyent/node/issues/3006
  104. function unlinkSync(file) {
  105. try {
  106. fs.unlinkSync(file);
  107. } catch(e) {
  108. // Try to override file permission
  109. if (e.code === 'EPERM') {
  110. fs.chmodSync(file, '0666');
  111. fs.unlinkSync(file);
  112. } else {
  113. throw e;
  114. }
  115. }
  116. }
  117. exports.unlinkSync = unlinkSync;
  118. // e.g. 'shelljs_a5f185d0443ca...'
  119. function randomFileName() {
  120. function randomHash(count) {
  121. if (count === 1)
  122. return parseInt(16*Math.random(), 10).toString(16);
  123. else {
  124. var hash = '';
  125. for (var i=0; i<count; i++)
  126. hash += randomHash(1);
  127. return hash;
  128. }
  129. }
  130. return 'shelljs_'+randomHash(20);
  131. }
  132. exports.randomFileName = randomFileName;
  133. // extend(target_obj, source_obj1 [, source_obj2 ...])
  134. // Shallow extend, e.g.:
  135. // extend({A:1}, {b:2}, {c:3}) returns {A:1, b:2, c:3}
  136. function extend(target) {
  137. var sources = [].slice.call(arguments, 1);
  138. sources.forEach(function(source) {
  139. for (var key in source)
  140. target[key] = source[key];
  141. });
  142. return target;
  143. }
  144. exports.extend = extend;
  145. // Common wrapper for all Unix-like commands
  146. function wrap(cmd, fn, options) {
  147. return function() {
  148. var retValue = null;
  149. state.currentCmd = cmd;
  150. state.error = null;
  151. try {
  152. var args = [].slice.call(arguments, 0);
  153. if (options && options.notUnix) {
  154. retValue = fn.apply(this, args);
  155. } else {
  156. if (args.length === 0 || typeof args[0] !== 'string' || args[0][0] !== '-')
  157. args.unshift(''); // only add dummy option if '-option' not already present
  158. retValue = fn.apply(this, args);
  159. }
  160. } catch (e) {
  161. if (!state.error) {
  162. // If state.error hasn't been set it's an error thrown by Node, not us - probably a bug...
  163. console.log('shell.js: internal error');
  164. console.log(e.stack || e);
  165. process.exit(1);
  166. }
  167. if (config.fatal)
  168. throw e;
  169. }
  170. state.currentCmd = 'shell.js';
  171. return retValue;
  172. };
  173. } // wrap
  174. exports.wrap = wrap;