通过Streams进行SVN日志解析

时间:2013-11-01 10:51:27

标签: node.js

我试图通过流解析svn提交日志。我有一些工作在一个存储库,但如果我尝试做两个不同的存储库,它不会像我想的那样工作。如果我在getLatest()中使用svn_parse,它会向我显示第一个repo消息两次。如果我按照下面的方式执行,我会获得第二次回购消息。我怎么能按照我的意愿让这个工作?

var svn_parse = require('./svn_stream_parser'),
  spawn = require('child_process').spawn;

function getLatest(repo) {
  var sp = require('./svn_stream_parser');
  var svn = spawn('svn', ['log', '-v', '-l', '1', repo]);
  sp(svn.stdout).pipe(process.stdout);
}

getLatest('https://github.com/emberjs/ember.js');
getLatest('https://github.com/emberjs/starter-kit');

svn_stream_parser.js:

var BufferStream = require('bufferstream'),
  through = require('through'),
  _ = require('lodash');

var bufferstream = new BufferStream({encoding:'utf8', size:'flexible'});
bufferstream.split('------------------------------------------------------------------------\n');
bufferstream.on('split', function (chunk) {
  bufferstream.emit('data', chunk)
});

function parseStream(istream) {
  return istream.pipe(bufferstream)
    .pipe(through(function(chunk) {
      var str = chunk.toString();
      if(str.trim().length === 0) return;
      var commitObj = parseCommit(str);
      this.queue(JSON.stringify(commitObj) + '\n');
    }));
}

function parseCommit(commit) {
  var commitSplit = commit.split('\n');

  var summarySplit = commitSplit.shift().split('|');
  var commitObject = {
/*    repository: repositoryUrl,*/
    revision: summarySplit[0].trim().substring(1),
    author: summarySplit[1].trim(),
    timestamp: summarySplit[2].trim(),
    files: [],
    messages: []
  };

  var idx = 0;
  if(commitSplit[0].trim() === 'Changed paths:') {
    // Start at 1 because 0 is expected to be an empty string
    //  inserted for formatting
    for(idx = 1; idx < commitSplit.length; idx++) {
      var fileInfo = commitSplit[idx].trim();
      if(fileInfo.length === 0) {
        break; // File change block is contiguous, empty line means the block is done
      }
      commitObject.files.push({
        operation: fileInfo.substring(0,1),
        path: fileInfo.substring(2)
      });
    }
  }

  // Parse the remaining lines, they should all be the commit message
  _.forEach(commitSplit.slice(idx + 1), function(msg) {
    msg = msg.trim();
    if(msg.length > 0) {
      commitObject.messages.push(msg);
    }
  });
  return commitObject;
}

module.exports = parseStream;

1 个答案:

答案 0 :(得分:1)

问题是我的缓冲流声明的方式,应该是

function parseStream(istream) {
  var bufferstream = new BufferStream({encoding:'utf8', size:'flexible'});
  bufferstream.split('------------------------------------------------------------------------\n');
  bufferstream.on('split', function (chunk) {
    bufferstream.emit('data', chunk)
  });

  return istream.pipe(bufferstream)
    .pipe(through(function(chunk) {
      var str = chunk.toString();
      if(str.trim().length === 0) return;
      var commitObj = parseCommit(str);
      this.queue(JSON.stringify(commitObj) + '\n');
    }));
}