<commit_before>  'use strict';

  /***
   * @package Core
   * @description Core package allows custom methods to be defined on the Sugar global and extended onto natives later.
   ***/

  // Natives by name.
  var NATIVES = 'Boolean,Number,String,Array,Date,RegExp,Function'.split(',');

  // Natives including Object
  var NATIVES_WITH_OBJECT = NATIVES.concat('Object');

  // Property descriptors exist in IE8 but will error when trying to define a property on
  // native objects. IE8 does not have defineProperies, however, so this check saves a try/catch block.
  var PROPERTY_DESCRIPTOR_SUPPORT = !!(Object.defineProperty && Object.defineProperties);

  // The global to export.
  var Sugar;

  // The global context
  var globalContext = typeof global !== 'undefined' ? global : window;

  // Is the environment node?
  var hasExports = typeof module !== 'undefined' && module.exports;

  // Internal hasOwnProperty
  var internalHasOwnProperty = Object.prototype.hasOwnProperty;

  // Whether object instance methods can be mapped to the prototype.
  var allowObjectInstance = false;

  // Define property with fallback for environments with no support.
  var defineProperty = PROPERTY_DESCRIPTOR_SUPPORT ? Object.defineProperty : definePropertyShim;

  function setupGlobal() {
    Sugar = function(arg) {
      for (var i = 0; i < NATIVES_WITH_OBJECT.length; i++) {
        Sugar[NATIVES_WITH_OBJECT[i]].extend(arg);
      }
      // return self
      return Sugar;
    };
    // There are 2 identical methods for extending with Sugar:
    // 1. Sugar.extend();
    // 2. require('sugar')();
    // The "extend" method is more explicit and preferred, but the
    // namespace itself is also available for cleaner npm modules.
    setProperty(Sugar, 'extend', Sugar);
    iterateOverObject(NATIVES_WITH_OBJECT, setupNamespace);
    if (hasExports) {
      module.exports = Sugar;
    } else {
      globalContext['Sugar'] = Sugar;
    }
  }

  function setupNamespace(i, name) {
    var nativeClass = globalContext[name], isObject = nativeClass === Object, namespace;

    namespace = function(arg) {
      var staticMethods = {}, instanceMethods = {}, opts = {}, methodsByName;

      function disallowedByFlags(flags) {
        if (!flags) return;
        for (var i = 0; i < flags.length; i++) {
          if (opts[flags[i]] === false) {
            return true;
          }
        }
      }

      function canExtendPrototype(method) {
        return (!isObject || allowObjectInstance) && !disallowedByFlags(method.flags);
      }

      if (typeof arg === 'string') {
        methodsByName = [arg];
      } else if (arg && arg.length) {
        methodsByName = arg;
      } else if (arg) {
        opts = arg;
        methodsByName = opts.methods;
        if (isObject && typeof opts.objectInstance === 'boolean') {
          // Store "objectInstance" flag for future reference.
          allowObjectInstance = opts.objectInstance;
        }
      }

      iterateOverObject(methodsByName || namespace, function(methodName, method) {
        if (methodsByName) {
          // If we have method names passed in an array,
          // then we need to flip the key and value here
          // and find the method in the Sugar namespace.
          methodName = method;
          method = namespace[methodName];
        }
        if (hasOwnProperty(method, 'instance') && canExtendPrototype(method)) {
          instanceMethods[methodName] = method.instance;
        }
        if(hasOwnProperty(method, 'static')) {
          staticMethods[methodName] = method;
        }
      });
      extendNative(nativeClass, staticMethods);
      extendNative(nativeClass.prototype, instanceMethods);
      if (!methodsByName) {
        // If there are no method names passed, then
        // all methods in then namespace will be extended
        // to the native. This includes all future defined
        // methods, so add a flag here to check later.
        setProperty(namespace, 'active', true);
      }
      // return self
      return namespace;
    }

    // Extending by namespace:
    // 1. Sugar.Array.extend();
    // 2. require('sugar-array')();
    Sugar[name] = namespace;
    setProperty(namespace, 'extend', namespace);

    setProperty(namespace, 'defineStatic', function(methods) {
      defineMethods(namespace, methods);
    });

    setProperty(namespace, 'defineStaticWithArguments', function(methods) {
      defineMethods(namespace, methods, false, true);
    });

    setProperty(namespace, 'defineInstance', function(methods) {
      defineMethods(namespace, methods, true);
    });

    setProperty(namespace, 'defineInstanceWithArguments', function(methods) {
      defineMethods(namespace, methods, true, true);
    });

  }

  function extendNative(extendee, source, polyfill) {
    iterateOverObject(source, function(name, method) {
      if (polyfill && extendee[name]) {
        // Polyfill exists, so bail.
        return;
      }
      setProperty(extendee, name, method);
    });
  }

  function setProperty(target, name, property, enumerable) {
    defineProperty(target, name, {
      value: property,
      enumerable: !!enumerable,
      configurable: true,
      writable: true
    });
  }

  function definePropertyShim(obj, prop, descriptor) {
    obj[prop] = descriptor.value;
  }

  // Defining Methods

  // Identical to exported methods on the Sugar global but a
  // bit simplified and saves a few bytes in the minified script.

  function defineStatic(sugarNamespace, methods) {
    defineMethods(sugarNamespace, methods);
  }

  function defineStaticWithArguments(sugarNamespace, methods) {
    defineMethods(sugarNamespace, methods, false, true);
  }

  function defineInstance(sugarNamespace, methods, flags) {
    defineMethods(sugarNamespace, methods, true, false, flags);
  }

  function defineInstanceWithArguments(sugarNamespace, methods, flags) {
    defineMethods(sugarNamespace, methods, true, true, flags);
  }

  function alias(namespace, toName, fromName) {
    setProperty(namespace, toName, namespace[fromName], true);
  }

  function defineMethods(sugarNamespace, methods, instance, args, flags) {
    iterateOverObject(methods, function(methodName, method) {
      var instanceMethod, staticMethod = method;
      if (args) {
        staticMethod = wrapMethodWithArguments(method);
      }
      if (flags) {
        staticMethod.flags = flags;
      }
      setProperty(sugarNamespace, methodName, staticMethod, true);
      if (instance && !method.instance) {
        if (args) {
          instanceMethod = wrapMethodWithArguments(method, true);
        } else {
          instanceMethod = wrapInstanceMethodFixed(method);
        }
        setProperty(staticMethod, 'instance', instanceMethod);
      } else {
        setProperty(staticMethod, 'static', true);
      }
      if (sugarNamespace.active) {
        // If the namespace has been activated (all methods mapped)
        // then map this method as well.
        sugarNamespace(methodName);
      }
    });
  }

  function wrapMethodWithArguments(fn, instance) {
    // Functions accepting enumerated arguments will always have "args" as the
    // last argument, so subtract one from the function length to get the point
    // at which to start collecting arguments. If this is an instance method on
    // a prototype, then "this" will be pushed into the arguments array so start
    // collecting 1 argument earlier.
    var startCollect = fn.length - 1 - (instance ? 1 : 0);
    return function() {
      var args = [], collectedArgs = [];
      if (instance) {
        args.push(this);
      }
      // Optimized: no leaking arguments
      for (var i = 0; i < arguments.length; i++) {
        if (i < startCollect) {
          args.push(arguments[i]);
        } else {
          collectedArgs.push(arguments[i]);
        }
      }
      args.push(collectedArgs);
      return fn.apply(null, args);
    }
  }

  function wrapInstanceMethodFixed(fn) {
    switch(fn.length) {
      // case 0:
      // Wrapped instance methods will always be passed the instance
      // as the first argument, but requiring the argument to be defined
      // may cause confusion here, so return the same wrapped function regardless.
      case 0:
      case 1:
        return function() {
          return fn(this);
        }
      case 2:
        return function(a) {
          return fn(this, a);
        }
      case 3:
        return function(a, b) {
          return fn(this, a, b);
        }
      case 4:
        return function(a, b, c) {
          return fn(this, a, b, c);
        }
      case 5:
        return function(a, b, c, d) {
          return fn(this, a, b, c, d);
        }
    }
  }

  // Polyfills are directly mapped to the prototype.

  function defineStaticPolyfill(globalNamespace, methods) {
    extendNative(globalNamespace, methods, true);
  }

  function defineInstancePolyfill(globalNamespace, methods) {
    extendNative(globalNamespace.prototype, methods, true);
  }

  // Properties are simply set on the Sugar namespace
  // and do not get extended across.

  function defineStaticProperties(sugarNamespace, props) {
    iterateOverObject(props, function(name, prop) {
      setProperty(sugarNamespace, name, prop, true);
    });
  }

  // Util

  function iterateOverObject(obj, fn) {
    for(var key in obj) {
      if (!hasOwnProperty(obj, key)) continue;
      if (fn.call(obj, key, obj[key], obj) === false) break;
    }
  }

  function hasOwnProperty(obj, prop) {
    return !!obj && internalHasOwnProperty.call(obj, prop);
  }

  setupGlobal();
<commit_msg>fixing issue with collecting arguments in core<commit_after>  'use strict';

  /***
   * @package Core
   * @description Core package allows custom methods to be defined on the Sugar global and extended onto natives later.
   ***/

  // Natives by name.
  var NATIVES = 'Boolean,Number,String,Array,Date,RegExp,Function'.split(',');

  // Natives including Object
  var NATIVES_WITH_OBJECT = NATIVES.concat('Object');

  // Property descriptors exist in IE8 but will error when trying to define a property on
  // native objects. IE8 does not have defineProperies, however, so this check saves a try/catch block.
  var PROPERTY_DESCRIPTOR_SUPPORT = !!(Object.defineProperty && Object.defineProperties);

  // The global to export.
  var Sugar;

  // The global context
  var globalContext = typeof global !== 'undefined' ? global : window;

  // Is the environment node?
  var hasExports = typeof module !== 'undefined' && module.exports;

  // Internal hasOwnProperty
  var internalHasOwnProperty = Object.prototype.hasOwnProperty;

  // Whether object instance methods can be mapped to the prototype.
  var allowObjectInstance = false;

  // Define property with fallback for environments with no support.
  var defineProperty = PROPERTY_DESCRIPTOR_SUPPORT ? Object.defineProperty : definePropertyShim;

  function setupGlobal() {
    Sugar = function(arg) {
      for (var i = 0; i < NATIVES_WITH_OBJECT.length; i++) {
        Sugar[NATIVES_WITH_OBJECT[i]].extend(arg);
      }
      // return self
      return Sugar;
    };
    // There are 2 identical methods for extending with Sugar:
    // 1. Sugar.extend();
    // 2. require('sugar')();
    // The "extend" method is more explicit and preferred, but the
    // namespace itself is also available for cleaner npm modules.
    setProperty(Sugar, 'extend', Sugar);
    iterateOverObject(NATIVES_WITH_OBJECT, setupNamespace);
    if (hasExports) {
      module.exports = Sugar;
    } else {
      globalContext['Sugar'] = Sugar;
    }
  }

  function setupNamespace(i, name) {
    var nativeClass = globalContext[name], isObject = nativeClass === Object, namespace;

    namespace = function(arg) {
      var staticMethods = {}, instanceMethods = {}, opts = {}, methodsByName;

      function disallowedByFlags(flags) {
        if (!flags) return;
        for (var i = 0; i < flags.length; i++) {
          if (opts[flags[i]] === false) {
            return true;
          }
        }
      }

      function canExtendPrototype(method) {
        return (!isObject || allowObjectInstance) && !disallowedByFlags(method.flags);
      }

      if (typeof arg === 'string') {
        methodsByName = [arg];
      } else if (arg && arg.length) {
        methodsByName = arg;
      } else if (arg) {
        opts = arg;
        methodsByName = opts.methods;
        if (isObject && typeof opts.objectInstance === 'boolean') {
          // Store "objectInstance" flag for future reference.
          allowObjectInstance = opts.objectInstance;
        }
      }

      iterateOverObject(methodsByName || namespace, function(methodName, method) {
        if (methodsByName) {
          // If we have method names passed in an array,
          // then we need to flip the key and value here
          // and find the method in the Sugar namespace.
          methodName = method;
          method = namespace[methodName];
        }
        if (hasOwnProperty(method, 'instance') && canExtendPrototype(method)) {
          instanceMethods[methodName] = method.instance;
        }
        if(hasOwnProperty(method, 'static')) {
          staticMethods[methodName] = method;
        }
      });
      extendNative(nativeClass, staticMethods);
      extendNative(nativeClass.prototype, instanceMethods);
      if (!methodsByName) {
        // If there are no method names passed, then
        // all methods in then namespace will be extended
        // to the native. This includes all future defined
        // methods, so add a flag here to check later.
        setProperty(namespace, 'active', true);
      }
      // return self
      return namespace;
    }

    // Extending by namespace:
    // 1. Sugar.Array.extend();
    // 2. require('sugar-array')();
    Sugar[name] = namespace;
    setProperty(namespace, 'extend', namespace);

    setProperty(namespace, 'defineStatic', function(methods) {
      defineMethods(namespace, methods);
    });

    setProperty(namespace, 'defineStaticWithArguments', function(methods) {
      defineMethods(namespace, methods, false, true);
    });

    setProperty(namespace, 'defineInstance', function(methods) {
      defineMethods(namespace, methods, true);
    });

    setProperty(namespace, 'defineInstanceWithArguments', function(methods) {
      defineMethods(namespace, methods, true, true);
    });

  }

  function extendNative(extendee, source, polyfill) {
    iterateOverObject(source, function(name, method) {
      if (polyfill && extendee[name]) {
        // Polyfill exists, so bail.
        return;
      }
      setProperty(extendee, name, method);
    });
  }

  function setProperty(target, name, property, enumerable) {
    defineProperty(target, name, {
      value: property,
      enumerable: !!enumerable,
      configurable: true,
      writable: true
    });
  }

  function definePropertyShim(obj, prop, descriptor) {
    obj[prop] = descriptor.value;
  }

  // Defining Methods

  // Identical to exported methods on the Sugar global but a
  // bit simplified and saves a few bytes in the minified script.

  function defineStatic(sugarNamespace, methods) {
    defineMethods(sugarNamespace, methods);
  }

  function defineStaticWithArguments(sugarNamespace, methods) {
    defineMethods(sugarNamespace, methods, false, true);
  }

  function defineInstance(sugarNamespace, methods, flags) {
    defineMethods(sugarNamespace, methods, true, false, flags);
  }

  function defineInstanceWithArguments(sugarNamespace, methods, flags) {
    defineMethods(sugarNamespace, methods, true, true, flags);
  }

  function alias(namespace, toName, fromName) {
    setProperty(namespace, toName, namespace[fromName], true);
  }

  function defineMethods(sugarNamespace, methods, instance, args, flags) {
    iterateOverObject(methods, function(methodName, method) {
      var instanceMethod, staticMethod = method;
      if (args) {
        staticMethod = wrapMethodWithArguments(method);
      }
      if (flags) {
        staticMethod.flags = flags;
      }
      setProperty(sugarNamespace, methodName, staticMethod, true);
      if (instance && !method.instance) {
        if (args) {
          instanceMethod = wrapMethodWithArguments(method, true);
        } else {
          instanceMethod = wrapInstanceMethodFixed(method);
        }
        setProperty(staticMethod, 'instance', instanceMethod);
      } else {
        setProperty(staticMethod, 'static', true);
      }
      if (sugarNamespace.active) {
        // If the namespace has been activated (all methods mapped)
        // then map this method as well.
        sugarNamespace(methodName);
      }
    });
  }

  function wrapMethodWithArguments(fn, instance) {
    // Functions accepting enumerated arguments will always have "args" as the
    // last argument, so subtract one from the function length to get the point
    // at which to start collecting arguments. If this is an instance method on
    // a prototype, then "this" will be pushed into the arguments array so start
    // collecting 1 argument earlier.
    var startCollect = fn.length - 1 - (instance ? 1 : 0);
    return function() {
      var args = [], collectedArgs = [], len;
      if (instance) {
        args.push(this);
      }
      len = Math.max(arguments.length, startCollect);
      // Optimized: no leaking arguments
      for (var i = 0; i < len; i++) {
        if (i < startCollect) {
          args.push(arguments[i]);
        } else {
          collectedArgs.push(arguments[i]);
        }
      }
      args.push(collectedArgs);
      return fn.apply(null, args);
    }
  }

  function wrapInstanceMethodFixed(fn) {
    switch(fn.length) {
      // case 0:
      // Wrapped instance methods will always be passed the instance
      // as the first argument, but requiring the argument to be defined
      // may cause confusion here, so return the same wrapped function regardless.
      case 0:
      case 1:
        return function() {
          return fn(this);
        }
      case 2:
        return function(a) {
          return fn(this, a);
        }
      case 3:
        return function(a, b) {
          return fn(this, a, b);
        }
      case 4:
        return function(a, b, c) {
          return fn(this, a, b, c);
        }
      case 5:
        return function(a, b, c, d) {
          return fn(this, a, b, c, d);
        }
    }
  }

  // Polyfills are directly mapped to the prototype.

  function defineStaticPolyfill(globalNamespace, methods) {
    extendNative(globalNamespace, methods, true);
  }

  function defineInstancePolyfill(globalNamespace, methods) {
    extendNative(globalNamespace.prototype, methods, true);
  }

  // Properties are simply set on the Sugar namespace
  // and do not get extended across.

  function defineStaticProperties(sugarNamespace, props) {
    iterateOverObject(props, function(name, prop) {
      setProperty(sugarNamespace, name, prop, true);
    });
  }

  // Util

  function iterateOverObject(obj, fn) {
    for(var key in obj) {
      if (!hasOwnProperty(obj, key)) continue;
      if (fn.call(obj, key, obj[key], obj) === false) break;
    }
  }

  function hasOwnProperty(obj, prop) {
    return !!obj && internalHasOwnProperty.call(obj, prop);
  }

  setupGlobal();
<|endoftext|>


<commit_before>'use babel';

// eslint-disable-next-line import/no-extraneous-dependencies, import/extensions
import { CompositeDisposable, Range } from 'atom';
import { findAsync, rangeFromLineNumber, exec } from 'atom-linter';
import { dirname, join, relative, sep } from 'path';
import { existsSync, readFileSync, readdirSync } from 'fs';

const tmp = require('tmp');

// Internal values
const elixirProjectPathCache = new Map();
let elixircPath;
let mixPath;
let forceElixirc;

function regexp(string, flags) {
  return new RegExp(
    string
      .replace(/\\ /gm, 'randomstring123')
      .replace(/\s/gm, '')
      .replace(/randomstring123/gm, '\\ '),
    flags,
  );
}

// Find elixir project in the file path by locating mix.exs, otherwise
//  fallback to project path or file path
const findElixirProjectPath = async (editorPath) => {
  const editorDir = dirname(editorPath);
  const mixexsPath = await findAsync(editorDir, 'mix.exs');
  if (mixexsPath !== null) {
    return mixexsPath;
  }
  const projPath = atom.project.relativizePath(editorPath)[0];
  if (projPath !== null) {
    return projPath;
  }
  return editorDir;
};

// Memoize the project path per file (traversing is quite expensive)
const elixirProjectPath = async (textEditor) => {
  const editorPath = textEditor.getPath();
  if (elixirProjectPathCache.has(editorPath)) {
    return elixirProjectPathCache.get(editorPath);
  }
  const projectPath = await findElixirProjectPath(editorPath);
  elixirProjectPathCache.set(editorPath, projectPath);
  return projectPath;
};

const isMixProject = async (textEditor) => {
  const project = await elixirProjectPath(textEditor);
  return existsSync(join(project, 'mix.exs'));
};

const isTestFile = async (textEditor) => {
  const project = await elixirProjectPath(textEditor);
  const relativePath = relative(project, textEditor.getPath());
  // Is the first directory of the relative path "test"?
  return relativePath.split(sep)[0] === 'test';
};

const isForcedElixirc = () => forceElixirc;

const isExsFile = textEditor => textEditor.getPath().endsWith('.exs');

const isPhoenixProject = async (textEditor) => {
  const project = await elixirProjectPath(textEditor);
  const mixLockPath = join(project, 'mix.lock');
  try {
    const mixLockContent = readFileSync(mixLockPath, 'utf-8');
    return mixLockContent.indexOf('"phoenix"') > 0;
  } catch (error) {
    return false;
  }
};

const findTextEditor = (filePath) => {
  const allEditors = atom.workspace.getTextEditors();
  const matchingEditor = allEditors.find(
    textEditor => textEditor.getPath() === filePath);
  if (matchingEditor !== undefined) {
    return matchingEditor;
  }
  return false;
};

const parseError = async (toParse, textEditor) => {
  const messages = [];
  const re = regexp(
    `
    \\*\\*[\\ ]+
    \\((\\w+)\\)                   ${''/* 1 - (TypeOfError)*/}
    [\\ ](?:                       ${''/* Two message formats.... mode one*/}
      ([\\w\\ ]+)                  ${''/* 2 - Message*/}
      [\\r\\n]{1,2}.+[\\r\\n]{1,2} ${''/* Internal elixir code*/}
      [\\ ]+(.+)                   ${''/* 3 - File*/}
      :(\\d+):                     ${''/* 4 - Line*/}
    |                              ${''/* Or... mode two*/}
      (.+)                         ${''/* 5 - File*/}
      :(\\d+):                     ${''/* 6 - Line*/}
      [\\ ](.+)                    ${''/* 7 - Message*/}
    )
  `,
    'gm',
  );
  const projectPath = await elixirProjectPath(textEditor);
  let reResult = re.exec(toParse);
  while (reResult !== null) {
    let text;
    let filePath;
    let range;
    if (reResult[2] !== undefined) {
      text = `(${reResult[1]}) ${reResult[2]}`;
      filePath = join(projectPath, reResult[3]);
      const fileEditor = findTextEditor(filePath);
      if (fileEditor) {
        // If there is an open TextEditor instance for the file from the Error,
        // we can get a better range using rangeFromLineNumber, otherwise
        // generate a 1 character range that can be updated to a proper range
        // if/when the file is opened.
        range = rangeFromLineNumber(fileEditor, reResult[4] - 1);
      } else {
        range = new Range([reResult[4] - 1, 0], [reResult[4] - 1, 1]);
      }
    } else {
      text = `(${reResult[1]}) ${reResult[7]}`;
      filePath = join(projectPath, reResult[5]);
      if (filePath === textEditor.getPath()) {
        range = rangeFromLineNumber(textEditor, reResult[6] - 1);
      } else {
        range = new Range([reResult[6] - 1, 0], [reResult[6] - 1, 1]);
      }
    }
    messages.push({
      type: 'Error',
      text,
      filePath,
      range,
    });
    reResult = re.exec(toParse);
  }
  return messages;
};

// Only Elixir 1.3+
const parseWarning = async (toParse, textEditor) => {
  const messages = [];
  const re = regexp(
    `
    warning:\\ (.*)\\n  ${''/* warning */}
    \\ \\ (.*):([0-9]+) ${''/* file and file number */}
    `,
    'g',
  );
  const projectPath = await elixirProjectPath(textEditor);
  let reResult = re.exec(toParse);

  while (reResult != null) {
    const filePath = join(projectPath, reResult[2]);
    try {
      let range;
      const fileEditor = findTextEditor(filePath);
      if (fileEditor) {
        range = rangeFromLineNumber(fileEditor, reResult[3] - 1);
      } else {
        range = new Range([reResult[3] - 1, 0], [reResult[3] - 1, 1]);
      }
      messages.push({
        type: 'Warning',
        text: reResult[1],
        filePath,
        range,
      });
    } catch (Error) {
      // eslint-disable-next-line no-console
      console.error('linter-elixirc:', Error);
    }
    reResult = re.exec(toParse);
  }
  return messages;
};

// Parses warning for elixir 1.2 and below
const parseLegacyWarning = async (toParse, textEditor) => {
  const messages = [];
  const re = regexp(
    `
    ([^:\\n]*)   ${''/* 1 - File name */}
    :(\\d+)      ${''/* 2 - Line */}
    :\\ warning
    :\\ (.*)     ${''/* 3 - Message */}
    `,
    'g',
  );
  const projectPath = await elixirProjectPath(textEditor);
  let reResult = re.exec(toParse);
  while (reResult !== null) {
    const filePath = join(projectPath, reResult[1]);
    try {
      let range;
      const fileEditor = findTextEditor(filePath);
      if (fileEditor) {
        range = rangeFromLineNumber(fileEditor, reResult[3] - 1);
      } else {
        range = new Range([reResult[3] - 1, 0], [reResult[3] - 1, 1]);
      }
      messages.push({
        type: 'Warning',
        text: reResult[3],
        filePath,
        range,
      });
    } catch (Error) {
      // eslint-disable-next-line no-console
      console.error('linter-elixirc:', Error);
    }
    reResult = re.exec(toParse);
  }
  return messages;
};

const handleResult = async (compileResult, textEditor) => {
  const resultString = `${compileResult.stdout}\n${compileResult.stderr}`;
  try {
    const errorStack = await parseError(resultString, textEditor);
    const warningStack = await parseWarning(resultString, textEditor);
    const legacyWarningStack = await parseLegacyWarning(resultString, textEditor);
    return errorStack.concat(warningStack).concat(legacyWarningStack)
      .filter(error => error !== null)
      .map(error => error);
  } catch (Error) {
    // eslint-disable-next-line no-console
    console.error('linter-elixirc:', Error);
    return []; // Error is in a different file, just suppress
  }
};

const getOpts = async textEditor => ({
  cwd: await elixirProjectPath(textEditor),
  throwOnStdErr: false,
  stream: 'both',
  allowEmptyStderr: true,
});

const getDepsPa = async (textEditor) => {
  const env = (await isTestFile(textEditor)) ? 'test' : 'dev';
  const buildDir = join('_build', env, 'lib');
  const projectPath = await elixirProjectPath(textEditor);
  try {
    return readdirSync(join(projectPath, buildDir))
      .map(
        item =>
          join(projectPath, buildDir, item, 'ebin'),
      );
  } catch (e) {
    return [];
  }
};

const lintElixirc = async (textEditor) => {
  const tempDir = tmp.dirSync({ unsafeCleanup: true });
  const elixircArgs = [
    '--ignore-module-conflict',
    '--app',
    'mix',
    '--app',
    'ex_unit',
    '-o',
    tempDir.name,
  ];
  const paDeps = await getDepsPa(textEditor);
  paDeps.forEach((item) => {
    elixircArgs.push('-pa', item);
  });
  elixircArgs.push(textEditor.getPath());

  const fileText = textEditor.getText();
  const execOpts = await getOpts(textEditor);
  const result = await exec(elixircPath, elixircArgs, execOpts);
  // Cleanup the temp dir
  tempDir.removeCallback();
  if (textEditor.getText() !== fileText) {
    // File contents have changed since the run was triggered, don't update messages
    return null;
  }
  return handleResult(result, textEditor);
};

const lintMix = async (textEditor) => {
  const fileText = textEditor.getText();
  const execOpts = await getOpts(textEditor);
  const result = await exec(mixPath, ['compile'], execOpts);
  if (textEditor.getText() !== fileText) {
    // File contents have changed since the run was triggered, don't update messages
    return null;
  }
  return handleResult(result, textEditor);
};

export default {
  activate() {
    require('atom-package-deps').install('linter-elixirc');

    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(
      atom.config.observe('linter-elixirc.elixircPath', (value) => {
        elixircPath = value;
      }),
    );
    this.subscriptions.add(
      atom.config.observe('linter-elixirc.mixPath', (value) => {
        mixPath = value;
      }),
    );
    this.subscriptions.add(
      atom.config.observe('linter-elixirc.forceElixirc', (value) => {
        forceElixirc = value;
      }),
    );
  },

  deactivate() {
    this.subscriptions.dispose();
  },

  provideLinter() {
    return {
      grammarScopes: ['source.elixir'],
      scope: 'project',
      lintOnFly: false,
      name: 'Elixir',
      async lint(textEditor) {
        if (
          isForcedElixirc() ||
            !(await isMixProject(textEditor)) ||
            isExsFile(textEditor) ||
            (await isPhoenixProject(textEditor))
        ) {
          return lintElixirc(textEditor);
        }
        return lintMix(textEditor);
      },
    };
  },
};
<commit_msg>Search for a TextEditor in Error-mode2 messages<commit_after>'use babel';

// eslint-disable-next-line import/no-extraneous-dependencies, import/extensions
import { CompositeDisposable, Range } from 'atom';
import { findAsync, rangeFromLineNumber, exec } from 'atom-linter';
import { dirname, join, relative, sep } from 'path';
import { existsSync, readFileSync, readdirSync } from 'fs';

const tmp = require('tmp');

// Internal values
const elixirProjectPathCache = new Map();
let elixircPath;
let mixPath;
let forceElixirc;

function regexp(string, flags) {
  return new RegExp(
    string
      .replace(/\\ /gm, 'randomstring123')
      .replace(/\s/gm, '')
      .replace(/randomstring123/gm, '\\ '),
    flags,
  );
}

// Find elixir project in the file path by locating mix.exs, otherwise
//  fallback to project path or file path
const findElixirProjectPath = async (editorPath) => {
  const editorDir = dirname(editorPath);
  const mixexsPath = await findAsync(editorDir, 'mix.exs');
  if (mixexsPath !== null) {
    return mixexsPath;
  }
  const projPath = atom.project.relativizePath(editorPath)[0];
  if (projPath !== null) {
    return projPath;
  }
  return editorDir;
};

