all files / src/commitizen/ init.js

100% Statements 11/11
86.36% Branches 19/22
100% Functions 3/3
100% Lines 11/11
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                                                                                                                                14×                                                   12×                           14×     14×     14×                   14×          
import path from 'path';
import * as configLoader from './configLoader';
import {executeShellCommand} from '../common/util';
import * as adapter from './adapter';
 
let {
  addPathToAdapterConfig,
  generateNpmInstallAdapterCommand,
  getNpmInstallStringMappings
} = adapter;
 
export default init;
 
const CLI_PATH = path.normalize(__dirname + '/../../');
 
/**
 * CZ INIT
 * 
 * Init is generally responsible for initializing an adapter in
 * a user's project. The goal is to be able to run 
 * `commitizen init` and be prompted for certain fields which
 * will help you install the proper adapter for your project.
 * 
 * Init does not actually create the adapter (it defers to adapter
 * for this). Instead, it is specifically designed to help gather
 * and validate the information needed to install the adapter
 * properly without interfering with a previous adapter config.
 */
 
/**
 * The defaults for init
 */
const defaultInitOptions = {
  save: false,
  saveDev: true,
  saveExact: false,
  force: false
};
 
/**
 * Runs npm install for the adapter then modifies the config.commitizen as needed
 */
function init(sh, repoPath, adapterNpmName, {
  save = false, 
  saveDev = true, 
  saveExact = false,
  force = false
} = defaultInitOptions) {
  
  // Don't let things move forward if required args are missing
  checkRequiredArguments(sh, repoPath, adapterNpmName);
  
  // Move to the correct directory so we can run commands
  sh.cd(repoPath);
  
  // Load the current adapter config
  let adapterConfig = loadAdapterConfig();
  
  // Get the npm string mappings based on the arguments provided
  let stringMappings = getNpmInstallStringMappings(save, saveDev, saveExact, force);
    
  // Generate a string that represents the npm install command
  let installAdapterCommand = generateNpmInstallAdapterCommand(stringMappings, adapterNpmName);
 
  // Check for previously installed adapters
  if(adapterConfig && adapterConfig.path && adapterConfig.path.length>0) {
    
    // console.log(`
    //   Previous adapter detected! 
    // `);
    
    if(!force) { 
      
      // console.log(`
      //   Previous adapter detected! 
      // `);
      
      throw 'A previous adapter is already configured. Use --force to override';  
    } else { // Override it
      try {
        executeShellCommand(sh, repoPath, installAdapterCommand);
        addPathToAdapterConfig(sh, CLI_PATH, repoPath, adapterNpmName); 
      } catch (e) {
        console.error(e);
      }
    }
    
  } else {
    
    // console.log(`
    //   No previous adapter was detected 
    // `); 
 
    try {
      
      executeShellCommand(sh, repoPath, installAdapterCommand);
      addPathToAdapterConfig(sh, CLI_PATH, repoPath, adapterNpmName);
    } catch (e) {
      console.error(e);
    }
  }
}
 
/**
 * Checks to make sure that the required arguments are passed
 * Throws an exception if any are not.
 */
function checkRequiredArguments(sh, path, adapterNpmName) {
  Iif(!sh) {
    throw "You must pass an instance of shelljs when running init.";
  }
  Iif(!path) {
    throw "Path is required when running init.";
  }
  Iif(!adapterNpmName) {
    throw "The adapter's npm name is required when running init.";
  }
}
 
/**
 * CONFIG
 * Loads and returns the adapter config at key config.commitizen, if it exists
 */
function loadAdapterConfig() {
  let config = configLoader.load();
  if(config) {
    return config; 
  } else {
    return;
  }
}