Skip to content

Commit 4ba6b15

Browse files
Fix for issue 276 (#292)
* Fix for issue 276 Fixes Empty input file and missing input file produce the same target hash #276 Signed-off-by: Maxwell Elliott <maxwell.elliott@gotinder.com> * more updates Signed-off-by: Maxwell Elliott <maxwell.elliott@gotinder.com> --------- Signed-off-by: Maxwell Elliott <maxwell.elliott@gotinder.com>
1 parent 4dbce4c commit 4ba6b15

File tree

5 files changed

+48
-3
lines changed

5 files changed

+48
-3
lines changed

MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module(
22
name = "bazel-diff",
3-
version = "11.0.3",
3+
version = "12.0.0",
44
compatibility_level = 0,
55
)
66

MODULE.bazel.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ First, add the following snippet to your project:
272272
#### Bzlmod snippet
273273

274274
```bazel
275-
bazel_dep(name = "bazel-diff", version = "11.0.3")
275+
bazel_dep(name = "bazel-diff", version = "12.0.0")
276276
```
277277

278278
You can now run the tool with:

cli/src/main/kotlin/com/bazel_diff/hash/SourceFileHasher.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ class SourceFileHasherImpl : KoinComponent, SourceFileHasher {
8888
if (relativeFilenameToContentHash?.contains(filenamePathString) == true) {
8989
val contentHash = relativeFilenameToContentHash.getValue(filenamePathString)
9090
safePutBytes(contentHash.toByteArray())
91+
// Mark that file exists (via content hash)
92+
putBytes(byteArrayOf(0x01))
9193
} else {
9294
val absoluteFilePath = workingDirectory.resolve(filenamePath)
9395
val file = absoluteFilePath.toFile()
@@ -98,9 +100,13 @@ class SourceFileHasherImpl : KoinComponent, SourceFileHasher {
98100
} else if (modifiedFilepaths.any { workingDirectory.resolve(it) == absoluteFilePath }) {
99101
putFile(file)
100102
}
103+
// Mark that file exists
104+
putBytes(byteArrayOf(0x01))
101105
}
102106
} else {
103107
logger.w { "File $absoluteFilePath not found" }
108+
// Mark that file is missing
109+
putBytes(byteArrayOf(0x00))
104110
}
105111
}
106112
safePutBytes(sourceFileTarget.seed)

cli/src/test/kotlin/com/bazel_diff/hash/SourceFileHasherTest.kt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.bazel_diff.hash
22

33
import assertk.assertThat
44
import assertk.assertions.isEqualTo
5+
import assertk.assertions.isNotEqualTo
56
import assertk.assertions.isNull
67
import com.bazel_diff.bazel.BazelSourceFileTarget
78
import com.bazel_diff.extensions.toHexString
@@ -38,6 +39,7 @@ internal class SourceFileHasherTest : KoinTest {
3839
val expected =
3940
sha256 {
4041
safePutBytes(fixtureFileContent)
42+
putBytes(byteArrayOf(0x01))
4143
safePutBytes(seed)
4244
safePutBytes(fixtureFileTarget.toByteArray())
4345
}
@@ -53,6 +55,7 @@ internal class SourceFileHasherTest : KoinTest {
5355
val expected =
5456
sha256 {
5557
safePutBytes(fixtureFileContent)
58+
putBytes(byteArrayOf(0x01))
5659
safePutBytes(seed)
5760
safePutBytes(fixtureFileTarget.toByteArray())
5861
}
@@ -68,6 +71,7 @@ internal class SourceFileHasherTest : KoinTest {
6871
hasher.digest(bazelSourceFileTarget, setOf(Paths.get("some/other/path"))).toHexString()
6972
val expected =
7073
sha256 {
74+
putBytes(byteArrayOf(0x01))
7175
safePutBytes(seed)
7276
safePutBytes(fixtureFileTarget.toByteArray())
7377
}
@@ -89,6 +93,7 @@ internal class SourceFileHasherTest : KoinTest {
8993
val expected =
9094
sha256 {
9195
safePutBytes(externalRepoFileContent.toByteArray())
96+
putBytes(byteArrayOf(0x01))
9297
safePutBytes(seed)
9398
safePutBytes(externalRepoFileTarget.toByteArray())
9499
}
@@ -104,6 +109,7 @@ internal class SourceFileHasherTest : KoinTest {
104109
val expected =
105110
sha256 {
106111
safePutBytes(fixtureFileContent)
112+
putBytes(byteArrayOf(0x01))
107113
safePutBytes(seed)
108114
safePutBytes(fixtureFileTarget.toByteArray())
109115
}
@@ -136,6 +142,7 @@ internal class SourceFileHasherTest : KoinTest {
136142
val actual = hasher.digest(bazelSourceFileTarget).toHexString()
137143
val expected =
138144
sha256 {
145+
putBytes(byteArrayOf(0x00))
139146
safePutBytes(seed)
140147
safePutBytes(target.toByteArray())
141148
}
@@ -163,6 +170,7 @@ internal class SourceFileHasherTest : KoinTest {
163170
val expected =
164171
sha256 {
165172
safePutBytes("foo-content-hash".toByteArray())
173+
putBytes(byteArrayOf(0x01))
166174
safePutBytes(seed)
167175
safePutBytes(fixtureFileTarget.toByteArray())
168176
}
@@ -180,6 +188,7 @@ internal class SourceFileHasherTest : KoinTest {
180188
val expected =
181189
sha256 {
182190
safePutBytes(fixtureFileContent)
191+
putBytes(byteArrayOf(0x01))
183192
safePutBytes(seed)
184193
safePutBytes(fixtureFileTarget.toByteArray())
185194
}
@@ -198,10 +207,40 @@ internal class SourceFileHasherTest : KoinTest {
198207
val expected =
199208
sha256 {
200209
safePutBytes("foo-content-hash".toByteArray())
210+
putBytes(byteArrayOf(0x01))
201211
safePutBytes(seed)
202212
safePutBytes(targetName.toByteArray())
203213
}
204214
.toHexString()
205215
assertThat(actual).isEqualTo(expected)
206216
}
217+
218+
@Test
219+
fun testHashEmptyFileVsDeletedFile() = runBlocking<Unit> {
220+
// Create a temp directory for testing
221+
val testDir = Files.createTempDirectory("empty_file_test")
222+
val emptyFilePath = testDir.resolve("path/to/empty.txt")
223+
Files.createDirectories(emptyFilePath.parent)
224+
Files.createFile(emptyFilePath)
225+
226+
val emptyFileTarget = "//path/to:empty.txt"
227+
val hasher = SourceFileHasherImpl(testDir, null, externalRepoResolver)
228+
229+
// Hash the empty file (file exists)
230+
val emptyFileHash = hasher.digest(BazelSourceFileTarget(emptyFileTarget, seed)).toHexString()
231+
232+
// Delete the file
233+
Files.delete(emptyFilePath)
234+
235+
// Hash the non-existent file
236+
val deletedFileHash = hasher.digest(BazelSourceFileTarget(emptyFileTarget, seed)).toHexString()
237+
238+
// The hashes should be different (file exists vs file missing)
239+
assertThat(emptyFileHash).isNotEqualTo(deletedFileHash)
240+
241+
// Clean up
242+
Files.deleteIfExists(emptyFilePath.parent)
243+
Files.deleteIfExists(testDir.resolve("path"))
244+
Files.deleteIfExists(testDir)
245+
}
207246
}

0 commit comments

Comments
 (0)