Skip to content

Commit

Permalink
Merge pull request #34 from danger/feat/git-diff
Browse files Browse the repository at this point in the history
feat: git diff
  • Loading branch information
HelloCore authored Oct 3, 2023
2 parents 81e9a0b + 8df4084 commit 9ac70fa
Show file tree
Hide file tree
Showing 16 changed files with 1,126 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr_flow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: macos-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- uses: actions/setup-node@v1

Expand Down
8 changes: 7 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"name": "Dart: Attach to Process",
"type": "dart",
"request": "attach"
},
{
"name": "Danger Attach",
"type": "dart",
"request": "attach",
"program": "tool/dangerfile.dart"
}
]
}
}
8 changes: 7 additions & 1 deletion dangerfile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import 'package:path/path.dart' show join, current;
import 'package:danger_core/danger_core.dart';
import 'package:danger_plugin_dart_test/danger_plugin_dart_test.dart';

void main() {
void main() async {
await DangerUtils.gitFetchBranch();
final fullDiff = await DangerUtils.getFullDiff(
targetBranch: 'origin/${DangerUtils.getTargetBranch()}');

message('There are ${fullDiff.length} changed files');

if (danger.isGitHub) {
if (danger.github.pr.title.contains('WIP') == true) {
warn('PR is considered WIP');
Expand Down
1 change: 1 addition & 0 deletions packages/danger_core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## 2.0.0

- Provides API to get GitDiff (DangerUtils.getFullDiff)
- Migrate to Dart 3

## 1.0.1
Expand Down
1 change: 1 addition & 0 deletions packages/danger_core/lib/danger_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
library danger_core;

export 'src/danger_executor.dart';
export 'src/danger_utils.dart';
export 'src/models/danger_dsl.dart';
export 'src/models/bitbucket_cloud.dart';
export 'src/models/git_dsl.dart';
Expand Down
56 changes: 53 additions & 3 deletions packages/danger_core/lib/src/danger_utils.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,60 @@
import 'dart:io';

import 'package:danger_core/danger_core.dart';
import 'package:danger_core/src/models/git_diff.dart';
import 'package:danger_core/src/utils/git_diff_parser.dart';

class DangerUtils {
Future<String> spawn(String command,
{List<String> arguments = const []}) async {
final result = await Process.run(command, arguments);
DangerUtils._();

static Future<String> spawn(String command,
{List<String> arguments = const []}) async {
final result = await Process.run(command, arguments, runInShell: true);
return result.stdout.toString().trim();
}

static Future<void> gitFetchBranch({String? targetBranch}) async {
var base = targetBranch ?? '';
if (base.isEmpty) {
base = getTargetBranch();
}

await DangerUtils.spawn('git', arguments: ['fetch', 'origin', base]);
}

/// Get PR target branch based on git provider
static String getTargetBranch() {
var target = '';

if (danger.isGitHub) {
target = danger.github.pr.base.ref;
} else if (danger.isBitbucketCloud) {
target = danger.bitbucketCloud.pr.destination.branch.name;
} else if (danger.isGitLab) {
target = danger.gitLab.mergeRequest.targetBranch;
} else {
target = danger.settings.cliArgs?['base'] ?? '';
}

if (target.isEmpty) {
throw 'Cannot find base branch';
}

return target;
}

/// Get Git full diff.
/// The default targetBranch will be selected based on current environment.
///
/// This function needs Git history on the machine.
static Future<List<GitDiff>> getFullDiff(
{String sourceBranch = "HEAD", String? targetBranch}) async {
var base = targetBranch ?? '';
if (base.isEmpty) {
base = getTargetBranch();
}

final data = await DangerUtils.spawn('git', arguments: ['diff', base]);
return GitDiffParser.parse(data);
}
}
28 changes: 28 additions & 0 deletions packages/danger_core/lib/src/models/git_diff.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class GitDiff {
final String fromFile;
final String toFile;
final List<DiffBlock> diffBlocks;

GitDiff(
{required this.fromFile, required this.toFile, required this.diffBlocks});
}

class DiffBlock {
final int fromStart;
final int fromEnd;
final int toStart;
final int toEnd;

final List<String> addedLines;
final List<String> removedLines;
final List<String> unchangedLines;

DiffBlock(
{required this.fromStart,
required this.fromEnd,
required this.toStart,
required this.toEnd,
required this.addedLines,
required this.removedLines,
required this.unchangedLines});
}
58 changes: 58 additions & 0 deletions packages/danger_core/lib/src/utils/git_diff_parser.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import 'package:danger_core/src/models/git_diff.dart';

class GitDiffParser {
GitDiffParser._();

static List<GitDiff> parse(String diffData) {
List<GitDiff> diffs = [];
List<String> lines = diffData.split('\n');
GitDiff? currentDiff;
DiffBlock? currentBlock;

for (var line in lines) {
if (line.startsWith('diff --git')) {
final fromFile = line.split(' ')[2].substring(2);
final toFile = line.split(' ')[3].substring(2);
currentDiff =
GitDiff(fromFile: fromFile, toFile: toFile, diffBlocks: []);
diffs.add(currentDiff);
continue;
}

if (line.startsWith('@@')) {
String header = line.substring(3);
List<String> parts = header.split(' ');
List<String> fromRange = parts[0].split(',');
List<String> toRange = parts[1].split(',');

final fromStart = int.parse(fromRange[0].substring(1));
final fromEnd = fromStart +
(fromRange.length > 1 ? int.parse(fromRange[1]) : 1) -
1;
final toStart = int.parse(toRange[0].substring(1));
final toEnd =
toStart + (toRange.length > 1 ? int.parse(toRange[1]) : 1) - 1;

currentBlock = DiffBlock(
fromStart: fromStart,
fromEnd: fromEnd,
toStart: toStart,
toEnd: toEnd,
addedLines: [],
removedLines: [],
unchangedLines: []);
currentDiff?.diffBlocks.add(currentBlock);
}

if (line.startsWith('+')) {
currentBlock?.addedLines.add(line.substring(1));
} else if (line.startsWith('-')) {
currentBlock?.removedLines.add(line.substring(1));
} else if (line.startsWith(' ')) {
currentBlock?.unchangedLines.add(line.substring(1));
}
}

return diffs;
}
}
27 changes: 27 additions & 0 deletions packages/danger_core/test/fixtures/diff/add_only.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
diff --git a/.github/workflows/verify_compatibility.yaml b/.github/workflows/verify_compatibility.yaml
index 507cacb..701dd94 100644
--- a/.github/workflows/verify_compatibility.yaml
+++ b/.github/workflows/verify_compatibility.yaml
@@ -38,6 +38,22 @@ jobs:
run: dart pub get
working-directory: packages/danger_dart/

+ - name: Install app (non nullsafety) dependencies
+ run: dart pub get
+ working-directory: example/pre_nullsafety/
+
+ - name: Run danger local (non nullsafety)
+ run: danger_dart local
+ working-directory: example/pre_nullsafety/
+
+ - name: Install app dependencies (nullsafety)
+ run: dart pub get
+ working-directory: example/target_nullsafety/
+
+ - name: Run danger local (nullsafety)
+ run: danger_dart local
+ working-directory: example/target_nullsafety/
+
- name: Install plugin dependencies
run: dart pub get
working-directory: example/with_plugin/danger_plugin_example/
27 changes: 27 additions & 0 deletions packages/danger_core/test/fixtures/diff/mix.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
diff --git a/example/dart3/pubspec.yaml b/example/pre_nullsafety/pubspec.yaml
similarity index 64%
rename from example/dart3/pubspec.yaml
rename to example/pre_nullsafety/pubspec.yaml
index 8aca558..9c93b1b 100644
--- a/example/dart3/pubspec.yaml
+++ b/example/pre_nullsafety/pubspec.yaml
@@ -1,13 +1,16 @@
-name: danger_test_target_null_safety
+name: danger_test_pre_nullsafety
description: A simple command-line application.
# version: 1.0.0
# homepage: https://www.example.com

environment:
- sdk: ">=3.0.0 <4.0.0"
+ sdk: ">=2.7.0 <3.0.0"
+
+dependencies:
+ json_annotation: ^3.0.0

dev_dependencies:
lints: ^1.0.1
- path: ^1.8.3
+ path: ^1.8.0
danger_core:
path: ../../packages/danger_core
26 changes: 26 additions & 0 deletions packages/danger_core/test/fixtures/diff/multiple_chunk.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
diff --git a/packages/danger_plugin_golden_reporter/pubspec.yaml b/packages/danger_plugin_golden_reporter/pubspec.yaml
index eca2e35..a0d38bd 100644
--- a/packages/danger_plugin_golden_reporter/pubspec.yaml
+++ b/packages/danger_plugin_golden_reporter/pubspec.yaml
@@ -1,10 +1,10 @@
name: danger_plugin_golden_reporter
description: A Danger Dart plugin to display golden images on pull requests.
-version: 2.0.0
+version: 1.0.0
homepage: https://github.com/danger/dart

environment:
- sdk: ">=3.0.0 <4.0.0"
+ sdk: ">=2.12.0 <3.0.0"

dependencies:
# danger_core: ">= 1.0.0 < 2.0.0"
@@ -12,7 +12,7 @@ dependencies:
path: ../danger_core

dev_dependencies:
- lints: ^2.1.1
+ lints: ^1.0.1
test: ^1.20.2
mockito: ^5.1.0
build_runner: ^2.1.8
Loading

0 comments on commit 9ac70fa

Please sign in to comment.