all files / src/commitizen/ adapter.js

95% Statements 38/40
85.19% Branches 23/27
100% Functions 7/7
94.29% Lines 33/35
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 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145                                                              12×   12×               12× 12×     12× 12× 12× 12×   12×           13×     13×     13× 52× 15×       13×           12×     12×       12×                 12×           13×                                                                      
import path from 'path';
import fs from 'fs';
import findNodeModules from 'find-node-modules';
import _ from 'lodash';
import detectIndent from 'detect-indent';
 
import {isFunction} from '../common/util';
 
export {
  addPathToAdapterConfig,
  getNearestNodeModulesDirectory,
  getNearestProjectRootDirectory,
  getNpmInstallStringMappings,
  getPrompter,
  generateNpmInstallAdapterCommand,
  resolveAdapterPath
};
 
/**
 * ADAPTER
 *
 * Adapter is generally responsible for actually installing adapters to an
 * end user's project. It does not perform checks to determine if there is
 * a previous commitizen adapter installed or if the proper fields were
 * provided. It defers that responsibility to init.
 */
 
/**
 * Modifies the package.json, sets config.commitizen.path to the path of the adapter
 * Must be passed an absolute path to the cli's root
 */
function addPathToAdapterConfig(sh, cliPath, repoPath, adapterNpmName) {
  
  let commitizenAdapterConfig = {
    config: {
      commitizen: {
        path: `./node_modules/${adapterNpmName}`
      }
    }
  };
  
  let packageJsonPath = path.join(getNearestProjectRootDirectory(), 'package.json');
  let packageJsonString = fs.readFileSync(packageJsonPath, 'utf-8');
  // tries to detect the indentation and falls back to a default if it can't
  let indent = detectIndent(packageJsonString).indent || '  ';
  let packageJsonContent = JSON.parse(packageJsonString);
  let newPackageJsonContent = '';
  Eif(_.get(packageJsonContent,'config.commitizen.path') !== adapterNpmName) {
    newPackageJsonContent = _.merge(packageJsonContent, commitizenAdapterConfig);
  }
  fs.writeFileSync(packageJsonPath, JSON.stringify(newPackageJsonContent, null, indent));
}
 
/**
 * Generates an npm install command given a map of strings and a package name
 */
function generateNpmInstallAdapterCommand(stringMappings, adapterNpmName) {
 
  // Start with an initial npm install command
  let installAdapterCommand = `npm install ${adapterNpmName}`;
  
  // Append the neccesary arguments to it based on user preferences
  for(let [key, value] of stringMappings.entries()) {
    if(value) {
      installAdapterCommand = installAdapterCommand + ' ' + value;
    }
  }
  
  return installAdapterCommand;
}
 
/**
 * Gets the nearest npm_modules directory
 */
function getNearestNodeModulesDirectory(options) E{
  
  // Get the nearest node_modules directories to the current working directory
  let nodeModulesDirectories = findNodeModules(options);
  
   // Make sure we find a node_modules folder
  if(nodeModulesDirectories && nodeModulesDirectories.length > 0) {
    return nodeModulesDirectories[0];
  } else {
    console.error(`Error: Could not locate node_modules in your project's root directory. Did you forget to npm init or npm install?`)
  }
}
 
/**
 * Gets the nearest project root directory
 */
function getNearestProjectRootDirectory(options) {
  return path.join(process.cwd(), getNearestNodeModulesDirectory(options), '/../');
}
 
/**
 * Gets a map of arguments where the value is the corresponding npm strings
 */
function getNpmInstallStringMappings(save, saveDev, saveExact, force) {
  return new Map()
    .set('save', (save && !saveDev) ? '--save':undefined)
    .set('saveDev', saveDev ? '--save-dev':undefined)
    .set('saveExact', saveExact ? '--save-exact':undefined)
    .set('force', force ? '--force':undefined);
}
 
/**
 * Gets the prompter from an adapter given an adapter path
 */
function getPrompter(adapterPath) {
  // Resolve the adapter path
  let resolvedAdapterPath = resolveAdapterPath(adapterPath);
 
  // Load the adapter
  let adapter = require(resolvedAdapterPath);
  
  Eif(adapter && adapter.prompter && isFunction(adapter.prompter)) {
     return adapter.prompter;
  } else {
    throw "Could not find prompter method in the provided adapter module: " + adapterPath;
  }
}
 
/**
 * Given a resolvable module name or path, which can be a directory or file, will
 * return a located adapter path or will throw.
 */
function resolveAdapterPath(inboundAdapterPath) {
  // Check if inboundAdapterPath is a path or node module name
  let parsed = path.parse(inboundAdapterPath);
  let isPath = parsed.dir.length > 0;
  
  // Resolve from process.cwd() if inboundAdapterPath is a path
  let absoluteAdapterPath = isPath ?
    path.resolve(process.cwd(), inboundAdapterPath) :
    inboundAdapterPath;
  
  try {
    // try to resolve the given path
    return require.resolve(absoluteAdapterPath);
  } catch (error) {
    error.message = "Could not resolve " + absoluteAdapterPath, ". " + error.message;
    throw error;
  }
}