// Memoize the project path per file (traversing is quite expensive)
const elixirProjectPath = async (textEditor) => {
  const editorPath = textEditor.getPath();
  if (elixirProjectPathCache.has(editorPath)) {
    return elixirProjectPathCache.get(editorPath);
  }
  const projectPath = await findElixirProjectPath(editorPath);
  elixirProjectPathCache.set(editorPath, projectPath);
  return projectPath;
};

const isMixProject = async (textEditor) => {
  const project = await elixirProjectPath(textEditor);
  return existsSync(join(project, 'mix.exs'));
};

const isTestFile = async (textEditor) => {
  const project = await elixirProjectPath(textEditor);
  const relativePath = relative(project, textEditor.getPath());
  // Is the first directory of the relative path "test"?
  return relativePath.split(sep)[0] === 'test';
};

const isForcedElixirc = () => forceElixirc;

const isExsFile = textEditor => textEditor.getPath().endsWith('.exs');

const isPhoenixProject = async (textEditor) => {
  const project = await elixirProjectPath(textEditor);
  const mixLockPath = join(project, 'mix.lock');
  try {
    const mixLockContent = readFileSync(mixLockPath, 'utf-8');
    return mixLockContent.indexOf('"phoenix"') > 0;
  } catch (error) {
    return false;
  }
};

const findTextEditor = (filePath) => {
  const allEditors = atom.workspace.getTextEditors();
  const matchingEditor = allEditors.find(
    textEditor => textEditor.getPath() === filePath);
  if (matchingEditor !== undefined) {
    return matchingEditor;
  }
  return false;
};

const parseError = async (toParse, textEditor) => {
  const messages = [];
  const re = regexp(
    `
    \\*\\*[\\ ]+
    \\((\\w+)\\)                   ${''/* 1 - (TypeOfError)*/}
    [\\ ](?:                       ${''/* Two message formats.... mode one*/}
      ([\\w\\ ]+)                  ${''/* 2 - Message*/}
      [\\r\\n]{1,2}.+[\\r\\n]{1,2} ${''/* Internal elixir code*/}
      [\\ ]+(.+)                   ${''/* 3 - File*/}
      :(\\d+):                     ${''/* 4 - Line*/}
    |                              ${''/* Or... mode two*/}
      (.+)                         ${''/* 5 - File*/}
      :(\\d+):                     ${''/* 6 - Line*/}
      [\\ ](.+)                    ${''/* 7 - Message*/}
    )
  `,
    'gm',
  );
  const projectPath = await elixirProjectPath(textEditor);
  let reResult = re.exec(toParse);
  while (reResult !== null) {
    let text;
    let filePath;
    let range;
    if (reResult[2] !== undefined) {
      text = `(${reResult[1]}) ${reResult[2]}`;
      filePath = join(projectPath, reResult[3]);
      const fileEditor = findTextEditor(filePath);
      if (fileEditor) {
        // If there is an open TextEditor instance for the file from the Error,
        // we can get a better range using rangeFromLineNumber, otherwise
        // generate a 1 character range that can be updated to a proper range
        // if/when the file is opened.
        range = rangeFromLineNumber(fileEditor, reResult[4] - 1);
      } else {
        range = new Range([reResult[4] - 1, 0], [reResult[4] - 1, 1]);
      }
    } else {
      text = `(${reResult[1]}) ${reResult[7]}`;
      filePath = join(projectPath, reResult[5]);
      const fileEditor = findTextEditor(filePath);
      if (fileEditor) {
        range = rangeFromLineNumber(fileEditor, reResult[6] - 1);
      } else {
        range = new Range([reResult[6] - 1, 0], [reResult[6] - 1, 1]);
      }
    }
    messages.push({
      type: 'Error',
      text,
      filePath,
      range,
    });
    reResult = re.exec(toParse);
  }
  return messages;
};

// Only Elixir 1.3+
const parseWarning = async (toParse, textEditor) => {
  const messages = [];
  const re = regexp(
    `
    warning:\\ (.*)\\n  ${''/* warning */}
    \\ \\ (.*):([0-9]+) ${''/* file and file number */}
    `,
    'g',
  );
  const projectPath = await elixirProjectPath(textEditor);
  let reResult = re.exec(toParse);

  while (reResult != null) {
    const filePath = join(projectPath, reResult[2]);
    try {
      let range;
      const fileEditor = findTextEditor(filePath);
      if (fileEditor) {
        range = rangeFromLineNumber(fileEditor, reResult[3] - 1);
      } else {
        range = new Range([reResult[3] - 1, 0], [reResult[3] - 1, 1]);
      }
      messages.push({
        type: 'Warning',
        text: reResult[1],
        filePath,
        range,
      });
    } catch (Error) {
      // eslint-disable-next-line no-console
      console.error('linter-elixirc:', Error);
    }
    reResult = re.exec(toParse);
  }
  return messages;
};

// Parses warning for elixir 1.2 and below
const parseLegacyWarning = async (toParse, textEditor) => {
  const messages = [];
  const re = regexp(
    `
    ([^:\\n]*)   ${''/* 1 - File name */}
    :(\\d+)      ${''/* 2 - Line */}
    :\\ warning
    :\\ (.*)     ${''/* 3 - Message */}
    `,
    'g',
  );
  const projectPath = await elixirProjectPath(textEditor);
  let reResult = re.exec(toParse);
  while (reResult !== null) {
    const filePath = join(projectPath, reResult[1]);
    try {
      let range;
      const fileEditor = findTextEditor(filePath);
      if (fileEditor) {
        range = rangeFromLineNumber(fileEditor, reResult[3] - 1);
      } else {
        range = new Range([reResult[3] - 1, 0], [reResult[3] - 1, 1]);
      }
      messages.push({
        type: 'Warning',
        text: reResult[3],
        filePath,
        range,
      });
    } catch (Error) {
      // eslint-disable-next-line no-console
      console.error('linter-elixirc:', Error);
    }
    reResult = re.exec(toParse);
  }
  return messages;
};

const handleResult = async (compileResult, textEditor) => {
  const resultString = `${compileResult.stdout}\n${compileResult.stderr}`;
  try {
    const errorStack = await parseError(resultString, textEditor);
    const warningStack = await parseWarning(resultString, textEditor);
    const legacyWarningStack = await parseLegacyWarning(resultString, textEditor);
    return errorStack.concat(warningStack).concat(legacyWarningStack)
      .filter(error => error !== null)
      .map(error => error);
  } catch (Error) {
    // eslint-disable-next-line no-console
    console.error('linter-elixirc:', Error);
    return []; // Error is in a different file, just suppress
  }
};

const getOpts = async textEditor => ({
  cwd: await elixirProjectPath(textEditor),
  throwOnStdErr: false,
  stream: 'both',
  allowEmptyStderr: true,
});

const getDepsPa = async (textEditor) => {
  const env = (await isTestFile(textEditor)) ? 'test' : 'dev';
  const buildDir = join('_build', env, 'lib');
  const projectPath = await elixirProjectPath(textEditor);
  try {
    return readdirSync(join(projectPath, buildDir))
      .map(
        item =>
          join(projectPath, buildDir, item, 'ebin'),
      );
  } catch (e) {
    return [];
  }
};

const lintElixirc = async (textEditor) => {
  const tempDir = tmp.dirSync({ unsafeCleanup: true });
  const elixircArgs = [
    '--ignore-module-conflict',
    '--app',
    'mix',
    '--app',
    'ex_unit',
    '-o',
    tempDir.name,
  ];
  const paDeps = await getDepsPa(textEditor);
  paDeps.forEach((item) => {
    elixircArgs.push('-pa', item);
  });
  elixircArgs.push(textEditor.getPath());

  const fileText = textEditor.getText();
  const execOpts = await getOpts(textEditor);
  const result = await exec(elixircPath, elixircArgs, execOpts);
  // Cleanup the temp dir
  tempDir.removeCallback();
  if (textEditor.getText() !== fileText) {
    // File contents have changed since the run was triggered, don't update messages
    return null;
  }
  return handleResult(result, textEditor);
};

const lintMix = async (textEditor) => {
  const fileText = textEditor.getText();
  const execOpts = await getOpts(textEditor);
  const result = await exec(mixPath, ['compile'], execOpts);
  if (textEditor.getText() !== fileText) {
    // File contents have changed since the run was triggered, don't update messages
    return null;
  }
  return handleResult(result, textEditor);
};

export default {
  activate() {
    require('atom-package-deps').install('linter-elixirc');

    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(
      atom.config.observe('linter-elixirc.elixircPath', (value) => {
        elixircPath = value;
      }),
    );
    this.subscriptions.add(
      atom.config.observe('linter-elixirc.mixPath', (value) => {
        mixPath = value;
      }),
    );
    this.subscriptions.add(
      atom.config.observe('linter-elixirc.forceElixirc', (value) => {
        forceElixirc = value;
      }),
    );
  },

  deactivate() {
    this.subscriptions.dispose();
  },

  provideLinter() {
    return {
      grammarScopes: ['source.elixir'],
      scope: 'project',
      lintOnFly: false,
      name: 'Elixir',
      async lint(textEditor) {
        if (
          isForcedElixirc() ||
            !(await isMixProject(textEditor)) ||
            isExsFile(textEditor) ||
            (await isPhoenixProject(textEditor))
        ) {
          return lintElixirc(textEditor);
        }
        return lintMix(textEditor);
      },
    };
  },
};
<|endoftext|>


<commit_before>'use strict';

// --- Dependencies ---
//var debug  = require('debug')('arkivo:sufia');
var assert = require('assert');
var common = require('arkivo').common;

var extend = common.extend;
var pick   = common.pick;

/**
 * @class SufiaItem
 */
