gocommand.js 3.8 KB
Newer Older
B
bryk 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Helper function that spawns a go binary process.
 */
import child from 'child_process';
import lodash from 'lodash';
20
import q from 'q';
B
bryk 已提交
21

22 23
import conf from './conf';

24 25 26 27 28
// Add base directory to the gopath so that local imports work.
const sourceGopath = `${conf.paths.backendTmp}`;
// Add the project's required go tools to the PATH.
const devPath = `${process.env.PATH}:${conf.paths.goTools}/bin`;

B
bryk 已提交
29
/**
30 31 32 33 34 35 36 37
 * The environment needed for the execution of any go command.
 */
const env = lodash.merge(process.env, {GOPATH: sourceGopath, PATH: devPath});

/**
 * Spawns a Go process wrapped with the Godep command after making sure all GO prerequisites are
 * present. Backend source files must be packaged with 'package-backend-source' task before running
 * this command.
B
bryk 已提交
38
 *
39 40
 * @param {!Array<string>} args - Arguments of the go command.
 * @param {function(?Error=)} doneFn - Callback.
B
bryk 已提交
41
 */
42
export default function spawnGoProcess(args, doneFn) {
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
  checkPrerequisites().then(() => spawnProcess(args)).then(doneFn).fail((error) => doneFn(error));
}

/**
 * Checks if all prerequisites for a go-command execution are present.
 * @return {Q.Promise} A promise object.
 */
function checkPrerequisites() {
  return checkGo().then(checkGodep);
}

/**
 * Checks if go is on the PATH prior to a go command execution, promises an error otherwise.
 * @return {Q.Promise} A promise object.
 */
function checkGo() {
  let deferred = q.defer();
  child.exec(
      'which go',
      {
        env: env,
      },
      function(error, stdout, stderror) {
        if (error || stderror || !stdout) {
          deferred.reject(
              new Error(
                  'Go is not on the path. Please pass the PATH variable when you run ' +
                  'the gulp task with "PATH=$PATH" or install go if you have not yet.'));
          return;
        }
        deferred.resolve();
      });
  return deferred.promise;
}
77

78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
/**
 * Checks if godep is on the PATH prior to a go command execution, promises an error otherwise.
 * @return {Q.Promise} A promise object.
 */
function checkGodep() {
  let deferred = q.defer();
  child.exec(
      'which godep',
      {
        env: env,
      },
      function(error, stdout, stderror) {
        if (error || stderror || !stdout) {
          deferred.reject(
              new Error(
                  'Godep is not on the path. ' +
                  'Please run "npm install" in the base directory of the project.'));
          return;
        }
        deferred.resolve();
      });
  return deferred.promise;
}
101

102 103 104 105 106 107 108 109 110
/**
 * Spawns Go process wrapped with the Godep command.
 * Promises an error if the go command process fails.
 *
 * @param {!Array<string>} args - Arguments of the go command.
 * @return {Q.Promise} A promise object.
 */
function spawnProcess(args) {
  let deferred = q.defer();
B
bryk 已提交
111
  let goTask = child.spawn('godep', ['go'].concat(args), {
112
    env: env,
113 114
    stdio: 'inherit',
  });
B
bryk 已提交
115 116 117
  // Call Gulp callback on task exit. This has to be done to make Gulp dependency management
  // work.
  goTask.on('exit', function(code) {
118 119 120
    if (code !== 0) {
      deferred.reject(Error(`Go command error, code: ${code}`));
      return;
B
bryk 已提交
121
    }
122
    deferred.resolve();
B
bryk 已提交
123
  });
124
  return deferred.promise;
B
bryk 已提交
125
}