Linting
This commit is contained in:
		
							
								
								
									
										1
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							| @@ -5,6 +5,7 @@ | ||||
|     <option name="linkedExternalProjectsSettings"> | ||||
|       <GradleProjectSettings> | ||||
|         <option name="externalProjectPath" value="$PROJECT_DIR$" /> | ||||
|         <option name="gradleJvm" value="corretto-19" /> | ||||
|         <option name="modules"> | ||||
|           <set> | ||||
|             <option value="$PROJECT_DIR$" /> | ||||
|   | ||||
| @@ -7,17 +7,19 @@ abstract class Object( | ||||
|     val type: String, | ||||
| ) { | ||||
|     abstract val data: String | ||||
|     fun hash(): String = MessageDigest | ||||
|         .getInstance("SHA-1") | ||||
|         .digest("$type ${data.length}\u0000$data".toByteArray()) | ||||
|         .toHex() | ||||
|  | ||||
|     fun hash(): String = | ||||
|         MessageDigest | ||||
|             .getInstance("SHA-1") | ||||
|             .digest("$type ${data.length}\u0000$data".toByteArray()) | ||||
|             .toHex() | ||||
| } | ||||
|  | ||||
| class Commit( | ||||
|     val tree: Tree, | ||||
|     val author: Author, | ||||
|     val message: String, | ||||
|     val timestamp: Instant | ||||
|     val timestamp: Instant, | ||||
| ) : Object("commit") { | ||||
|     // Use \n\n for end of header in-case additional metadata is implemented in the future. | ||||
|     override val data: String | ||||
| @@ -26,8 +28,7 @@ class Commit( | ||||
|  | ||||
| data class Author( | ||||
|     val name: String, | ||||
|     val email: String | ||||
|     val email: String, | ||||
| ) { | ||||
|     override fun toString(): String = | ||||
|         "$name <$email>" | ||||
|     override fun toString(): String = "$name <$email>" | ||||
| } | ||||
| @@ -2,5 +2,4 @@ package tinyvm | ||||
|  | ||||
| import java.util.HexFormat | ||||
|  | ||||
| fun ByteArray.toHex(): String = | ||||
|      HexFormat.of().formatHex(this) | ||||
| fun ByteArray.toHex(): String = HexFormat.of().formatHex(this) | ||||
| @@ -2,9 +2,11 @@ package tinyvm | ||||
|  | ||||
| class HashCollisionException(hash: String) : Exception("Different object types with identical hash '$hash'") | ||||
|  | ||||
| class CommitTimeComparator: Comparator<Commit> { | ||||
|     override fun compare(o1: Commit, o2: Commit): Int = | ||||
|         (o1.timestamp.epochSecond - o2.timestamp.epochSecond).toInt() | ||||
| class CommitTimeComparator : Comparator<Commit> { | ||||
|     override fun compare( | ||||
|         o1: Commit, | ||||
|         o2: Commit, | ||||
|     ): Int = (o1.timestamp.epochSecond - o2.timestamp.epochSecond).toInt() | ||||
| } | ||||
|  | ||||
| class Repository { | ||||
| @@ -23,12 +25,13 @@ class Repository { | ||||
|         val hash = commit.hash() | ||||
|         val obj = findObject<Commit>(hash) | ||||
|         if (obj != null) return obj | ||||
|         val newCommit = Commit( | ||||
|             tree = addTree(commit.tree), | ||||
|             author = commit.author, | ||||
|             message = commit.message, | ||||
|             timestamp = commit.timestamp | ||||
|         ) | ||||
|         val newCommit = | ||||
|             Commit( | ||||
|                 tree = addTree(commit.tree), | ||||
|                 author = commit.author, | ||||
|                 message = commit.message, | ||||
|                 timestamp = commit.timestamp, | ||||
|             ) | ||||
|         objects[hash] = newCommit | ||||
|         commits.add(newCommit) | ||||
|         return newCommit | ||||
| @@ -47,8 +50,7 @@ class Repository { | ||||
|     /** | ||||
|      * Find commit. | ||||
|      */ | ||||
|     fun findCommit(predicate: (Commit) -> Boolean): Commit? = | ||||
|         commits.find(predicate) | ||||
|     fun findCommit(predicate: (Commit) -> Boolean): Commit? = commits.find(predicate) | ||||
|  | ||||
|     /** | ||||
|      * Dump repository objects | ||||
| @@ -63,14 +65,15 @@ class Repository { | ||||
|         val hash = tree.hash() | ||||
|         val obj = findObject<Tree>(hash) | ||||
|         if (obj != null) return obj | ||||
|         val newTree = Tree( | ||||
|             tree.nodes.map { (name, node) -> | ||||
|                 when (node) { | ||||
|                     is Tree -> name to addTree(node) | ||||
|                     is Blob -> name to addObject(node) | ||||
|                 } | ||||
|             }.toMap() | ||||
|         ) | ||||
|         val newTree = | ||||
|             Tree( | ||||
|                 tree.nodes.map { (name, node) -> | ||||
|                     when (node) { | ||||
|                         is Tree -> name to addTree(node) | ||||
|                         is Blob -> name to addObject(node) | ||||
|                     } | ||||
|                 }.toMap(), | ||||
|             ) | ||||
|         objects[hash] = newTree | ||||
|         return tree | ||||
|     } | ||||
| @@ -86,5 +89,4 @@ class Repository { | ||||
|      */ | ||||
|     private inline fun <reified T : Object> findObject(hash: String): T? = | ||||
|         objects[hash]?.let { it as? T ?: throw HashCollisionException(hash) } | ||||
|  | ||||
| } | ||||
| @@ -1,13 +1,14 @@ | ||||
| package tinyvm | ||||
|  | ||||
| sealed class Node(type: String): Object(type) | ||||
| sealed class Node(type: String) : Object(type) | ||||
|  | ||||
| class Tree(val nodes: Map<String, Node>) : Node("tree") { | ||||
|     // For simplicity just use the hex-formatted hash, not the actual value like git does. | ||||
|     override val data: String | ||||
|         get() = nodes.map { (name, node) -> | ||||
|             "${node.type} $name\u0000${node.hash()}" | ||||
|         }.sorted().joinToString() | ||||
|         get() = | ||||
|             nodes.map { (name, node) -> | ||||
|                 "${node.type} $name\u0000${node.hash()}" | ||||
|             }.sorted().joinToString() | ||||
| } | ||||
|  | ||||
| class Blob(override val data: String) : Node("blob") | ||||
| @@ -6,51 +6,60 @@ import kotlin.test.assertEquals | ||||
|  | ||||
| internal class RepositoryTest { | ||||
|     private val repository = Repository() | ||||
|     private val commits = listOf( | ||||
|         Commit( | ||||
|             tree = Tree(mapOf("test1.txt" to Blob("Hello World!"))), | ||||
|             author = Author("Gleb Koval", "gleb@koval.net"), | ||||
|             message = "Add test1.txt", | ||||
|             timestamp = Instant.ofEpochSecond(0) | ||||
|         ), Commit( | ||||
|             tree = Tree( | ||||
|                 mapOf( | ||||
|                     "dir1" to Tree( | ||||
|                         mapOf( | ||||
|                             "test1.txt" to Blob("Hello World!") | ||||
|                         ) | ||||
|                     ), | ||||
|                     "dir2" to Tree( | ||||
|                         mapOf( | ||||
|                             "test2.txt" to Blob("This is a second file") | ||||
|                         ) | ||||
|                     ) | ||||
|                 ) | ||||
|     private val commits = | ||||
|         listOf( | ||||
|             Commit( | ||||
|                 tree = Tree(mapOf("test1.txt" to Blob("Hello World!"))), | ||||
|                 author = Author("Gleb Koval", "gleb@koval.net"), | ||||
|                 message = "Add test1.txt", | ||||
|                 timestamp = Instant.ofEpochSecond(0), | ||||
|             ), | ||||
|             author = Author("Gleb Koval", "gleb@koval.net"), | ||||
|             message = "Move test1.txt and add dir2/test2.txt", | ||||
|             timestamp = Instant.ofEpochSecond(50) | ||||
|         ), Commit( | ||||
|             tree = Tree( | ||||
|                 mapOf( | ||||
|                     "dir1" to Tree( | ||||
|             Commit( | ||||
|                 tree = | ||||
|                     Tree( | ||||
|                         mapOf( | ||||
|                             "test1.txt" to Blob("Hello World!") | ||||
|                         ) | ||||
|                             "dir1" to | ||||
|                                 Tree( | ||||
|                                     mapOf( | ||||
|                                         "test1.txt" to Blob("Hello World!"), | ||||
|                                     ), | ||||
|                                 ), | ||||
|                             "dir2" to | ||||
|                                 Tree( | ||||
|                                     mapOf( | ||||
|                                         "test2.txt" to Blob("This is a second file"), | ||||
|                                     ), | ||||
|                                 ), | ||||
|                         ), | ||||
|                     ), | ||||
|                     "dir2" to Tree( | ||||
|                         mapOf( | ||||
|                             "test2.txt" to Blob("This is a second file") | ||||
|                         ) | ||||
|                     ), | ||||
|                     "README.md" to Blob("# This is a test repo!") | ||||
|                 ) | ||||
|                 author = Author("Gleb Koval", "gleb@koval.net"), | ||||
|                 message = "Move test1.txt and add dir2/test2.txt", | ||||
|                 timestamp = Instant.ofEpochSecond(50), | ||||
|             ), | ||||
|             Commit( | ||||
|                 tree = | ||||
|                     Tree( | ||||
|                         mapOf( | ||||
|                             "dir1" to | ||||
|                                 Tree( | ||||
|                                     mapOf( | ||||
|                                         "test1.txt" to Blob("Hello World!"), | ||||
|                                     ), | ||||
|                                 ), | ||||
|                             "dir2" to | ||||
|                                 Tree( | ||||
|                                     mapOf( | ||||
|                                         "test2.txt" to Blob("This is a second file"), | ||||
|                                     ), | ||||
|                                 ), | ||||
|                             "README.md" to Blob("# This is a test repo!"), | ||||
|                         ), | ||||
|                     ), | ||||
|                 author = Author("Gleb Koval", "gleb@koval.net"), | ||||
|                 message = "Add README.md", | ||||
|                 timestamp = Instant.ofEpochSecond(100), | ||||
|             ), | ||||
|             author = Author("Gleb Koval", "gleb@koval.net"), | ||||
|             message = "Add README.md", | ||||
|             timestamp = Instant.ofEpochSecond(100) | ||||
|         ) | ||||
|     ) | ||||
|  | ||||
|     @Test | ||||
|     fun `can commit`() { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user