function SufiaItem(token, zotero) {
  this.token    = token;
  this.file     = {};
  this.metadata = {
    creators: [], tags: [], rights: 'All rights reserved'
  };

  if (zotero) this.parse(zotero);
}

// Zotero item type to Sufia resource type
SufiaItem.TYPE = {
  journalArticle: 'Article',
  magazineArticle: 'Article',
  newspaperArticle: 'Article',
  audioRecording: 'Audio',
  radioBroadcast: 'Audio',
  podcast: 'Audio',
  book: 'Book',
  bookSection: 'Part of Book',
  thesis: 'Thesis',
  videoRecording: 'Video',
  film: 'Video',
  tvBroadcast: 'Video',
  conferencePaper: 'Conference Proceeding',
  computerProgram: 'Software or Program Code',
  artwork: 'Image',
  map: 'Map or Cartographic Material',
  presentation: 'Presentation'
};

// Zotero data fields to copy as is
SufiaItem.FIELDS = [
  'title', 'rights', 'publisher', 'url', 'language'
];

/**
 * Parse a Zotero item.
 * @convert
 */
SufiaItem.prototype.parse = function (z) {
  assert(z);
  assert(z.data, 'Zotero item has no data');

  this.metadata.resourceType =
    SufiaItem.TYPE[z.data.itemType] || 'Other';

  extend(this.metadata, pick(z.data, SufiaItem.FIELDS));

  this.metadata.basedNear   = z.data.place;
  this.metadata.description = z.data.abstractNote;

  this.metadata.identifier =
    z.data.DOI || z.data.ISBN || z.data.PMID || z.data.arXiv;

  copy(this.metadata.creators, z.data.creators);
  copy(this.metadata.tags, z.data.tags, tag);

};

// --- Helpers ---

function copy(target, source, converter) {
  var i, ii;

  target.length = 0;

  if (source && source.length) {
    converter = converter || id;

    for (i = 0, ii = source.length; i < ii; ++i)
      target.push(converter(source[i], i, ii));

  }

  return target;
}

function id(x)  { return x; }
function tag(x) { return x.tag; }

// --- Exports ---
module.exports = SufiaItem;
<commit_msg>add attach file<commit_after>'use strict';

// --- Dependencies ---
//var debug  = require('debug')('arkivo:sufia');
var assert = require('assert');
var common = require('arkivo').common;

var extend = common.extend;
var pick   = common.pick;
var md5    = common.md5;
var base64 = common.base64;

/**
 * @class SufiaItem
 */
function SufiaItem(token, zotero) {
  this.token    = token;
  this.file     = {};
  this.metadata = {
    creators: [], tags: [], rights: 'All rights reserved'
  };

  if (zotero) this.parse(zotero);
}

// Zotero item type to Sufia resource type
SufiaItem.TYPE = {
  journalArticle: 'Article',
  magazineArticle: 'Article',
  newspaperArticle: 'Article',
  audioRecording: 'Audio',
  radioBroadcast: 'Audio',
  podcast: 'Audio',
  book: 'Book',
  bookSection: 'Part of Book',
  thesis: 'Thesis',
  videoRecording: 'Video',
  film: 'Video',
  tvBroadcast: 'Video',
  conferencePaper: 'Conference Proceeding',
  computerProgram: 'Software or Program Code',
  artwork: 'Image',
  map: 'Map or Cartographic Material',
  presentation: 'Presentation'
};

// Zotero data fields to copy as is
SufiaItem.FIELDS = [
  'title', 'rights', 'publisher', 'url', 'language'
];

/**
 * Parse a Zotero item.
 * @convert
 */
SufiaItem.prototype.parse = function (z) {
  assert(z);
  assert(z.data, 'Zotero item has no data');

  this.metadata.resourceType =
    SufiaItem.TYPE[z.data.itemType] || 'Other';

  extend(this.metadata, pick(z.data, SufiaItem.FIELDS));

  this.metadata.basedNear   = z.data.place;
  this.metadata.description = z.data.abstractNote;

  this.metadata.identifier =
    z.data.DOI || z.data.ISBN || z.data.PMID || z.data.arXiv;

  copy(this.metadata.creators, z.data.creators);
  copy(this.metadata.tags, z.data.tags, tag);

};

SufiaItem.prototype.attach = function (z, data) {
  assert(z);
  assert(z.data, 'Zotero item has no data');
  assert.equal(z.data.md5, md5(data), 'md5 checksum mismatch');

  extend(this.file, pick(z.data, ['filename', 'contentType', 'md5']));

  this.file.base64 = base64(data);
};

// --- Helpers ---

function copy(target, source, converter) {
  var i, ii;

  target.length = 0;

  if (source && source.length) {
    converter = converter || id;

    for (i = 0, ii = source.length; i < ii; ++i)
      target.push(converter(source[i], i, ii));

  }

  return target;
}

function id(x)  { return x; }
function tag(x) { return x.tag; }

// --- Exports ---
module.exports = SufiaItem;
<|endoftext|>


<commit_before>require('envloader').load();
var express 		= require('express');
var cors 			= require('cors');
var bodyParser 		= require('body-parser');
var compression 	= require('compression');
var app 			= express();
var https 			= require("https");
var request			= require('request');
var engines 		= require('consolidate');
var elastic_search 	= require('./search.js');
var processing 		= require('./process.js');
var slack 			= require('./slack.js');

/*----------------------------------
// START MIDDLEWARES
----------------------------------*/
app.use(cors());
app.use(compression())

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }))

app.use(bodyParser.json({ type: 'application/json' })); // for parsing application/json

app.use(function(err, req, res, next) {
  console.error(err.stack);
  if (err.status === 400 && err.name === 'SyntaxError' && err.body) {
    res.status(err.status).send({details: 'Invalid JSON'})
  }

  res.status(err.status).send({details: err.body.slice(0, 100).toString()});
});

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Content-Type, Accept, api_key, Authorization");
  res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, OPTIONS");
  next();
});
/*----------------------------------
// END MIDDLEWARES
----------------------------------*/
app.use(express.static('public'))

app.set('views', __dirname + './../views');
app.engine('html',  require('ejs').renderFile);
app.set('view engine', 'html');

app.get('/', function(req, res) {
  //search('eo1', req, res);
  res.render("home.html")
});

app.get('/search', function(req, res) {
	var id 		= null
	var host	= req.protocol + '://' + req.get('host')

	//search('eo1', req, res);
	res.render("search.ejs", {
		id: 	id,
		host: host
	})
});

app.get('/search/:id', function(req, res) {
	var id 		= req.params['id']
	var host	= req.protocol + '://' + req.get('host')

		res.render("search.ejs", {
			id: 	id,
			host: host,
			data: data
	    })

});

app.get('/process/:id', function(req, res) {
	var id 		= req.params['id']
	var host	= req.protocol + '://' + req.get('host')

  //search('eo1', req, res);
  res.render("process.ejs", {
	  id: 	id,
	  host: host
  })
});

app.get('/show/:id', function(req, res) {
	var id 		= req.params['id']
	var url		= req.protocol + '://' + req.get('host') + req.originalUrl;
	slack.searchPost( id, function(err, data) {
		res.render("show.ejs", {
			id: id,
			url: url,
			message: data
		})
	})
});

app.get('/download/:id', function(req, res) {
	var id 		= req.params['id']
	var url		= req.protocol + '://' + req.get('host') + req.originalUrl;
	var scene	= id.split("_")[0]
	var year	= scene.substring(10,14)
	var doy		= scene.substring(14,17)

	var url2	= "https://s3.amazonaws.com/eo1-hyperion/L1U/" + year + "/" + doy +"/"
	url2 		+= scene + "/" + id +".json"
//	console.log(url2)
//	var url2 = "https://s3.amazonaws.com/eo1-hyperion/L1U/2013/228/EO1H0110282013228110T3/EO1H0110282013228110T3_L1U.json"
	request.get(url2, function(err, response, body) {
		if(!err) {
			var data = JSON.parse(body)
		}
		res.render("download.ejs", {
			id: id,
			url: url,
			downloads: data.actions.downloads
		})
	})

});

app.get('/map/:id', function(req, res) {
	var id 		= req.params['id']
	var url		= req.protocol + '://' + req.get('host') + req.originalUrl;
	res.render("show_map.ejs", {
		id: id,
		url: url
  	})
});

app.get('/map', function(req, res) {
	res.render("map.html")
});

app.get('/api', function(req, res) {
	res.redirect("/dist/index.html")
});

app.get('/slack-app', function(req, res) {
	res.render("slack.ejs", {

	})
});

app.get('/geoquery', 		elastic_search.eo1_geoquery);
app.get('/landsat', 		elastic_search.landsat_query);
app.get('/sentinel', 		elastic_search.sentinel_query);
app.get('/eo1', 			elastic_search.eo1_query);
app.get('/eo1/process', 	processing.index);
app.get('/count', 			elastic_search.count);
app.get('/geojson', 		elastic_search.geojson);
app.get('/health', 			elastic_search.health);
app.post('/slack', 			elastic_search.eo1_slack);
app.post('/slack/actions', 	slack.actions);
app.get('/slack/oauth', 	slack.oauth);
app.get('/slacksearch/:id', slack.search);
app.get('/slack/:id', 		slack.postMessage);

/*----------------------------------
// END ENDPOINTS
----------------------------------*/

var port = process.env.PORT || 8000;
app.listen(port, function() {
  console.log('Listening on ' + port);
});
<commit_msg>problem with heroku<commit_after>require('envloader').load();
var express 		= require('express');
var cors 			= require('cors');
var bodyParser 		= require('body-parser');
var compression 	= require('compression');
var app 			= express();
var https 			= require("https");
var request			= require('request');
var engines 		= require('consolidate');

var elastic_search 	= require('./search.js');
var processing 		= require('./process');
var slack 			= require('./slack');

