Skip to content

Commit 88320d8

Browse files
committed
Add diff syntax hl
1 parent 723a14b commit 88320d8

13 files changed

Lines changed: 276 additions & 38 deletions

File tree

MODULE.bazel

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module(
1010
bazel_dep(name = "rules_proto", version = "7.1.0")
1111
bazel_dep(name = "rules_go", version = "0.57.0")
1212
bazel_dep(name = "gazelle", version = "0.45.0")
13-
bazel_dep(name = "build_stack_rules_proto", version = "4.1.0")
13+
bazel_dep(name = "build_stack_rules_proto", version = "4.1.1")
1414

1515
local_path_override(
1616
module_name = "rules_go",
@@ -38,7 +38,7 @@ use_repo(
3838
# Configuration: Protobuf Deps
3939
# -------------------------------------------------------------------
4040

41-
proto_repository = use_extension("@build_stack_rules_proto//extensions:proto_repository.bzl", "proto_repository", dev_dependency = True)
41+
proto_repository = use_extension("@build_stack_rules_proto//extensions:proto_repository.bzl", "proto_repository")
4242
proto_repository.archive(
4343
name = "protobufapis",
4444
build_directives = [
@@ -56,7 +56,7 @@ proto_repository.archive(
5656
],
5757
build_file_generation = "clean",
5858
build_file_proto_mode = "file",
59-
cfgs = ["@//:rules_proto_config.yaml"],
59+
cfgs = ["//:rules_proto_config.yaml"],
6060
deleted_files = [
6161
"google/protobuf/*test*.proto",
6262
"google/protobuf/*unittest*.proto",

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
This is a port of
66
<https://github.com/bazelbuild/bazel/blob/master/tools/aquery_differ/aquery_differ.py>
7-
to golang.
7+
to golang with a nicer UI.
88

99
## Installation
1010

11-
Download and unzip a release artifact, or clone and `bazel build //cmd/aquerydiff`.
11+
Download and unzip a release artifact, or git clone and `bazel build //cmd/aquerydiff`.
1212

1313
## Usage
1414

cmd/aquerydiff/config.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package main
22

33
type config struct {
4-
target string
5-
beforeFile string
6-
afterFile string
7-
reportDir string
8-
port string
9-
serve bool
10-
open bool
4+
target string
5+
beforeFile string
6+
afterFile string
7+
reportDir string
8+
matchingStrategy string
9+
port string
10+
unidiff bool
11+
cmpdiff bool
12+
serve bool
13+
open bool
1114
}

cmd/aquerydiff/main.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@ func run(args []string) error {
3030
flags.StringVar(&config.target, "target", "", "the target under analysis")
3131
flags.StringVar(&config.beforeFile, "before", "", "filepath to aquery file (before)")
3232
flags.StringVar(&config.afterFile, "after", "", "filepath to aquery file (after)")
33+
flags.StringVar(&config.matchingStrategy, "match", "output_files", "method used to build mapping of before & after actions (output_files|mnemonic)")
3334
flags.StringVar(&config.reportDir, "report_dir", "", "path to directory where report files should be written")
3435
flags.StringVar(&config.port, "port", "8000", "port number to use when serving content")
36+
flags.BoolVar(&config.unidiff, "unidiff", false, "compute unidiffs (can be slow)")
37+
flags.BoolVar(&config.cmpdiff, "cmpdiff", true, "compute go-cmp diffs (usually fast)")
3538
flags.BoolVar(&config.serve, "serve", false, "start webserver")
3639
flags.BoolVar(&config.open, "open", false, "open browser to webserver URL")
3740
if err := flags.Parse(args); err != nil {
@@ -71,7 +74,21 @@ func run(args []string) error {
7174
return err
7275
}
7376

74-
beforeOnly, afterOnly, both := action.Partition(beforeGraph.OutputMap, afterGraph.OutputMap)
77+
var mapper action.ActionMapper
78+
switch config.matchingStrategy {
79+
case "output_files":
80+
mapper = action.NewOutputFilesMap
81+
case "mnemonic":
82+
mapper = action.NewMnemonicFileMap
83+
default:
84+
return fmt.Errorf("unknown matching strategy '%s'", config.matchingStrategy)
85+
}
86+
87+
beforeOnly, afterOnly, both := action.Partition(
88+
mapper(beforeGraph.Actions),
89+
mapper(afterGraph.Actions),
90+
)
91+
7592
var equal action.OutputPairs
7693
var nonEqual action.OutputPairs
7794

@@ -97,6 +114,8 @@ func run(args []string) error {
97114
AfterOnly: afterOnly,
98115
Equal: equal,
99116
NonEqual: nonEqual,
117+
Unidiff: config.unidiff,
118+
Cmpdiff: config.cmpdiff,
100119
}
101120

102121
log.Printf("Generating report in: %s", config.reportDir)

pkg/action/graph.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ type Graph struct {
2020
DepSetOfFiles depset.Map
2121
DepSetResolver depset.Resolver
2222
Actions []*dipb.Action
23-
OutputMap OutputMap
2423
}
2524

2625
func NewGraph(name string, container *anpb.ActionGraphContainer) (*Graph, error) {
@@ -50,11 +49,10 @@ func NewGraph(name string, container *anpb.ActionGraphContainer) (*Graph, error)
5049
DepSetOfFiles: depSetOfFiles,
5150
DepSetResolver: *depSetResolver,
5251
Actions: actions,
53-
OutputMap: NewOutputMap(actions),
5452
}, nil
5553
}
5654

57-
func Partition(before, after OutputMap) (beforeOnly, afterOnly, both OutputPairs) {
55+
func Partition(before, after ActionMap) (beforeOnly, afterOnly, both OutputPairs) {
5856
a := make(map[string]bool)
5957
b := make(map[string]bool)
6058
for output := range before {

pkg/action/output_map.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,28 @@ import (
44
dipb "github.com/stackb/bazel-aquery-differ/build/stack/bazel/aquery/differ"
55
)
66

7-
// OutputMap is a map of string -> action were the key is the primary
8-
// output file(s) of the action.
9-
type OutputMap map[string]*dipb.Action
7+
// ActionMap is a map of string -> action.
8+
type ActionMap map[string]*dipb.Action
9+
10+
// ActionMapper is a function that creates an ActionMap from a list of Actions.
11+
type ActionMapper func([]*dipb.Action) ActionMap
1012

11-
// NewOutputMap creates a new actionOutputMap.
12-
func NewOutputMap(actions []*dipb.Action) OutputMap {
13-
result := make(OutputMap)
13+
// NewOutputFilesMap creates a new actionOutputMap were the key is the primary
14+
// output file(s) of the action.
15+
func NewOutputFilesMap(actions []*dipb.Action) ActionMap {
16+
result := make(ActionMap)
1417
for _, action := range actions {
1518
result[action.OutputFiles] = action
1619
}
1720
return result
1821
}
22+
23+
// NewMnemonicFileMap creates a new actionOutputMap were the key is the primary
24+
// output file(s) of the action. In the strategy, the last action having the mnemonic wins.
25+
func NewMnemonicFileMap(actions []*dipb.Action) ActionMap {
26+
result := make(ActionMap)
27+
for _, action := range actions {
28+
result[action.Mnemonic] = action
29+
}
30+
return result
31+
}

pkg/report/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ go_library(
99
],
1010
embedsrcs = [
1111
"index.html.tmpl",
12+
"diff.html.tmpl",
13+
"cmp.html.tmpl",
1214
"style.css",
1315
],
1416
importpath = "github.com/stackb/bazel-aquery-differ/pkg/report",

pkg/report/assets.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,11 @@ import (
77
//go:embed index.html.tmpl
88
var indexHtmlFs embed.FS
99

10+
//go:embed diff.html.tmpl
11+
var diffHtmlFs embed.FS
12+
13+
//go:embed cmp.html.tmpl
14+
var cmpHtmlFs embed.FS
15+
1016
//go:embed style.css
1117
var styleCss []byte

pkg/report/cmp.html.tmpl

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<title>Cmp Diff - Aquerydiff</title>
7+
<link href="/style.css" rel="stylesheet">
8+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css">
9+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
10+
<style>
11+
body {
12+
margin: 0;
13+
padding: 20px;
14+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
15+
background-color: #ffffff;
16+
}
17+
.header {
18+
margin-bottom: 20px;
19+
padding-bottom: 10px;
20+
border-bottom: 1px solid #e1e4e8;
21+
}
22+
.header h1 {
23+
font-size: 24px;
24+
margin: 0 0 10px 0;
25+
}
26+
.header a {
27+
color: #0366d6;
28+
text-decoration: none;
29+
}
30+
.header a:hover {
31+
text-decoration: underline;
32+
}
33+
.diff-container {
34+
max-width: 100%;
35+
overflow-x: auto;
36+
}
37+
pre {
38+
margin: 0;
39+
padding: 4px;
40+
background-color: #f6f8fa;
41+
border: 1px solid #e1e4e8;
42+
border-radius: 6px;
43+
overflow: auto;
44+
}
45+
code {
46+
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
47+
font-size: 13px;
48+
line-height: 1.5;
49+
}
50+
/* GitHub-style diff colors */
51+
.hljs-addition {
52+
color: #22863a;
53+
background-color: #f0fff4;
54+
}
55+
.hljs-deletion {
56+
color: #b31d28;
57+
background-color: #ffeef0;
58+
}
59+
</style>
60+
</head>
61+
62+
<body>
63+
<div class="header">
64+
<h1>Diff (go-cmp)</code></h1>
65+
<a href="/">← Back to index</a>
66+
</div>
67+
<div class="diff-container">
68+
<pre><code class="language-diff">{{.Content}}</code></pre>
69+
</div>
70+
<script>
71+
hljs.highlightAll();
72+
</script>
73+
</body>
74+
75+
</html>

pkg/report/diff.html.tmpl

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<title>Unidiff - Aquerydiff</title>
7+
<link href="/style.css" rel="stylesheet">
8+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css">
9+
<script src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html-ui.min.js"></script>
10+
<style>
11+
body {
12+
margin: 0;
13+
padding: 20px;
14+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
15+
}
16+
.header {
17+
margin-bottom: 20px;
18+
padding-bottom: 10px;
19+
border-bottom: 1px solid #e1e4e8;
20+
}
21+
.header h1 {
22+
font-size: 24px;
23+
margin: 0 0 10px 0;
24+
}
25+
.header a {
26+
color: #0366d6;
27+
text-decoration: none;
28+
}
29+
.header a:hover {
30+
text-decoration: underline;
31+
}
32+
#diff-container {
33+
max-width: 100%;
34+
overflow-x: auto;
35+
}
36+
</style>
37+
</head>
38+
39+
<body>
40+
<div class="header">
41+
<h1>Diff</h1>
42+
<a href="/">← Back to index</a>
43+
</div>
44+
<div id="diff-container"></div>
45+
<script>
46+
const diffString = `{{.Content}}`;
47+
const targetElement = document.getElementById('diff-container');
48+
const configuration = {
49+
drawFileList: true,
50+
fileListToggle: false,
51+
fileListStartVisible: false,
52+
fileContentToggle: false,
53+
matching: 'lines',
54+
outputFormat: 'side-by-side',
55+
synchronisedScroll: true,
56+
highlight: true,
57+
renderNothingWhenEmpty: false,
58+
};
59+
const diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration);
60+
diff2htmlUi.draw();
61+
diff2htmlUi.highlightCode();
62+
</script>
63+
</body>
64+
65+
</html>

0 commit comments

Comments
 (0)