This change detects if the user has `protoc` available and, if so, uses it to generate `.pb.dart` files. If not, pre-built files are used instead.
		
			
				
	
	
		
			124 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
var fs = require('fs');
 | 
						|
var glob = require('glob');
 | 
						|
var hashFiles = require('hash-files');
 | 
						|
var path = require('path');
 | 
						|
var protocDetect = require('./protoc').detect;
 | 
						|
var spawn = require('child_process').spawn;
 | 
						|
 | 
						|
// Hashs all .proto files at `config.dir`, calling `computedCallback` on each
 | 
						|
// when done with the original file name and its hash.
 | 
						|
// When all files have been hashed, calls `completeCallback` with no parameters.
 | 
						|
function _hashProtosTask(config, computedCallback, completeCallback) {
 | 
						|
  var files = glob.sync(path.join(config.dir, '*.proto'));
 | 
						|
  var toUpdate = {};
 | 
						|
  var checkComplete = function() {
 | 
						|
    for (var key in toUpdate) {
 | 
						|
      if (toUpdate.hasOwnProperty(key) && toUpdate[key]) {
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return true;
 | 
						|
  };
 | 
						|
  files.forEach(function(file) { toUpdate[file] = true; });
 | 
						|
  files.forEach(
 | 
						|
      function(file) {
 | 
						|
        hashFiles({
 | 
						|
          algorithm: config.algorithm || 'sha1',
 | 
						|
          files: [file]
 | 
						|
        }, function(error, hash) {
 | 
						|
          computedCallback(file, hash);
 | 
						|
          toUpdate[file] = false;
 | 
						|
          if (checkComplete()) {
 | 
						|
            completeCallback();
 | 
						|
          }
 | 
						|
        });
 | 
						|
      });
 | 
						|
}
 | 
						|
 | 
						|
function _toPbDartExtension(path) {
 | 
						|
  return path.replace(/\.proto$/, '.pb.dart');
 | 
						|
}
 | 
						|
 | 
						|
module.exports = {
 | 
						|
  // Generates `.pb.dart` files from all `.proto` files located at `config.dir`.
 | 
						|
  // This task requires the Dart protoc plugin, which is expected to reside at
 | 
						|
  // the path specified in `config.plugin`.
 | 
						|
  generate: function(config, done) {
 | 
						|
    // Note that while the Dart protoc plugin requires the Dart sdk, this task will be skipped if the
 | 
						|
    // Dart sdk is not available.
 | 
						|
    var protoc = protocDetect();
 | 
						|
    if (!protoc) {
 | 
						|
      done(new Error('Could not detect protoc - failed to rebuild Dart proto code.'));
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    var protoPaths = glob.sync(path.join(config.dir, '*.proto'));
 | 
						|
    var spawnArgs = [
 | 
						|
        '--plugin', config.plugin,
 | 
						|
        '--proto_path', config.dir,
 | 
						|
        '--dart_out', config.dir,
 | 
						|
    ].concat(protoPaths);
 | 
						|
    var proc = spawn(protoc.bin, spawnArgs, {
 | 
						|
      cwd: '.',
 | 
						|
      stdio: ['ignore', 2, 'inherit']
 | 
						|
    });
 | 
						|
    var failed = false;
 | 
						|
    var failWithError = function(msg) {
 | 
						|
      if (failed) return;
 | 
						|
      failed = true;
 | 
						|
      done(new Error('Failed while generating transformer boilerplate. Check for output above.\n' +
 | 
						|
                     'Message: ' + msg + '\n' +
 | 
						|
                     'Please run manually: ' + [protoc.bin].concat(spawnArgs).join(' ')));
 | 
						|
    };
 | 
						|
    proc.on('error', function(err) { failWithError(String(err)); });
 | 
						|
    proc.on('exit', function(code, signal) {
 | 
						|
      if (!code) {
 | 
						|
        var protocHash = hashFiles.sync({
 | 
						|
          algorithm: config.algorithm || 'sha1',
 | 
						|
          files: [config.plugin]
 | 
						|
        });
 | 
						|
        var computedCallback = function(fileName, hash) {
 | 
						|
          var pbDartPath = _toPbDartExtension(fileName);
 | 
						|
          var toAppend = '/**\n' +
 | 
						|
                         ' * Generated with:\n' +
 | 
						|
                         ' * ' + path.basename(fileName) + ' (' + hash + ')\n' +
 | 
						|
                         ' * ' + protoc.version + '\n' +
 | 
						|
                         ' * dart-protoc-plugin (' + protocHash + ')\n' +
 | 
						|
                         ' */\n';
 | 
						|
          fs.appendFileSync(pbDartPath, toAppend);
 | 
						|
        };
 | 
						|
        return _hashProtosTask(config, computedCallback, function() { done(); });
 | 
						|
      } else {
 | 
						|
        failWithError('Exit code was ' + code);
 | 
						|
      }
 | 
						|
    });
 | 
						|
  },
 | 
						|
 | 
						|
  // Checks that the `.pb.dart` files located at `config.dir` are in sync with
 | 
						|
  // the `proto` files at the same directory.
 | 
						|
  // It does this by computing the hash of the `.proto` files and looking for
 | 
						|
  // that string in the contents of the associated `.pb.dart` file. If one or
 | 
						|
  // more file(s) do not have that hash present, this task will fail with a
 | 
						|
  // descriptive error message.
 | 
						|
  lint: function(config, done) {
 | 
						|
    var missing = [];
 | 
						|
    var computedCallback = function(filePath, hash) {
 | 
						|
      var pbDartPath = _toPbDartExtension(filePath);
 | 
						|
      if (String(fs.readFileSync(pbDartPath)).indexOf(hash) < 0) {
 | 
						|
        missing.push('  ' + hash  + ' not found in ' + pbDartPath + '\n');
 | 
						|
      }
 | 
						|
    };
 | 
						|
    var completeCallback = function() {
 | 
						|
      if (missing.length == 0) {
 | 
						|
        done();
 | 
						|
      } else {
 | 
						|
        done(new Error(
 | 
						|
            'Generated Dart protobuf files are out of date. Please run `gulp gen_protos.dart`.\n' +
 | 
						|
            missing.join(''))
 | 
						|
        );
 | 
						|
      }
 | 
						|
    };
 | 
						|
    return _hashProtosTask(config, computedCallback, completeCallback);
 | 
						|
  }
 | 
						|
};
 |