/*----------------------------------
// START MIDDLEWARES
----------------------------------*/
app.use(cors());
app.use(compression())

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }))

app.use(bodyParser.json({ type: 'application/json' })); // for parsing application/json

app.use(function(err, req, res, next) {
  console.error(err.stack);
  if (err.status === 400 && err.name === 'SyntaxError' && err.body) {
    res.status(err.status).send({details: 'Invalid JSON'})
  }

  res.status(err.status).send({details: err.body.slice(0, 100).toString()});
});

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Content-Type, Accept, api_key, Authorization");
  res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, OPTIONS");
  next();
});
/*----------------------------------
// END MIDDLEWARES
----------------------------------*/
app.use(express.static('public'))

app.set('views', __dirname + './../views');
app.engine('html',  require('ejs').renderFile);
app.set('view engine', 'html');

app.get('/', function(req, res) {
  //search('eo1', req, res);
  res.render("home.html")
});

app.get('/search', function(req, res) {
	var id 		= null
	var host	= req.protocol + '://' + req.get('host')

	//search('eo1', req, res);
	res.render("search.ejs", {
		id: 	id,
		host: host
	})
});

app.get('/search/:id', function(req, res) {
	var id 		= req.params['id']
	var host	= req.protocol + '://' + req.get('host')

		res.render("search.ejs", {
			id: 	id,
			host: host,
			data: data
	    })

});

app.get('/process/:id', function(req, res) {
	var id 		= req.params['id']
	var host	= req.protocol + '://' + req.get('host')

  //search('eo1', req, res);
  res.render("process.ejs", {
	  id: 	id,
	  host: host
  })
});

app.get('/show/:id', function(req, res) {
	var id 		= req.params['id']
	var url		= req.protocol + '://' + req.get('host') + req.originalUrl;
	slack.searchPost( id, function(err, data) {
		res.render("show.ejs", {
			id: id,
			url: url,
			message: data
		})
	})
});

app.get('/download/:id', function(req, res) {
	var id 		= req.params['id']
	var url		= req.protocol + '://' + req.get('host') + req.originalUrl;
	var scene	= id.split("_")[0]
	var year	= scene.substring(10,14)
	var doy		= scene.substring(14,17)

	var url2	= "https://s3.amazonaws.com/eo1-hyperion/L1U/" + year + "/" + doy +"/"
	url2 		+= scene + "/" + id +".json"
//	console.log(url2)
//	var url2 = "https://s3.amazonaws.com/eo1-hyperion/L1U/2013/228/EO1H0110282013228110T3/EO1H0110282013228110T3_L1U.json"
	request.get(url2, function(err, response, body) {
		if(!err) {
			var data = JSON.parse(body)
		}
		res.render("download.ejs", {
			id: id,
			url: url,
			downloads: data.actions.downloads
		})
	})

});

app.get('/map/:id', function(req, res) {
	var id 		= req.params['id']
	var url		= req.protocol + '://' + req.get('host') + req.originalUrl;
	res.render("show_map.ejs", {
		id: id,
		url: url
  	})
});

app.get('/map', function(req, res) {
	res.render("map.html")
});

app.get('/api', function(req, res) {
	res.redirect("/dist/index.html")
});

app.get('/slack-app', function(req, res) {
	res.render("slack.ejs", {

	})
});

app.get('/geoquery', 		elastic_search.eo1_geoquery);
app.get('/landsat', 		elastic_search.landsat_query);
app.get('/sentinel', 		elastic_search.sentinel_query);
app.get('/eo1', 			elastic_search.eo1_query);
app.get('/eo1/process', 	processing.index);
app.get('/count', 			elastic_search.count);
app.get('/geojson', 		elastic_search.geojson);
app.get('/health', 			elastic_search.health);
app.post('/slack', 			elastic_search.eo1_slack);
app.post('/slack/actions', 	slack.actions);
app.get('/slack/oauth', 	slack.oauth);
app.get('/slacksearch/:id', slack.search);
app.get('/slack/:id', 		slack.postMessage);

/*----------------------------------
// END ENDPOINTS
----------------------------------*/

var port = process.env.PORT || 8000;
app.listen(port, function() {
  console.log('Listening on ' + port);
});
<|endoftext|>


<commit_before>"use strict";
var Key = require('./key'),
    Attribute = require('./attribute'),
    common = require('./common'),
    merge = common.merge,
    errors = require('./errors');

function Item(){
    this.key = null;
    this.attributes = {};
}

Item.fromData = function(data, keySchema){
    var item = new Item();
    item.key = Key.fromSchema(data, keySchema);
    Object.keys(data).forEach(function(name){
        var value = data[name];
        if(!item.key.hasOwnProperty(name)){
            item.attributes[name] = Attribute.fromHash(name, value);
        }
    });
    return item;
};

Item.fromKey = function(key){
    var item = new Item();
    item.key = key;
    return item;
};

Item.prototype.asHash = function(){
    var result = {};
    merge(result, this.key.asHash());
    Object.keys(this.attributes).forEach(function(name){
        var attribute = this.attributes[name];
        merge(result, attribute.asHash());
    }.bind(this));
    return result;
};

Item.prototype.update = function(name, data){
    if(this.key.hasOwnProperty(name)){
        throw new errors.ValidationException("Cannot update attribute #{name}. This attribute is part of the key");
    }

    var newValue = data.Value,
        action = data.Action || 'PUT',
        methodName = action.toLowerCase();

    if(!newValue && action !== 'DELETE'){
        throw new errors.ValidationException("Only DELETE action is allowed when no attribute value is specified");
    }

    return this[methodName].apply(this, [name, newValue]);
};

Item.prototype.put = function(name, value){
    this.attributes[name] = Attribute.fromHash(name, value);
};

Item.prototype.delete = function(name, value){
    if(!value){
        delete this.attrbutes[name];
        return;
    }
    // elsif old_attribute = attributes[name]
    // validate_type(value, old_attribute)
    // unless ["SS", "NS"].include? old_attribute.type
    //   raise ValidationException, "Action DELETE is not supported for type #{old_attribute.type}"
    // end
    // attribute = Attribute.from_hash(name, value)
    // old_attribute.value -= attribute.value
    // end
};

Item.prototype.add = function(name, value){
    var attribute = Attribute.fromHash(name, value),
        oldAttribute = this.attributes[name],
        newValue;

    if(['N', 'SS', 'NS'].indexOf(attribute.type) === -1){
        throw new errors.ValidationException("Action ADD is not supported for type "+attribute.type);
    }

    if(!oldAttribute){
        this.attributes[name] = attribute;
        return;
    }

    // validate_type(value, old_attribute)
    if(attribute.type === 'N'){
        this.attributes[name].value = Number(oldAttribute.value) + Number(attribute.value);
    }
    else{
        this.attributes[name].value.push(attribute.value);
    }

};

module.exports = Item;<commit_msg>Fix bug when adding to sets with an update<commit_after>"use strict";
var Key = require('./key'),
    Attribute = require('./attribute'),
    common = require('./common'),
    merge = common.merge,
    errors = require('./errors');

function Item(){
    this.key = null;
    this.attributes = {};
}

Item.fromData = function(data, keySchema){
    var item = new Item();
    item.key = Key.fromSchema(data, keySchema);
    Object.keys(data).forEach(function(name){
        var value = data[name];
        if(!item.key.hasOwnProperty(name)){
            item.attributes[name] = Attribute.fromHash(name, value);
        }
    });
    return item;
};

Item.fromKey = function(key){
    var item = new Item();
    item.key = key;
    return item;
};

Item.prototype.asHash = function(){
    var result = {};
    merge(result, this.key.asHash());
    Object.keys(this.attributes).forEach(function(name){
        var attribute = this.attributes[name];
        merge(result, attribute.asHash());
    }.bind(this));
    return result;
};

Item.prototype.update = function(name, data){
    if(this.key.hasOwnProperty(name)){
        throw new errors.ValidationException("Cannot update attribute #{name}. This attribute is part of the key");
    }

    var newValue = data.Value,
        action = data.Action || 'PUT',
        methodName = action.toLowerCase();

    if(!newValue && action !== 'DELETE'){
        throw new errors.ValidationException("Only DELETE action is allowed when no attribute value is specified");
    }

    return this[methodName].apply(this, [name, newValue]);
};

Item.prototype.put = function(name, value){
    this.attributes[name] = Attribute.fromHash(name, value);
};

Item.prototype.delete = function(name, value){
    if(!value){
        delete this.attrbutes[name];
        return;
    }
    // elsif old_attribute = attributes[name]
    // validate_type(value, old_attribute)
    // unless ["SS", "NS"].include? old_attribute.type
    //   raise ValidationException, "Action DELETE is not supported for type #{old_attribute.type}"
    // end
    // attribute = Attribute.from_hash(name, value)
    // old_attribute.value -= attribute.value
    // end
};

Item.prototype.add = function(name, value){
    var attribute = Attribute.fromHash(name, value),
        oldAttribute = this.attributes[name],
        newValue;

    if(['N', 'SS', 'NS'].indexOf(attribute.type) === -1){
        throw new errors.ValidationException("Action ADD is not supported for type "+attribute.type);
    }

    if(!oldAttribute){
        this.attributes[name] = attribute;
        return;
    }

    // validate_type(value, old_attribute)
    if(attribute.type === 'N'){
        this.attributes[name].value = Number(oldAttribute.value) + Number(attribute.value);
    }
    else{
        attribute.value.forEach(function(v){
            this.attributes[name].value.push(v);
        }.bind(this));
    }

};

module.exports = Item;<|endoftext|>


<commit_before>'use strict';

// replace ende
var assign = require('lodash/object/assign')

var fs = require('fs');

var $ = require('jquery'),
    BpmnModeler = require('bpmn-js/lib/Modeler');

var container = $('#js-drop-zone');

var canvas = $('#js-canvas');

