-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b5252b7
Showing
17 changed files
with
588 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.gradle | ||
.idea | ||
build/ | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
![badge][badge-mac] | ||
|
||
# Kommand | ||
|
||
Quick command execution tool. | ||
|
||
## Configuration | ||
|
||
Kommand is configured via `$HOME/.kommand.js`. The configuration file has the following structure: | ||
|
||
``` | ||
{ | ||
"home": PROJECTS_ROOT_DIRECTORY, | ||
"projects": { | ||
PROJECT_DIRECTORY: { | ||
COMMAND_NAME: { | ||
"dependsOn": [ | ||
{ | ||
"project": PROJECT_NAME, | ||
"command": COMMAND_NAME | ||
}, | ||
... | ||
], | ||
"command": SHELL_COMMAND | ||
}, | ||
... | ||
}, | ||
... | ||
} | ||
} | ||
``` | ||
|
||
When `kommand` is run, the current directory name is considered the **project** being operated on. | ||
Execution working directory will be the current directory name relative to the configured `home`. | ||
|
||
### Example | ||
|
||
```json | ||
{ | ||
"home": "/Users/travis/Projects", | ||
"projects": { | ||
"kable": { | ||
"install": { | ||
"command": "./gradlew publishToMavenLocal" | ||
} | ||
}, | ||
"sensortag": { | ||
"run": { | ||
"dependsOn": [ | ||
{ | ||
"project": "kable", | ||
"command": "install" | ||
} | ||
], | ||
"command": "./gradlew runDebugExecutableMacosX64" | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
With the current directory as `/Users/travis/Projects/sensortag`, running `kommand run` will result in: | ||
|
||
``` | ||
🏃 kable ▶ ./gradlew publishToMavenLocal | ||
🏃 sensortag ▶ ./gradlew runDebugExecutableMacosX64 | ||
``` | ||
|
||
|
||
[badge-android]: http://img.shields.io/badge/platform-android-6EDB8D.svg?style=flat | ||
[badge-ios]: http://img.shields.io/badge/platform-ios-CDCDCD.svg?style=flat | ||
[badge-js]: http://img.shields.io/badge/platform-js-F8DB5D.svg?style=flat | ||
[badge-jvm]: http://img.shields.io/badge/platform-jvm-DB413D.svg?style=flat | ||
[badge-linux]: http://img.shields.io/badge/platform-linux-2D3F6C.svg?style=flat | ||
[badge-windows]: http://img.shields.io/badge/platform-windows-4D76CD.svg?style=flat | ||
[badge-mac]: http://img.shields.io/badge/platform-macos-111111.svg?style=flat | ||
[badge-watchos]: http://img.shields.io/badge/platform-watchos-C0C0C0.svg?style=flat | ||
[badge-tvos]: http://img.shields.io/badge/platform-tvos-808080.svg?style=flat | ||
[badge-wasm]: https://img.shields.io/badge/platform-wasm-624FE8.svg?style=flat |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
buildscript { | ||
repositories { | ||
jcenter() | ||
} | ||
} | ||
|
||
plugins { | ||
kotlin("multiplatform") version "1.4.20" apply false | ||
kotlin("plugin.serialization") version "1.4.20" apply false | ||
} | ||
|
||
subprojects { | ||
repositories { | ||
jcenter() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
plugins { | ||
kotlin("multiplatform") | ||
kotlin("plugin.serialization") | ||
} | ||
|
||
kotlin { | ||
macosX64 { | ||
binaries { | ||
executable { | ||
baseName = "kommand" | ||
entryPoint = "com.juul.kommand.main" | ||
} | ||
} | ||
} | ||
|
||
sourceSets { | ||
val commonMain by getting { | ||
dependencies { | ||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1") | ||
implementation("com.github.ajalt.clikt:clikt:3.0.1") | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.juul.kommand | ||
|
||
import kotlinx.serialization.KSerializer | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
import kotlinx.serialization.decodeFromString | ||
import kotlinx.serialization.descriptors.SerialDescriptor | ||
import kotlinx.serialization.encoding.Decoder | ||
import kotlinx.serialization.encoding.Encoder | ||
import kotlinx.serialization.json.Json | ||
|
||
expect fun read(path: String): String? | ||
|
||
val config: Config by lazy { | ||
val configPath = "$homePath/.kommand.json" | ||
val text = read(configPath) ?: error("Config '$configPath' not found") | ||
Json.Default.decodeFromString(text) | ||
} | ||
|
||
private typealias Name = String | ||
|
||
@Serializable(with = ConfigSerializer::class) | ||
data class Config( | ||
@SerialName("home") val homeDirectory: String, | ||
val projects: Map<Name, Project>, | ||
) | ||
|
||
data class Project( | ||
val name: String, | ||
val commands: Map<Name, Command>, | ||
) | ||
|
||
@Serializable | ||
data class Command( | ||
@SerialName("dependsOn") val dependencies: List<Dependency>? = null, | ||
val command: String | ||
) | ||
|
||
@Serializable | ||
data class Dependency( | ||
val project: String, | ||
val command: String, | ||
) | ||
|
||
object ConfigSerializer : KSerializer<Config> { | ||
|
||
override val descriptor: SerialDescriptor = ConfigSurrogate.serializer().descriptor | ||
|
||
override fun serialize(encoder: Encoder, value: Config) = throw UnsupportedOperationException() | ||
|
||
override fun deserialize(decoder: Decoder): Config { | ||
val surrogate = decoder.decodeSerializableValue(ConfigSurrogate.serializer()) | ||
return Config( | ||
homeDirectory = surrogate.homeDirectory, | ||
projects = surrogate.projects.map { (name, commands) -> | ||
name to Project(name, commands) | ||
}.toMap() | ||
) | ||
} | ||
} | ||
|
||
@Serializable | ||
private data class ConfigSurrogate( | ||
@SerialName("home") val homeDirectory: String, | ||
val projects: Map<Name, Map<Name, Command>>, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package com.juul.kommand | ||
|
||
expect fun execute(path: String, command: String) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package com.juul.kommand | ||
|
||
import com.github.ajalt.clikt.core.CliktCommand | ||
import com.github.ajalt.clikt.parameters.arguments.argument | ||
import com.github.ajalt.clikt.parameters.options.flag | ||
import com.github.ajalt.clikt.parameters.options.option | ||
|
||
class Kommand : CliktCommand() { | ||
|
||
private val command by argument() | ||
private val dryRun by option("-d", "--dry-run").flag() | ||
|
||
override fun run() { | ||
val projectName = currentDirectoryPath.substringAfterLast("/") | ||
val project = config.projects[projectName] | ||
?: error("Project '$projectName' not found in config") | ||
|
||
project.execute( | ||
command.let { project.commands[it] ?: error("Command '$it' not found in project") }, | ||
dryRun | ||
) | ||
} | ||
} | ||
|
||
fun Config.path(project: Project) = "$homeDirectory/${project.name}" | ||
|
||
fun Project.execute(command: Command, dryRun: Boolean) { | ||
command.dependencies?.forEach { execute(it, dryRun) } | ||
if (!dryRun) println() | ||
println("🏃 $name ▶ ${command.command}") | ||
if (!dryRun) execute(config.path(this), command.command) | ||
} | ||
|
||
fun execute(dependency: Dependency, dryRun: Boolean) { | ||
val projectName = dependency.project | ||
val commandName = dependency.command | ||
|
||
val project = config.projects[projectName] | ||
?: error("Project '$projectName' not found in config") | ||
val command = project.commands[commandName] | ||
?: error("Command '$commandName' not found in project '$projectName'") | ||
|
||
project.execute(command, dryRun) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package com.juul.kommand | ||
|
||
expect val currentDirectoryPath: String | ||
expect val homePath: String |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.juul.kommand | ||
|
||
import platform.Foundation.NSString | ||
import platform.Foundation.stringWithContentsOfFile | ||
|
||
actual fun read( | ||
path: String | ||
): String? = NSString.stringWithContentsOfFile(path) as? String |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.juul.kommand | ||
|
||
import kotlinx.cinterop.autoreleasepool | ||
import platform.Foundation.NSPipe | ||
import platform.Foundation.NSTask | ||
import platform.Foundation.currentDirectoryPath | ||
import platform.Foundation.launch | ||
import platform.Foundation.launchPath | ||
import platform.Foundation.waitUntilExit | ||
|
||
actual fun execute(path: String, command: String) { | ||
autoreleasepool { | ||
val stdin = NSPipe() | ||
val task = NSTask() | ||
task.currentDirectoryPath = path | ||
task.launchPath = "/bin/sh" | ||
task.arguments = listOf("-c", command) | ||
task.standardInput = stdin | ||
task.launch() | ||
task.waitUntilExit() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.juul.kommand | ||
|
||
import platform.Foundation.NSFileManager | ||
import platform.Foundation.homeDirectoryForCurrentUser | ||
|
||
actual val currentDirectoryPath: String = NSFileManager.defaultManager.currentDirectoryPath | ||
|
||
actual val homePath: String = NSFileManager.defaultManager.homeDirectoryForCurrentUser.path | ||
?: error("Home directory unavailable") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.juul.kommand | ||
|
||
fun main(args: Array<String>) { | ||
if (args.isEmpty()) printCommands() | ||
Kommand().main(args) | ||
} | ||
|
||
private fun printCommands() { | ||
val projectName = currentDirectoryPath.substringAfterLast("/") | ||
val project = config.projects[projectName] ?: return | ||
println("▼ $projectName COMMANDs") | ||
project.commands.keys.forEach { println("• $it") } | ||
println() | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
distributionBase=GRADLE_USER_HOME | ||
distributionPath=wrapper/dists | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip | ||
zipStoreBase=GRADLE_USER_HOME | ||
zipStorePath=wrapper/dists |
Oops, something went wrong.