<commit_before>var argv     = require('optimist').argv,
    archiver = require('archiver'),
    async    = require('async'),
    colors   = require('colors'),
    fse      = require('fs-extra'),
    git      = require('gift'),
    nconf    = require('nconf'),
    request  = require('request'),
    scripty  = require('azure-scripty'),
    tmpDirs  = require('tmp');

var state = {};
var NumRetries = 3;
var defaultPingDelay = 7500;

function run(callback) {
  async.series([
    read_config,
    read_existing_apps,
    make_app
  ], callback);
}

function usage() {
  console.log('Usage: node e2esetup [options] jsonOptions');
  console.log("   options:");
  console.log("      --name               app name");
  console.log("      --useExistingApp     Whether to re-use an existing app instead of recreating it each time: 'true' or 'false' (default is 'false' if not specified)");
  console.log("      --platform           app platform (DotNet / Node)");
  console.log("      --location           app location (e.g. West US)");
  console.log("      --sql:server         SQL server name");
  console.log("      --sql:db             database name");
  console.log("      --sql:user           database username");
  console.log("      --sql:password       database password");
  console.log("      --appKey             application key");
  console.log("      --corsWhitelist      CORS whitelist (e.g. 'ms-appx-web://10805zumoTestUser.zumotestblu2' or '10805zumoTestUser.zumotestblu2')");
  console.log("      --srcFiles           Optional path to the runtime user source files (these are pushed through Git)");
  console.log("      --binFiles           Optional path to the runtime user binary files (these are uploaded through Kudu at /site/wwwroot)");
  console.log("      --configFile:        JSON file with additional configs for a Node app. See the provided templates.");
  console.log("      --tier:              The tier level for the app i.e Free, basic or standard");
  console.log("      --pingEndpoint:      Endpoint to ping (GET) after app is created (e.g. 'status' or 'tables/movies')");
  console.log("      --pingDelay:         Time (in milliseconds) to wait before pinging the pingEndpoint (default: " + defaultPingDelay + ")");
  console.log("      --siteExtensionPath  ");
  console.log();
  console.log("   jsonOptions:");
  console.log("      JSON file with configuration settings as specified above. See the supplied templates.");
  console.log("      Values specified in the command line take precedence.");
  console.log();
}

function read_config(callback) {
  if (argv._.length != 1) {
    // Should have only one free argument, which is the config file name
    usage();
    return callback('Invalid input.');
  }
  var configFile = argv._[0];
  process.stdout.write('Reading config...');
  nconf.argv().file({ file: configFile });

  console.log(' OK'.green.bold);
  callback();
}

function read_existing_apps(callback) {
  process.stdout.write('Reading existing apps...');
  scripty.invoke('mobile list', function(err, results) {
    if (!err) {
      state.existingApps = results;
      process.stdout.write(' OK'.green.bold + '\n');
      process.stdout.write('   Found ' + state.existingApps.length + ' apps:\n');
      state.existingApps.forEach(function(a) {
        process.stdout.write('      ' + a.name + '\n');
      });
      process.stdout.write('\n');
    }
    callback(err);
  });
}

function make_app(callback) {
  console.log('');
  console.log('======== Processing app: '.white.bold + nconf.get('name') + ' ========');
  
  async.series(
    [
      function(done) {
        var existingApp = null;
        var appName = nconf.get('name');
        state.existingApps.forEach(function(i) {
          if (i.name.toLowerCase() == appName.toLowerCase()) {
            existingApp = i;
          }
        });
        if (existingApp) {
          var useExistingApp = (nconf.get('useExistingApp') || 'false').toLowerCase();
          if (useExistingApp == 'false') {
            console.log('   App already exists. Deleting and recreating it...');
            async.series([
              delete_app,
              create_app
            ], done);
          } else if (useExistingApp == 'true') {
            console.log('   App already exists and will be re-used...');
            done();
          } else {
            done('Configuration value "useExistingApp" must be "true" or "false" (default).');
          }
        } else {
          console.log('   App does not currently exist and will be created');
          create_app(done);
        }
      },
      scale_app,
      setup_app
    ], callback);
}

function delete_app(callback) {
  process.stdout.write('   Deleting existing app...');
  scripty.invoke('mobile delete --deleteData --quiet ' + nconf.get('name'), function(err, results) {
    if (!err) {
      process.stdout.write(' OK'.green.bold + '\n');
    }
    callback(err);
  });
}

function create_app(callback) {
  process.stdout.write('   Creating new app...');

  var cmd = {
    command: 'mobile create',
    sqlServer: nconf.get('sql:server'),
    sqlDb: nconf.get('sql:db'),
    location: '"' + nconf.get('location') + '"',
    backend: nconf.get('platform'),
    positional: [nconf.get('name'), nconf.get('sql:user'), nconf.get('sql:password')]
  };
  scripty.invoke(cmd, function(err, results) {
      if (!err) {
        console.log(' OK'.green.bold);
      }
      callback(err);
    });
}