// Reference to the custom Modules
var CustomBpmnReplace=require('./customReplace/CustomReplace.js'); // affects activities
//var CustomContextPadProvider=require('./customContextPadProvider/CustomContextPadProvider.js'); //affects participants

// Register the custom Modules
 var overrideModule = {
   bpmnReplace: [ 'type', CustomBpmnReplace ]//,
//     contextPadProvider: [ 'type', CustomContextPadProvider ]
 };

var extensionModule = {
//  __init__: [ 'ParticipantAttribute' ],
//  ParticipantAttribute: [ 'type', ParticipantAttribute ]
};

// Load the Modeler
var renderer = new BpmnModeler({ container: canvas , additionalModules: [ overrideModule ]});

//var shape = elementFactory.createShape({ type: 'bpmn:PartnerRole','participantRef':businessObject });

renderer.on('element.click',function(event){
  console.log(event);
});
//var a=renderer.get('moddle');
//a.create('bpmn:PartnerRole');

var newDiagramXML = fs.readFileSync(__dirname + '/../resources/newDiagram.bpmn', 'utf-8');

function createNewDiagram() {
  openDiagram(newDiagramXML);
}

function openDiagram(xml) {

  renderer.importXML(xml, function(err) {

    if (err) {
      container
        .removeClass('with-diagram')
        .addClass('with-error');

      container.find('.error pre').text(err.message);

      console.error(err);
    } else {
      container
        .removeClass('with-error')
        .addClass('with-diagram');
    }

  });
}

function saveSVG(done) {
  renderer.saveSVG(done);
}

function saveDiagram(done) {

  renderer.saveXML({ format: true }, function(err, xml) {
    done(err, xml);
  });
}

function registerFileDrop(container, callback) {

  function handleFileSelect(e) {
    e.stopPropagation();
    e.preventDefault();

    var files = e.dataTransfer.files;

    var file = files[0];

    var reader = new FileReader();

    reader.onload = function(e) {

      var xml = e.target.result;

      callback(xml);
    };

    reader.readAsText(file);
  }

  function handleDragOver(e) {
    e.stopPropagation();
    e.preventDefault();

    e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
  }

  container.get(0).addEventListener('dragover', handleDragOver, false);
  container.get(0).addEventListener('drop', handleFileSelect, false);
}

////// file drag / drop ///////////////////////

// check file api availability
if (!window.FileList || !window.FileReader) {
  window.alert(
    'Looks like you use an older browser that does not support drag and drop. ' +
    'Try using Chrome, Firefox or the Internet Explorer > 10.');
} else {
  registerFileDrop(container, openDiagram);
}

// bootstrap diagram functions

$(document).on('ready', function() {

  $('#js-create-diagram').click(function(e) {
    e.stopPropagation();
    e.preventDefault();

    createNewDiagram();
  });

  var downloadLink = $('#js-download-diagram');
  var downloadSvgLink = $('#js-download-svg');

  $('.buttons a').click(function(e) {
    if (!$(this).is('.active')) {
      e.preventDefault();
      e.stopPropagation();
    }
  });

  function setEncoded(link, name, data) {
    var encodedData = encodeURIComponent(data);

    if (data) {
      link.addClass('active').attr({
        'href': 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData,
        'download': name
      });
    } else {
      link.removeClass('active');
    }
  }

  var _ = require('lodash');

  var exportArtifacts = _.debounce(function() {

    saveSVG(function(err, svg) {
      setEncoded(downloadSvgLink, 'diagram.svg', err ? null : svg);
    });

    saveDiagram(function(err, xml) {
      setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml);
    });
  }, 500);

  renderer.on('commandStack.changed', exportArtifacts);

});<commit_msg>Enabled CustomContextPadProvider<commit_after>'use strict';

// replace ende
var assign = require('lodash/object/assign');

var fs = require('fs');

var $ = require('jquery'),
    BpmnModeler = require('bpmn-js/lib/Modeler');

var container = $('#js-drop-zone');

var canvas = $('#js-canvas');

// Reference to the custom Modules
var CustomBpmnReplace=require('./customReplace/CustomReplace.js'); // affects activities
var CustomContextPadProvider=require('./customContextPadProvider/CustomContextPadProvider.js'); //affects participants

// Register the custom Modules
 var overrideModule = {
   bpmnReplace: [ 'type', CustomBpmnReplace ],
     contextPadProvider: [ 'type', CustomContextPadProvider ]
 };

var extensionModule = {
//  __init__: [ 'ParticipantAttribute' ],
//  ParticipantAttribute: [ 'type', ParticipantAttribute ]
};

// Load the Modeler
var renderer = new BpmnModeler({ container: canvas , additionalModules: [ overrideModule ]});

//var shape = elementFactory.createShape({ type: 'bpmn:PartnerRole','participantRef':businessObject });
/*
renderer.on('element.click',function(event){
  var businessObject=event.element.businessObject;
  if(!businessObject.resources){
      var Modeling=require('bpmn-js/lib/features/modeling/modeling');
      Modeling.updateProperties(businessObject,{'resources':'http://'});

  }
  console.log(event);
});*/
//var a=renderer.get('moddle');
//a.create('bpmn:PartnerRole');

var newDiagramXML = fs.readFileSync(__dirname + '/../resources/newDiagram.bpmn', 'utf-8');

function createNewDiagram() {
  openDiagram(newDiagramXML);
}

function openDiagram(xml) {

  renderer.importXML(xml, function(err) {

    if (err) {
      container
        .removeClass('with-diagram')
        .addClass('with-error');

      container.find('.error pre').text(err.message);

      console.error(err);
    } else {
      container
        .removeClass('with-error')
        .addClass('with-diagram');
    }

  });
}

function saveSVG(done) {
  renderer.saveSVG(done);
}

function saveDiagram(done) {

  renderer.saveXML({ format: true }, function(err, xml) {
    done(err, xml);
  });
}

function registerFileDrop(container, callback) {

  function handleFileSelect(e) {
    e.stopPropagation();
    e.preventDefault();

    var files = e.dataTransfer.files;

    var file = files[0];

    var reader = new FileReader();

    reader.onload = function(e) {

      var xml = e.target.result;

      callback(xml);
    };

    reader.readAsText(file);
  }

  function handleDragOver(e) {
    e.stopPropagation();
    e.preventDefault();

    e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
  }

  container.get(0).addEventListener('dragover', handleDragOver, false);
  container.get(0).addEventListener('drop', handleFileSelect, false);
}

////// file drag / drop ///////////////////////

// check file api availability
if (!window.FileList || !window.FileReader) {
  window.alert(
    'Looks like you use an older browser that does not support drag and drop. ' +
    'Try using Chrome, Firefox or the Internet Explorer > 10.');
} else {
  registerFileDrop(container, openDiagram);
}

// bootstrap diagram functions

$(document).on('ready', function() {

  $('#js-create-diagram').click(function(e) {
    e.stopPropagation();
    e.preventDefault();

    createNewDiagram();
  });

  var downloadLink = $('#js-download-diagram');
  var downloadSvgLink = $('#js-download-svg');

  $('.buttons a').click(function(e) {
    if (!$(this).is('.active')) {
      e.preventDefault();
      e.stopPropagation();
    }
  });

  function setEncoded(link, name, data) {
    var encodedData = encodeURIComponent(data);

    if (data) {
      link.addClass('active').attr({
        'href': 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData,
        'download': name
      });
    } else {
      link.removeClass('active');
    }
  }

  var _ = require('lodash');

  var exportArtifacts = _.debounce(function() {

    saveSVG(function(err, svg) {
      setEncoded(downloadSvgLink, 'diagram.svg', err ? null : svg);
    });

    saveDiagram(function(err, xml) {
      setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml);
    });
  }, 500);

  renderer.on('commandStack.changed', exportArtifacts);

});<|endoftext|>


<commit_before>'use strict';
var util = require('util');
var path = require('path');
var generators = require('yeoman-generator');
var glob = require('glob');
var slugify = require('underscore.string/slugify');
var mkdirp = require('mkdirp');

