Skip to content

Commit

Permalink
(#10) Add a draft version of the change tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
y0ung3r committed Jan 24, 2024
1 parent 4ff6cbd commit 4340079
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.github.y0ung3r.gitglobalhookslocator.git

import java.nio.file.Path
import java.nio.file.WatchEvent

data class HookEvent(
val kind: WatchEvent.Kind<Path>,
val entry: HookEntry)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.github.y0ung3r.gitglobalhookslocator.git

import java.nio.file.*
import java.nio.file.attribute.BasicFileAttributes

class HooksFolderVisitor(private val watchService: WatchService) : SimpleFileVisitor<Path>() {
override fun preVisitDirectory(directory: Path, attributes: BasicFileAttributes): FileVisitResult {
directory.register(
watchService,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE)

return FileVisitResult.CONTINUE
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.github.y0ung3r.gitglobalhookslocator.git

import com.github.y0ung3r.gitglobalhookslocator.git.extensions.getGlobalHooksPath
import com.intellij.openapi.diagnostic.thisLogger
import io.reactivex.rxjava3.subjects.PublishSubject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.nio.file.*
import kotlin.io.path.nameWithoutExtension

class ObservableHooksFolder(git: Git) {
companion object {
@JvmStatic
val supportedHooks = arrayOf(
"pre-commit",
"prepare-commit-msg",
"commit-msg",
"post-commit",
"applypatch-msg",
"pre-applypatch",
"post-applypatch",
"pre-rebase",
"post-rewrite",
"post-checkout",
"post-merge",
"pre-push",
"pre-auto-gc"
)
}

private var count: Int = 0
val hooks: PublishSubject<HookEvent>
val path: Path

init {
path = git.getGlobalHooksPath()

val files = try {
Files.list(path)
}
catch (exception: NoSuchFileException) {
thisLogger()
.info("Provided hooks path is not valid", exception)

emptyList<Path>()
.stream()
}

hooks = PublishSubject.create()

files
.filter {
supportedHooks.any { hookName -> it.fileName.nameWithoutExtension.contains(hookName) }
}
.map { HookEvent(StandardWatchEventKinds.ENTRY_CREATE, HookEntry.load(it)) }
.forEach { hooks.onNext(it) }

val watchService = FileSystems.getDefault().newWatchService()
Files.walkFileTree(path, HooksFolderVisitor(watchService))

val changesTrackingJob = CoroutineScope(Dispatchers.IO).launch {
while (true) {
val folderEntry = watchService.take()

folderEntry.pollEvents().forEach {
val hookPath = Path.of(path.toString(), it.context().toString())
val hookEntry = HookEntry.load(hookPath)
hooks.onNext(HookEvent(it.kind() as WatchEvent.Kind<Path>, hookEntry))
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,42 @@ package com.github.y0ung3r.gitglobalhookslocator.gitTests

import com.github.y0ung3r.gitglobalhookslocator.git.Git
import com.github.y0ung3r.gitglobalhookslocator.git.HooksFolder
import com.github.y0ung3r.gitglobalhookslocator.git.ObservableHooksFolder
import com.github.y0ung3r.gitglobalhookslocator.git.cli.CliResponse
import com.github.y0ung3r.gitglobalhookslocator.gitTests.testEngine.HookTestBase
import com.github.y0ung3r.gitglobalhookslocator.gitTests.testEngine.RespondInterchangeably
import org.junit.Assert.*
import org.junit.Test
import java.nio.file.Path
import java.nio.file.StandardWatchEventKinds

class ObservableHooksFolderTests : HookTestBase() {
private companion object {
@JvmStatic
fun getGit(hooksPath: Path) = Git(
RespondInterchangeably(
CliResponse(Git.minRequiredVersion.toString()),
CliResponse(hooksPath.toString())
)
)
}

@Test
fun `Should observe changes`() {
// Arrange
val git = getGit(getEnabledHooksPath())

// Act
val sut = ObservableHooksFolder(git)

sut.hooks.subscribe {
assertEquals(it.kind, StandardWatchEventKinds.ENTRY_CREATE)
}

// Assert
createHook("kek")
}
}

class HooksFolderTests : HookTestBase() {
private companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ abstract class HookTestBase {
fun getEnabledHooksPath(): Path
= getHooksPath(ENABLED_HOOK)

@JvmStatic
fun createHook(hookName: String) {
val hookPath = getHookPath(ENABLED_HOOK, hookName).toFile()

if (hookPath.exists()) {
return
}

hookPath.createNewFile()
}

@JvmStatic
private fun clearTestHooks(hookType: String) {
val hooksPath = getHooksPath(hookType)
Expand Down

0 comments on commit 4340079

Please sign in to comment.