# Code coverage report for lib/git/index.js

## Statements: 100% (58 / 58) Branches: 100% (22 / 22) Functions: 100% (9 / 9) Lines: 100% (58 / 58) Ignored: 3 statements, 2 branches

All files » lib/git/ » index.js

    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
    1281
    1
    1
    1
    1

    1

    1

    1

    1

    1

    1
    7
    5
    5
    5
    5
    5
    1
    1
    1

    1

    6

    6
    2
    4
    4

    1

    1
    1

    1
    1

    1

    1
    7

    7

    3
    3

    7
    1

    6

    1
    5

    1

    6

    6
    1

    5

    7

    7

    7
    2

    5

    5
    5
    1

    4
    4

    1

     var _ = require('underscore');
    var fs = require('fs');
    var path = require('path');
    var mkdirp = require('mkdirp');
    var util = require('util');

    var config_reader = require('../config_reader.js');

    var logger = require('../logging.js');

    var Repo = require('./repo.js');

    // By default, git2consul expects to run as a daemon.  If this flag is disabled, git2consul will not
    // start any hooks and will shut down after initializing each branch in each repo.
    Object.defineProperty(exports, 'daemon', {value: true, writable: true});

    // Track all active GitManager objects so we can traverse them as needed for a graceful shutdown.
    Object.defineProperty(exports, 'repos', { value: {} });

    // End the process once we are sure that no branches are busy updating.
    exports.gracefulShutdown = function(cb) {
      for (var repo_name in exports.repos) {
        var repo = exports.repos[repo_name];
        for (var i=0; i<repo.branch_names.length; ++i) {
          var branch_name = repo.branch_names[i];
          var branch = repo.getBranch(branch_name);
          if (branch && branch.busy) {
            logger.warn("Waiting for branch %s in repo %s", branch.name, repo_name);
            setTimeout(function() {
              exports.gracefulShutdown(cb);
            }, 1000);
            return;
          }
        }
      }

      // In some cases (such as unit tests), it might be good to know that halt was called.
      exports.halt_seen = true;

      /* istanbul ignore else */
      // If this method has a callback, fire it rather than killing the process.
      if (cb) {
        cb();
      } else Eif ((process.argv[1].indexOf('_mocha'), process.argv[1].length - 6) != -1) {
        logger.warn("Process is running in unit test.  Ignore shutdown.");
      } else {
        process.exit(0);
      }
    };

    /**
     * Halt all git_managers if git2consul config changes.
     */
    var enableHaltOnChange = function() {
      config_reader.wait(function(err) {
        /* istanbul ignore if */
        Iif (err) {
          return logger.error("config poll failure due to %s.  Ignoring...", err);
        }

        exports.gracefulShutdown();
      });
    };

    /**
     * Provided a configuration object, walk all repo configs and initialize the child repos.
     */
    exports.createRepos = function(config, cb) {
      var this_obj = this;

      var error_handler = function(err) {
        // Report the error to cb but also gracefully shutdown.
        exports.gracefulShutdown();
        cb(err);
      };

      // Validate that local_store exists.
      if (!config.local_store) {
        return error_handler("No local_store provided");
      }

      if (config.no_daemon === true) {
        // If we are running in no daemon mode, set git to disable any listeners that would keep
        // the process running after the initial sync.
        exports.daemon = false;
      } else if (config.halt_on_change === true) {
        // If we aren't running in no daemon mode and the configuration calls for halt on change, enable it.
        // We don't do this if config.no_daemon is enabled as the halt on change listener would keep the process
        // running.
        enableHaltOnChange();
      }

      // Build the root_directory, if necessary
      mkdirp(config.local_store, function(err) {

        if (err) {
          return error_handler("Failed to create local store " + config.local_store);
        }

        config.repos.forEach(function(repo_config) {

          try {
            // Each repo needs a copy of config.local_store
            repo_config.local_store = config.local_store;

            // Validate repo name is unique.
            if (exports.repos[repo_config.name]) {
              return cb("A repo with that name is already tracked.");
            }
            exports.repos[repo_config.name] = new Repo(repo_config);

            exports.repos[repo_config.name].init(function(err) {
              if (err) {
                return error_handler("Failed to load repo " + repo_config.name + " due to " + err);
              }

              logger.info("Loaded repo %s", repo_config.name);
              cb();
            });
          } catch(e) {
            /* istanbul ignore next */
            error_handler(e);
          }
        });
      });
    };