module.exports = generators.Base.extend({
  constructor: function () {
    generators.Base.apply(this, arguments);

    // add option to skip install
    this.option('skip-install');

    this.slugify = slugify;
  },
  prompting: {
    dir: function () {

      if (this.options.createDirectory !== undefined) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'confirm',
        name: 'createDirectory',
        message: 'Would you like to create a new directory for your project?'
      }];

      this.prompt(prompt, function (response) {
        this.options.createDirectory = response.createDirectory;
        done();
      }.bind(this));
    },
    dirname: function () {

      if (!this.options.createDirectory || this.options.dirname) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'input',
        name: 'dirname',
        message: 'Enter directory name'
      }];

      this.prompt(prompt, function (response) {
        this.options.dirname = response.dirname;
        done();
      }.bind(this));
    },
    type: function () {
      // Short circuit if an option was explicitly specified
      if (this.options.mvc || this.options.basic) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'list',
        name: 'type',
        message: 'Select a version to install:',
        choices: [
          'Basic',
          'MVC'
        ],
        store: true
      }];

      this.prompt(prompt, function (responses) {
        this.options.mvc = responses.type.match(/^MVC$/i) !== null;
        done();
      }.bind(this));
    },
    viewEngine: function () {

      if (this.options.viewEngine) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'list',
        name: 'viewEngine',
        message: 'Select a view engine to use:',
        choices: [
          'Jade',
          'Swig',
          'EJS',
          'Handlebars',
          'Marko'
        ],
        store: true
      }];

      this.prompt(prompt, function (response) {
        this.options.viewEngine = response.viewEngine.toLowerCase();
        done();
      }.bind(this));
    },
    cssPreprocessor: function () {

      if (this.options.cssPreprocessor) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'list',
        name: 'cssPreprocessor',
        message: 'Select a css preprocessor to use (Sass Requires Ruby):' ,
        choices: [
          'None',
          'Node-Sass',
          'Sass',
          'less',
          'Stylus'
        ],
        store: true
      }];

      this.prompt(prompt, function (response) {
        this.options.cssPreprocessor = response.cssPreprocessor.toLowerCase();
        done();
      }.bind(this));
    },
    database: function () {

      if (this.options.database || !this.options.mvc) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'list',
        name: 'database',
        message: 'Select a database to use:',
        choices: [
          'None',
          'MongoDB',
          'MySQL',
          'PostgreSQL',
          'RethinkDB',
          'SQLite'
        ],
        store: true
      }];
      this.prompt(prompt, function (response) {
        this.options.database = response.database.toLowerCase();
        done();
      }.bind(this));
    },
    buildTool: function () {

      if (this.options.buildTool) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'list',
        name: 'buildTool',
        message: 'Select a build tool to use:',
        choices: [
          'Grunt',
          'Gulp'
        ],
        store: true
      }];

      this.prompt(prompt, function (response) {
        this.options.buildTool = response.buildTool.toLowerCase();
        done();
      }.bind(this));

    }
  },
  writing: {
    buildEnv: function () {

      // create directory
      if(this.options.createDirectory){
        this.destinationRoot(this.options.dirname);
      }

      var name = this.options.mvc ? 'mvc' : 'basic';
      var suffix = this.options.coffee ? '-coffee' : '';
      this.filetype = 'js';
      if(this.options.coffee) this.filetype = 'coffee';

      // shared across all generators
      this.sourceRoot(path.join(__dirname, 'templates', 'shared'));
      glob.sync('**', { cwd: this.sourceRoot() }).map(function (file) {
        this.template(file, file.replace(/^_/, ''));
      }, this);

      // shared for mvc/basic generators
      this.sourceRoot(path.join(__dirname, 'templates', name + '-shared'));
      this.directory('.', '.');

      // templates
      this.sourceRoot(path.join(__dirname, 'templates', name + suffix));
      this.directory('.', '.');

      // views
      var views = this.options.viewEngine;
      this.sourceRoot(path.join(__dirname, 'templates', 'views', views));
      if (this.options.mvc) {
        this.directory('.', 'app/views');
      } else {
        this.directory('.', 'views');
      }

      // css
      var stylesheets = this.options.cssPreprocessor;
      if(stylesheets === 'none') stylesheets = 'css';
      if(stylesheets === 'node-sass') stylesheets = 'sass';
      this.sourceRoot(path.join(__dirname, 'templates', 'css', stylesheets));
      this.directory('.', 'public/css');

      // grunt/gulp
      var buildFile = this.options.buildTool === 'grunt' ? 'Gruntfile.js' : 'gulpfile.js';
      this.copy(path.join(__dirname, 'templates', 'extras', name + '-shared', buildFile), buildFile);

      // sequelize extra stuff
      if (this.options.database === 'mysql' ||
          this.options.database === 'postgresql' ||
          this.options.database === 'sqlite') {
        this.copy(path.join(__dirname, 'templates', 'extras', name + suffix, 'sequelize-model-index.' + this.filetype), 'app/models/index.' + this.filetype);
      }

      //thinky extra stuff
      if (this.options.database === 'rethinkdb') {
        this.copy(path.join(__dirname, 'templates', 'extras', name + suffix, 'thinky-model-index.' + this.filetype), 'app/models/index.' + this.filetype);
        this.copy(path.join(__dirname, 'templates', 'extras', name + suffix, 'thinky-config.' + this.filetype), 'config/thinky.' + this.filetype);
      }

    },
    assetsDirs: function () {
      mkdirp.sync('public');
      mkdirp.sync('public/components');
      mkdirp.sync('public/js');
      mkdirp.sync('public/css');
      mkdirp.sync('public/img');
      if (this.options.database == 'sqlite') {
        mkdirp.sync('data');
      }
    }
  },
  install: function () {
    if(!this.options['skip-install']) this.installDependencies();
  }
});
<commit_msg>fix appname if creating directory<commit_after>'use strict';
var util = require('util');
var path = require('path');
var generators = require('yeoman-generator');
var glob = require('glob');
var slugify = require('underscore.string/slugify');
var mkdirp = require('mkdirp');

module.exports = generators.Base.extend({
  constructor: function () {
    generators.Base.apply(this, arguments);

    // add option to skip install
    this.option('skip-install');

    this.slugify = slugify;
  },
  prompting: {
    dir: function () {

      if (this.options.createDirectory !== undefined) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'confirm',
        name: 'createDirectory',
        message: 'Would you like to create a new directory for your project?'
      }];

      this.prompt(prompt, function (response) {
        this.options.createDirectory = response.createDirectory;
        done();
      }.bind(this));
    },
    dirname: function () {

      if (!this.options.createDirectory || this.options.dirname) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'input',
        name: 'dirname',
        message: 'Enter directory name'
      }];

      this.prompt(prompt, function (response) {
        this.options.dirname = response.dirname;
        done();
      }.bind(this));
    },
    type: function () {
      // Short circuit if an option was explicitly specified
      if (this.options.mvc || this.options.basic) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'list',
        name: 'type',
        message: 'Select a version to install:',
        choices: [
          'Basic',
          'MVC'
        ],
        store: true
      }];

      this.prompt(prompt, function (responses) {
        this.options.mvc = responses.type.match(/^MVC$/i) !== null;
        done();
      }.bind(this));
    },
    viewEngine: function () {

      if (this.options.viewEngine) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'list',
        name: 'viewEngine',
        message: 'Select a view engine to use:',
        choices: [
          'Jade',
          'Swig',
          'EJS',
          'Handlebars',
          'Marko'
        ],
        store: true
      }];

      this.prompt(prompt, function (response) {
        this.options.viewEngine = response.viewEngine.toLowerCase();
        done();
      }.bind(this));
    },
    cssPreprocessor: function () {

      if (this.options.cssPreprocessor) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'list',
        name: 'cssPreprocessor',
        message: 'Select a css preprocessor to use (Sass Requires Ruby):' ,
        choices: [
          'None',
          'Node-Sass',
          'Sass',
          'less',
          'Stylus'
        ],
        store: true
      }];

      this.prompt(prompt, function (response) {
        this.options.cssPreprocessor = response.cssPreprocessor.toLowerCase();
        done();
      }.bind(this));
    },
    database: function () {

      if (this.options.database || !this.options.mvc) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'list',
        name: 'database',
        message: 'Select a database to use:',
        choices: [
          'None',
          'MongoDB',
          'MySQL',
          'PostgreSQL',
          'RethinkDB',
          'SQLite'
        ],
        store: true
      }];
      this.prompt(prompt, function (response) {
        this.options.database = response.database.toLowerCase();
        done();
      }.bind(this));
    },
    buildTool: function () {

      if (this.options.buildTool) {
        return true;
      }

      var done = this.async();
      var prompt = [{
        type: 'list',
        name: 'buildTool',
        message: 'Select a build tool to use:',
        choices: [
          'Grunt',
          'Gulp'
        ],
        store: true
      }];

      this.prompt(prompt, function (response) {
        this.options.buildTool = response.buildTool.toLowerCase();
        done();
      }.bind(this));

    }
  },
  writing: {
    buildEnv: function () {

      // create directory
      if(this.options.createDirectory){
        this.destinationRoot(this.options.dirname);
        this.appname = this.options.dirname;
      }

      var name = this.options.mvc ? 'mvc' : 'basic';
      var suffix = this.options.coffee ? '-coffee' : '';
      this.filetype = 'js';
      if(this.options.coffee) this.filetype = 'coffee';

      // shared across all generators
      this.sourceRoot(path.join(__dirname, 'templates', 'shared'));
      glob.sync('**', { cwd: this.sourceRoot() }).map(function (file) {
        this.template(file, file.replace(/^_/, ''));
      }, this);

      // shared for mvc/basic generators
      this.sourceRoot(path.join(__dirname, 'templates', name + '-shared'));
      this.directory('.', '.');

      // templates
      this.sourceRoot(path.join(__dirname, 'templates', name + suffix));
      this.directory('.', '.');

      // views
      var views = this.options.viewEngine;
      this.sourceRoot(path.join(__dirname, 'templates', 'views', views));
      if (this.options.mvc) {
        this.directory('.', 'app/views');
      } else {
        this.directory('.', 'views');
      }

      // css
      var stylesheets = this.options.cssPreprocessor;
      if(stylesheets === 'none') stylesheets = 'css';
      if(stylesheets === 'node-sass') stylesheets = 'sass';
      this.sourceRoot(path.join(__dirname, 'templates', 'css', stylesheets));
      this.directory('.', 'public/css');

      // grunt/gulp
      var buildFile = this.options.buildTool === 'grunt' ? 'Gruntfile.js' : 'gulpfile.js';
      this.copy(path.join(__dirname, 'templates', 'extras', name + '-shared', buildFile), buildFile);

      // sequelize extra stuff
      if (this.options.database === 'mysql' ||
          this.options.database === 'postgresql' ||
          this.options.database === 'sqlite') {
        this.copy(path.join(__dirname, 'templates', 'extras', name + suffix, 'sequelize-model-index.' + this.filetype), 'app/models/index.' + this.filetype);
      }

      //thinky extra stuff
      if (this.options.database === 'rethinkdb') {
        this.copy(path.join(__dirname, 'templates', 'extras', name + suffix, 'thinky-model-index.' + this.filetype), 'app/models/index.' + this.filetype);
        this.copy(path.join(__dirname, 'templates', 'extras', name + suffix, 'thinky-config.' + this.filetype), 'config/thinky.' + this.filetype);
      }

    },
    assetsDirs: function () {
      mkdirp.sync('public');
      mkdirp.sync('public/components');
      mkdirp.sync('public/js');
      mkdirp.sync('public/css');
      mkdirp.sync('public/img');
      if (this.options.database == 'sqlite') {
        mkdirp.sync('data');
      }
    }
  },
  install: function () {
    if(!this.options['skip-install']) this.installDependencies();
  }
});
<|endoftext|>