function scale_app(callback) {
  var tier = (nconf.get('tier') || 'free').toLowerCase();
  if (tier == 'free') {
    return callback();
  }
  process.stdout.write('   Scaling the app to \'' + tier + '\' tier...');
  scripty.invoke('mobile scale change --tier '+ nconf.get('tier') + ' ' + nconf.get('name'), function(err, results) {<commit_msg>Update E2E App setup script to include push flag<commit_after>var argv     = require('optimist').argv,
    archiver = require('archiver'),
    async    = require('async'),
    colors   = require('colors'),
    fse      = require('fs-extra'),
    git      = require('gift'),
    nconf    = require('nconf'),
    request  = require('request'),
    scripty  = require('azure-scripty'),
    tmpDirs  = require('tmp');

var state = {};
var NumRetries = 3;
var defaultPingDelay = 7500;

function run(callback) {
  async.series([
    read_config,
    read_existing_apps,
    make_app
  ], callback);
}

function usage() {
  console.log('Usage: node e2esetup [options] jsonOptions');
  console.log("   options:");
  console.log("      --name               app name");
  console.log("      --useExistingApp     Whether to re-use an existing app instead of recreating it each time: 'true' or 'false' (default is 'false' if not specified)");
  console.log("      --platform           app platform (DotNet / Node)");
  console.log("      --location           app location (e.g. West US)");
  console.log("      --sql:server         SQL server name");
  console.log("      --sql:db             database name");
  console.log("      --sql:user           database username");
  console.log("      --sql:password       database password");
  console.log("      --appKey             application key");
  console.log("      --corsWhitelist      CORS whitelist (e.g. 'ms-appx-web://10805zumoTestUser.zumotestblu2' or '10805zumoTestUser.zumotestblu2')");
  console.log("      --srcFiles           Optional path to the runtime user source files (these are pushed through Git)");
  console.log("      --binFiles           Optional path to the runtime user binary files (these are uploaded through Kudu at /site/wwwroot)");
  console.log("      --configFile:        JSON file with additional configs for a Node app. See the provided templates.");
  console.log("      --tier:              The tier level for the app i.e Free, basic or standard");
  console.log("      --pingEndpoint:      Endpoint to ping (GET) after app is created (e.g. 'status' or 'tables/movies')");
  console.log("      --pingDelay:         Time (in milliseconds) to wait before pinging the pingEndpoint (default: " + defaultPingDelay + ")");
  console.log("      --siteExtensionPath  ");
  console.log();
  console.log("   jsonOptions:");
  console.log("      JSON file with configuration settings as specified above. See the supplied templates.");
  console.log("      Values specified in the command line take precedence.");
  console.log();
}

function read_config(callback) {
  if (argv._.length != 1) {
    // Should have only one free argument, which is the config file name
    usage();
    return callback('Invalid input.');
  }
  var configFile = argv._[0];
  process.stdout.write('Reading config...');
  nconf.argv().file({ file: configFile });

  console.log(' OK'.green.bold);
  callback();
}

function read_existing_apps(callback) {
  process.stdout.write('Reading existing apps...');
  scripty.invoke('mobile list', function(err, results) {
    if (!err) {
      state.existingApps = results;
      process.stdout.write(' OK'.green.bold + '\n');
      process.stdout.write('   Found ' + state.existingApps.length + ' apps:\n');
      state.existingApps.forEach(function(a) {
        process.stdout.write('      ' + a.name + '\n');
      });
      process.stdout.write('\n');
    }
    callback(err);
  });
}

function make_app(callback) {
  console.log('');
  console.log('======== Processing app: '.white.bold + nconf.get('name') + ' ========');
  
  async.series(
    [
      function(done) {
        var existingApp = null;
        var appName = nconf.get('name');
        state.existingApps.forEach(function(i) {
          if (i.name.toLowerCase() == appName.toLowerCase()) {
            existingApp = i;
          }
        });
        if (existingApp) {
          var useExistingApp = (nconf.get('useExistingApp') || 'false').toLowerCase();
          if (useExistingApp == 'false') {
            console.log('   App already exists. Deleting and recreating it...');
            async.series([
              delete_app,
              create_app
            ], done);
          } else if (useExistingApp == 'true') {
            console.log('   App already exists and will be re-used...');
            done();
          } else {
            done('Configuration value "useExistingApp" must be "true" or "false" (default).');
          }
        } else {
          console.log('   App does not currently exist and will be created');
          create_app(done);
        }
      },
      scale_app,
      setup_app
    ], callback);
}

function delete_app(callback) {
  process.stdout.write('   Deleting existing app...');
  scripty.invoke('mobile delete --deleteData --quiet ' + nconf.get('name'), function(err, results) {
    if (!err) {
      process.stdout.write(' OK'.green.bold + '\n');
    }
    callback(err);
  });
}

function create_app(callback) {
  process.stdout.write('   Creating new app...');

  var cmd = {
    command: 'mobile create -p nh',
    sqlServer: nconf.get('sql:server'),
    sqlDb: nconf.get('sql:db'),
    location: '"' + nconf.get('location') + '"',
    backend: nconf.get('platform'),
    positional: [nconf.get('name'), nconf.get('sql:user'), nconf.get('sql:password')]
  };
  scripty.invoke(cmd, function(err, results) {
      if (!err) {
        console.log(' OK'.green.bold);
      }
      callback(err);
    });
}


function scale_app(callback) {
  var tier = (nconf.get('tier') || 'free').toLowerCase();
  if (tier == 'free') {
    return callback();
  }
  process.stdout.write('   Scaling the app to \'' + tier + '\' tier...');
  scripty.invoke('mobile scale change --tier '+ nconf.get('tier') + ' ' + nconf.get('name'), function(err, results) {
{'fraction_non_alphanumeric': 0.15815669784604822, 'fraction_numerical': 0.003518407277096027, 'mean_word_length': 2.516596258298129, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1845984', 'n_tokens_mistral': 3511, 'n_tokens_neox': 3455, 'n_words': 898}