Skip to content

Split diffs based on file headers instead of 'Index:' metadata #88

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 12, 2015
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 21 additions & 22 deletions src/patch/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,40 @@ export function parsePatch(uniDiff, options = {}) {
let index = {};
list.push(index);

// Ignore any leading junk
// Parse diff metadata
while (i < diffstr.length) {
if (/^(Index:|diff -r|@@)/.test(diffstr[i])) {
let line = diffstr[i];

// File header found, end parsing diff metadata
if (/^(\-\-\-|\+\+\+|@@)\s/.test(line)) {
break;
}
i++;
}

let header = (/^(?:Index:|diff(?: -r \w+)+) (.*)/.exec(diffstr[i]));
if (header) {
index.index = header[1];
i++;

if (/^===/.test(diffstr[i])) {
i++;
// Diff index
let header = (/^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/).exec(line);
if (header) {
index.index = header[1];
}

parseFileHeader(index);
parseFileHeader(index);
} else {
// Ignore erant header components that might occur at the start of the file
parseFileHeader({});
parseFileHeader({});
i++;
}

parseFileHeader(index);
parseFileHeader(index);

// Parse hunks
index.hunks = [];

while (i < diffstr.length) {
if (/^(Index:|diff -r)/.test(diffstr[i])) {
let line = diffstr[i];

if (/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(line)) {
break;
} else if (/^@@/.test(diffstr[i])) {
} else if (/^@@\s/.test(line)) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More restrictive than before. Why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To prevent the case where the line start with @@whatever, that in strict mode it should throw an error instead of think it's a new hunk.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relax both this and the changes down below. This is not a spec we are dealing with but a bunch of random projects that are hobbled together based on arbitrary documentation. We should follow Postel's law here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should follow the spec and the projects bad using it should fix themselves because being less restrictive here would lead to errors otherwise, but since we already are accepting hunks without file headers (that's not supported by the standard, but there's no technical issues for accept it) and there's other projects using the library that would break, I'll remove the \s.

index.hunks.push(parseHunk());
} else if (diffstr[i] && options.strict) {
} else if (line && options.strict) {
// Ignore unexpected content unless in strict mode
throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(diffstr[i]));
throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(line));
} else {
i++;
}
Expand All @@ -51,7 +50,7 @@ export function parsePatch(uniDiff, options = {}) {
// Parses the --- and +++ headers, if none are found, no lines
// are consumed.
function parseFileHeader(index) {
let fileHeader = (/^(\-\-\-|\+\+\+)\s(\S+)\s?(.*)/.exec(diffstr[i]));
let fileHeader = (/^(\-\-\-|\+\+\+)\s+(\S+)\s?(.+)/).exec(diffstr[i]);
if (fileHeader) {
let keyPrefix = fileHeader[1] === '---' ? 'old' : 'new';
index[keyPrefix + 'FileName'] = fileHeader[2];
Expand Down
4 changes: 2 additions & 2 deletions test/patch/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ Index: test2
});
it('should throw on invalid input in strict mode', function() {
expect(function() {
parsePatch('Index: foo\nfoo', {strict: true});
}).to['throw'](/Unknown line 2 "foo"/);
parsePatch('Index: foo\n+++ bar\nblah', {strict: true});
}).to['throw'](/Unknown line 3 "blah"/);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I said positive case, I meant create a new test case that would be failing without the changes above. Basically I'd like to see a TDD artifact here so we both have a example of what this change fixes if someone looks back on this in the future. This also help protect yourself as it ensures that your use case doesn't regress in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I missed the point. I've added a test to check applyPatches() work with diffs without Index metadata, using oldFileName and newFileName fields, that's just my use case.

});
});
});