mirror of
https://github.com/SkinnyMind/libgit2dart.git
synced 2025-05-04 20:29:08 -04:00
refactor(patch): initialize DiffHunk with all the information accessible immediately
This commit is contained in:
parent
28f08e308a
commit
77a34c3335
4 changed files with 167 additions and 149 deletions
|
@ -4,7 +4,6 @@ import 'package:ffi/ffi.dart';
|
|||
import 'package:libgit2dart/libgit2dart.dart';
|
||||
import 'package:libgit2dart/src/bindings/diff.dart' as bindings;
|
||||
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
|
||||
import 'package:libgit2dart/src/bindings/patch.dart' as patch_bindings;
|
||||
import 'package:libgit2dart/src/util.dart';
|
||||
|
||||
class Diff {
|
||||
|
@ -602,112 +601,3 @@ final _statsFinalizer = Finalizer<Pointer<git_diff_stats>>(
|
|||
(pointer) => bindings.statsFree(pointer),
|
||||
);
|
||||
// coverage:ignore-end
|
||||
|
||||
class DiffHunk {
|
||||
/// Initializes a new instance of [DiffHunk] class from provided
|
||||
/// pointers to patch object and diff hunk object in memory and number of
|
||||
/// lines in hunk.
|
||||
const DiffHunk(
|
||||
this._patchPointer,
|
||||
this._diffHunkPointer,
|
||||
this.linesCount,
|
||||
this.index,
|
||||
);
|
||||
|
||||
/// Pointer to memory address for allocated diff hunk object.
|
||||
final Pointer<git_diff_hunk> _diffHunkPointer;
|
||||
|
||||
/// Pointer to memory address for allocated patch object.
|
||||
final Pointer<git_patch> _patchPointer;
|
||||
|
||||
/// Number of total lines in this hunk.
|
||||
final int linesCount;
|
||||
|
||||
/// Index of this hunk in the patch.
|
||||
final int index;
|
||||
|
||||
/// Starting line number in 'old file'.
|
||||
int get oldStart => _diffHunkPointer.ref.old_start;
|
||||
|
||||
/// Number of lines in 'old file'.
|
||||
int get oldLines => _diffHunkPointer.ref.old_lines;
|
||||
|
||||
/// Starting line number in 'new file'.
|
||||
int get newStart => _diffHunkPointer.ref.new_start;
|
||||
|
||||
/// Number of lines in 'new file'.
|
||||
int get newLines => _diffHunkPointer.ref.new_lines;
|
||||
|
||||
/// Header of a hunk.
|
||||
String get header {
|
||||
final list = <int>[];
|
||||
for (var i = 0; i < _diffHunkPointer.ref.header_len; i++) {
|
||||
list.add(_diffHunkPointer.ref.header[i]);
|
||||
}
|
||||
return String.fromCharCodes(list);
|
||||
}
|
||||
|
||||
/// List of lines in a hunk of a patch.
|
||||
List<DiffLine> get lines {
|
||||
final lines = <DiffLine>[];
|
||||
for (var i = 0; i < linesCount; i++) {
|
||||
lines.add(
|
||||
DiffLine(
|
||||
patch_bindings.lines(
|
||||
patchPointer: _patchPointer,
|
||||
hunkIndex: index,
|
||||
lineOfHunk: i,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DiffHunk{linesCount: $linesCount, index: $index, '
|
||||
'oldStart: $oldStart, oldLines: $oldLines, newStart: $newStart, '
|
||||
'newLines: $newLines, header: $header}';
|
||||
}
|
||||
}
|
||||
|
||||
class DiffLine {
|
||||
/// Initializes a new instance of [DiffLine] class from provided
|
||||
/// pointer to diff line object in memory.
|
||||
const DiffLine(this._diffLinePointer);
|
||||
|
||||
/// Pointer to memory address for allocated diff line object.
|
||||
final Pointer<git_diff_line> _diffLinePointer;
|
||||
|
||||
/// Type of the line.
|
||||
GitDiffLine get origin {
|
||||
return GitDiffLine.values.singleWhere(
|
||||
(e) => _diffLinePointer.ref.origin == e.value,
|
||||
);
|
||||
}
|
||||
|
||||
/// Line number in old file or -1 for added line.
|
||||
int get oldLineNumber => _diffLinePointer.ref.old_lineno;
|
||||
|
||||
/// Line number in new file or -1 for deleted line.
|
||||
int get newLineNumber => _diffLinePointer.ref.new_lineno;
|
||||
|
||||
/// Number of newline characters in content.
|
||||
int get numLines => _diffLinePointer.ref.num_lines;
|
||||
|
||||
/// Offset in the original file to the content.
|
||||
int get contentOffset => _diffLinePointer.ref.content_offset;
|
||||
|
||||
/// Content of the diff line.
|
||||
String get content => _diffLinePointer.ref.content
|
||||
.cast<Utf8>()
|
||||
.toDartString(length: _diffLinePointer.ref.content_len);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DiffLine{oldLineNumber: $oldLineNumber, '
|
||||
'newLineNumber: $newLineNumber, numLines: $numLines, '
|
||||
'contentOffset: $contentOffset, content: $content}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:ffi';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
import 'package:libgit2dart/libgit2dart.dart';
|
||||
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
|
||||
import 'package:libgit2dart/src/bindings/patch.dart' as bindings;
|
||||
|
@ -197,14 +198,49 @@ class Patch {
|
|||
final length = bindings.numHunks(_patchPointer);
|
||||
final hunks = <DiffHunk>[];
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
final hunk = bindings.hunk(patchPointer: _patchPointer, hunkIndex: i);
|
||||
for (var index = 0; index < length; index++) {
|
||||
final hunk = bindings.hunk(patchPointer: _patchPointer, hunkIndex: index);
|
||||
final hunkPointer = hunk['hunk']! as Pointer<git_diff_hunk>;
|
||||
final linesCount = hunk['linesN']! as int;
|
||||
|
||||
final lines = <DiffLine>[];
|
||||
for (var i = 0; i < linesCount; i++) {
|
||||
final linePointer = bindings.lines(
|
||||
patchPointer: _patchPointer,
|
||||
hunkIndex: index,
|
||||
lineOfHunk: i,
|
||||
);
|
||||
lines.add(
|
||||
DiffLine._(
|
||||
origin: GitDiffLine.values.singleWhere(
|
||||
(e) => linePointer.ref.origin == e.value,
|
||||
),
|
||||
oldLineNumber: linePointer.ref.old_lineno,
|
||||
newLineNumber: linePointer.ref.new_lineno,
|
||||
numLines: linePointer.ref.num_lines,
|
||||
contentOffset: linePointer.ref.content_offset,
|
||||
content: linePointer.ref.content
|
||||
.cast<Utf8>()
|
||||
.toDartString(length: linePointer.ref.content_len),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final intHeader = <int>[];
|
||||
for (var i = 0; i < hunkPointer.ref.header_len; i++) {
|
||||
intHeader.add(hunkPointer.ref.header[i]);
|
||||
}
|
||||
|
||||
hunks.add(
|
||||
DiffHunk(
|
||||
_patchPointer,
|
||||
hunk['hunk']! as Pointer<git_diff_hunk>,
|
||||
hunk['linesN']! as int,
|
||||
i,
|
||||
DiffHunk._(
|
||||
linesCount: linesCount,
|
||||
index: index,
|
||||
oldStart: hunkPointer.ref.old_start,
|
||||
oldLines: hunkPointer.ref.old_lines,
|
||||
newStart: hunkPointer.ref.new_start,
|
||||
newLines: hunkPointer.ref.new_lines,
|
||||
header: String.fromCharCodes(intHeader),
|
||||
lines: lines,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -251,3 +287,83 @@ class PatchStats {
|
|||
'deletions: $deletions}';
|
||||
}
|
||||
}
|
||||
|
||||
class DiffHunk {
|
||||
const DiffHunk._({
|
||||
required this.linesCount,
|
||||
required this.index,
|
||||
required this.oldStart,
|
||||
required this.oldLines,
|
||||
required this.newStart,
|
||||
required this.newLines,
|
||||
required this.header,
|
||||
required this.lines,
|
||||
});
|
||||
|
||||
/// Number of total lines in this hunk.
|
||||
final int linesCount;
|
||||
|
||||
/// Index of this hunk in the patch.
|
||||
final int index;
|
||||
|
||||
/// Starting line number in 'old file'.
|
||||
final int oldStart;
|
||||
|
||||
/// Number of lines in 'old file'.
|
||||
final int oldLines;
|
||||
|
||||
/// Starting line number in 'new file'.
|
||||
final int newStart;
|
||||
|
||||
/// Number of lines in 'new file'.
|
||||
final int newLines;
|
||||
|
||||
/// Header of a hunk.
|
||||
final String header;
|
||||
|
||||
/// List of lines in a hunk of a patch.
|
||||
final List<DiffLine> lines;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DiffHunk{linesCount: $linesCount, index: $index, '
|
||||
'oldStart: $oldStart, oldLines: $oldLines, newStart: $newStart, '
|
||||
'newLines: $newLines, header: $header}';
|
||||
}
|
||||
}
|
||||
|
||||
class DiffLine {
|
||||
const DiffLine._({
|
||||
required this.origin,
|
||||
required this.oldLineNumber,
|
||||
required this.newLineNumber,
|
||||
required this.numLines,
|
||||
required this.contentOffset,
|
||||
required this.content,
|
||||
});
|
||||
|
||||
/// Type of the line.
|
||||
final GitDiffLine origin;
|
||||
|
||||
/// Line number in old file or -1 for added line.
|
||||
final int oldLineNumber;
|
||||
|
||||
/// Line number in new file or -1 for deleted line.
|
||||
final int newLineNumber;
|
||||
|
||||
/// Number of newline characters in content.
|
||||
final int numLines;
|
||||
|
||||
/// Offset in the original file to the content.
|
||||
final int contentOffset;
|
||||
|
||||
/// Content of the diff line.
|
||||
final String content;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DiffLine{oldLineNumber: $oldLineNumber, '
|
||||
'newLineNumber: $newLineNumber, numLines: $numLines, '
|
||||
'contentOffset: $contentOffset, content: $content}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -559,33 +559,6 @@ index e69de29..c217c63 100644
|
|||
expect(Diff.parse(patchText).patch, patchText);
|
||||
});
|
||||
|
||||
test('returns hunks in a patch', () {
|
||||
final patch = Patch.fromDiff(diff: Diff.parse(patchText), index: 0);
|
||||
final hunk = patch.hunks[0];
|
||||
|
||||
expect(patch.hunks.length, 1);
|
||||
expect(hunk.linesCount, 1);
|
||||
expect(hunk.oldStart, 0);
|
||||
expect(hunk.oldLines, 0);
|
||||
expect(hunk.newStart, 1);
|
||||
expect(hunk.newLines, 1);
|
||||
expect(hunk.header, '@@ -0,0 +1 @@\n');
|
||||
});
|
||||
|
||||
test('returns lines in a hunk', () {
|
||||
final patch = Patch.fromDiff(diff: Diff.parse(patchText), index: 0);
|
||||
final hunk = patch.hunks[0];
|
||||
final line = hunk.lines[0];
|
||||
|
||||
expect(hunk.lines.length, 1);
|
||||
expect(line.origin, GitDiffLine.addition);
|
||||
expect(line.oldLineNumber, -1);
|
||||
expect(line.newLineNumber, 1);
|
||||
expect(line.numLines, 1);
|
||||
expect(line.contentOffset, 155);
|
||||
expect(line.content, 'Modified content\n');
|
||||
});
|
||||
|
||||
test('manually releases allocated memory', () {
|
||||
final diff = Diff.parse(patchText);
|
||||
expect(() => diff.free(), returnsNormally);
|
||||
|
@ -597,8 +570,8 @@ index e69de29..c217c63 100644
|
|||
});
|
||||
|
||||
test(
|
||||
'returns string representation of Diff, DiffDelta, DiffFile, '
|
||||
'DiffHunk, DiffLine and DiffStats objects', () {
|
||||
'returns string representation of Diff, DiffDelta, DiffFile '
|
||||
' and DiffStats objects', () {
|
||||
final diff = Diff.parse(patchText);
|
||||
final patch = Patch.fromDiff(diff: diff, index: 0);
|
||||
final stats = diff.stats;
|
||||
|
@ -606,8 +579,6 @@ index e69de29..c217c63 100644
|
|||
expect(diff.toString(), contains('Diff{'));
|
||||
expect(patch.delta.toString(), contains('DiffDelta{'));
|
||||
expect(patch.delta.oldFile.toString(), contains('DiffFile{'));
|
||||
expect(patch.hunks[0].toString(), contains('DiffHunk{'));
|
||||
expect(patch.hunks[0].lines[0].toString(), contains('DiffLine{'));
|
||||
expect(stats.toString(), contains('DiffStats{'));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -155,6 +155,43 @@ index e69de29..0000000
|
|||
expect(() => Patch(nullptr).text, throwsA(isA<LibGit2Error>()));
|
||||
});
|
||||
|
||||
test('returns hunks in a patch', () {
|
||||
final patch = Patch.fromBuffers(
|
||||
oldBuffer: oldBuffer,
|
||||
newBuffer: newBuffer,
|
||||
oldBufferPath: path,
|
||||
newBufferPath: path,
|
||||
);
|
||||
final hunk = patch.hunks[0];
|
||||
|
||||
expect(patch.hunks.length, 1);
|
||||
expect(hunk.linesCount, 1);
|
||||
expect(hunk.oldStart, 0);
|
||||
expect(hunk.oldLines, 0);
|
||||
expect(hunk.newStart, 1);
|
||||
expect(hunk.newLines, 1);
|
||||
expect(hunk.header, '@@ -0,0 +1 @@\n');
|
||||
});
|
||||
|
||||
test('returns lines in a hunk', () {
|
||||
final patch = Patch.fromBuffers(
|
||||
oldBuffer: oldBuffer,
|
||||
newBuffer: newBuffer,
|
||||
oldBufferPath: path,
|
||||
newBufferPath: path,
|
||||
);
|
||||
final hunk = patch.hunks[0];
|
||||
final line = hunk.lines[0];
|
||||
|
||||
expect(hunk.lines.length, 1);
|
||||
expect(line.origin, GitDiffLine.addition);
|
||||
expect(line.oldLineNumber, -1);
|
||||
expect(line.newLineNumber, 1);
|
||||
expect(line.numLines, 1);
|
||||
expect(line.contentOffset, 0);
|
||||
expect(line.content, 'Feature edit\n');
|
||||
});
|
||||
|
||||
test('returns line counts of each type in a patch', () {
|
||||
final patch = Patch.fromBuffers(
|
||||
oldBuffer: oldBuffer,
|
||||
|
@ -180,7 +217,9 @@ index e69de29..0000000
|
|||
expect(() => patch.free(), returnsNormally);
|
||||
});
|
||||
|
||||
test('returns string representation of Patch object', () {
|
||||
test(
|
||||
'returns string representation of Patch, DiffHunk and DiffLine objects',
|
||||
() {
|
||||
final patch = Patch.fromBuffers(
|
||||
oldBuffer: oldBuffer,
|
||||
newBuffer: newBuffer,
|
||||
|
@ -189,6 +228,8 @@ index e69de29..0000000
|
|||
);
|
||||
|
||||
expect(patch.toString(), contains('Patch{'));
|
||||
expect(patch.hunks[0].toString(), contains('DiffHunk{'));
|
||||
expect(patch.hunks[0].lines[0].toString(), contains('DiffLine{'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue