From a845d1dabed53f65fafc9c2e19804f4d94ec832a Mon Sep 17 00:00:00 2001 From: Jonas Wanke Date: Sat, 6 Apr 2019 17:22:35 +0200 Subject: [PATCH 01/12] feat(commands/init): support existing projects --- .../com/jonaswanke/unicorn/ProjectConfig.kt | 3 +- .../unicorn/commands/BaseCommand.kt | 15 +- .../com/jonaswanke/unicorn/commands/Init.kt | 233 ++++++++++++------ .../unicorn/commands/issue/CompleteIssue.kt | 2 +- .../unicorn/utils/GitCommandUtils.kt | 4 +- 5 files changed, 170 insertions(+), 87 deletions(-) diff --git a/src/main/kotlin/com/jonaswanke/unicorn/ProjectConfig.kt b/src/main/kotlin/com/jonaswanke/unicorn/ProjectConfig.kt index 7edc187..fcac77a 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/ProjectConfig.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/ProjectConfig.kt @@ -7,8 +7,7 @@ data class ProjectConfig( val type: Type, val name: String, val description: String?, - val version: SemVer, - val githubName: String? = null + val version: SemVer ) { enum class Type { ANDROID, diff --git a/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt b/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt index fb66033..6c5378a 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt @@ -144,7 +144,20 @@ abstract class BaseCommand( val github get() = getGithubAuthResult().github val githubCp get() = getGithubAuthResult().credentialsProvider - val githubRepo: GHRepository? get() = github.getRepository(getProjectConfig().githubName) + + val githubRepoName: String? + get() { + return call(git.remoteList()).mapNotNull { remoteConfig -> + remoteConfig.urIs.firstOrNull { it.host == "github.com" } + } + .firstOrNull() + ?.path + ?.trimStart('/') + ?.substringBeforeLast('.') + } + val githubRepo: GHRepository? + get() = githubRepoName?.let { github.getRepository(it) } + fun requireGithubRepo(): GHRepository { return githubRepo ?: throw UsageError("No repository is configured for the current project") diff --git a/src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt b/src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt index 1df3974..0fb569c 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt @@ -1,11 +1,9 @@ package com.jonaswanke.unicorn.commands import com.fasterxml.jackson.core.type.TypeReference -import com.github.ajalt.clikt.core.BadParameterValue -import com.github.ajalt.clikt.core.CliktError -import com.github.ajalt.clikt.core.NoSuchOption -import com.github.ajalt.clikt.core.PrintMessage +import com.github.ajalt.clikt.core.* import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.arguments.optional import com.github.ajalt.clikt.parameters.options.convert import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.types.choice @@ -15,6 +13,7 @@ import net.swiftzer.semver.SemVer import okhttp3.OkHttpClient import okhttp3.Request import org.eclipse.jgit.api.Git +import org.eclipse.jgit.lib.RepositoryBuilder import org.eclipse.jgit.transport.URIish import org.kohsuke.github.GHCreateRepositoryBuilder import org.kohsuke.github.GHOrganization @@ -36,6 +35,7 @@ open class Create : BaseCommand() { } private val name by argument("name") + .optional() private val description by option("-d", "--desc", "--description") private val type by option("-t", "--type") .choice(ProjectConfig.Type.stringToValueMap) @@ -43,7 +43,28 @@ open class Create : BaseCommand() { .convert { SemVer.parse(it) } override fun run() { + val initInExisting = name == null + if (initInExisting) + confirm("Using create in an existing project is experimental. Continue?", abort = true) + + val name = name + ?: prefix.name + + if (initInExisting) { + if (!prefix.exists()) + throw UsageError("The specified directory does not exist. If you want to create a new repository, please specify a name") + if (!prefix.isDirectory) + throw UsageError("The specified path is not a directory. If you want to create a new repository, please specify a name") + try { + getProjectConfig() + throw UsageError("Unicorn is already initialized in the specified directory") + } catch (e: IOException) { + // Means no project config file was found - expected + } + } + val description = description + ?: githubRepo?.description ?: promptOptional("Provide a short description") val type: ProjectConfig.Type = type ?: prompt( @@ -57,7 +78,12 @@ open class Create : BaseCommand() { ?: throw NoSuchOption(key, ProjectConfig.Type.stringToValueMap.keys.toList()) } val version = version - ?: prompt("What's the initial version of your project?", default = "0.0.1") { + ?: prompt( + if (initInExisting) "What's the current version of your project?" + else "What's the initial version of your project?", + default = githubRepo?.latestRelease?.tagName?.removePrefix("v") + ?: "0.0.1" + ) { try { SemVer.parse(it) } catch (e: IllegalArgumentException) { @@ -82,10 +108,14 @@ open class Create : BaseCommand() { fun createFiles(): File { echo("Creating files...") - echo("Creating directory") - val dir = File(prefix, "./$name") - if (dir.exists()) throw PrintMessage("The specified directory already exists!") - dir.mkdirs() + val dir = if (initInExisting) prefix + else { + echo("Creating directory") + File(prefix, "./$name").also { + if (it.exists()) throw PrintMessage("The specified directory already exists!") + it.mkdirs() + } + } echo("Saving project config") val config = ProjectConfig( @@ -103,8 +133,18 @@ open class Create : BaseCommand() { File(dir, ".github").mkdir() copyTemplate(dir, replacements, "github/PULL_REQUEST_TEMPLATE.md", ".github/PULL_REQUEST_TEMPLATE.md") File(dir, ".github/ISSUE_TEMPLATE").mkdir() - copyTemplate(dir, replacements, "github/ISSUE_TEMPLATE/1-bug-report.md", ".github/ISSUE_TEMPLATE/1-bug-report.md") - copyTemplate(dir, replacements, "github/ISSUE_TEMPLATE/2-feature-request.md", ".github/ISSUE_TEMPLATE/2-feature-request.md") + copyTemplate( + dir, + replacements, + "github/ISSUE_TEMPLATE/1-bug-report.md", + ".github/ISSUE_TEMPLATE/1-bug-report.md" + ) + copyTemplate( + dir, + replacements, + "github/ISSUE_TEMPLATE/2-feature-request.md", + ".github/ISSUE_TEMPLATE/2-feature-request.md" + ) return dir } @@ -113,7 +153,9 @@ open class Create : BaseCommand() { // Travis CI newLine() - if (confirm("Setup Travis CI?", default = true) == true) { + if (!fileExists(dir, CI_TRAVIS_CONFIG_FILE) + && confirm("Setup Travis CI?", default = true) == true + ) { when (type) { ProjectConfig.Type.ANDROID -> { echo("A config file is being generated for you, but you have to manually setup travis-ci.com to connect to GitHub and your repo.") @@ -129,50 +171,58 @@ open class Create : BaseCommand() { fun initGit(): Git { echo("Initializing git...") - val gitignore = promptOptional( - "Please enter the .gitignore-template names from www.gitignore.io to use (separated by a comma)" - ) { input -> - val templates = input?.split(",") - ?.map { it.trim().toLowerCase() } - ?: emptyList() - - val request = Request.Builder() - .get() - .url("https://www.gitignore.io/api/${templates.joinToString(",")}") - .build() - val result = webClient.newCall(request).execute().use { - it.body()?.string() - } ?: throw CliktError("Network error: No response") - - val errorLine = result.indexOf(GIT_GITIGNOREIO_ERROR_PREFIX) - if (errorLine >= 0) - result.substring(errorLine + GIT_GITIGNOREIO_ERROR_PREFIX.length) - .substringBefore(' ') - .let { invalidOption -> - throw NoSuchOption(invalidOption) - } - - result - } ?: "" - copyTemplate(dir, replacements, "gitignore", GIT_GITIGNORE_FILE) - File(dir, GIT_GITIGNORE_FILE) - .appendText(gitignore) + if (!fileExists(dir, GIT_GITIGNORE_FILE)) { + val gitignore = promptOptional( + "Please enter the .gitignore-template names from www.gitignore.io to use (separated by a comma)" + ) { input -> + val templates = input?.split(",") + ?.map { it.trim().toLowerCase() } + ?: emptyList() + + val request = Request.Builder() + .get() + .url("https://www.gitignore.io/api/${templates.joinToString(",")}") + .build() + val result = webClient.newCall(request).execute().use { + it.body()?.string() + } ?: throw CliktError("Network error: No response") + + val errorLine = result.indexOf(GIT_GITIGNOREIO_ERROR_PREFIX) + if (errorLine >= 0) + result.substring(errorLine + GIT_GITIGNOREIO_ERROR_PREFIX.length) + .substringBefore(' ') + .let { invalidOption -> + throw NoSuchOption(invalidOption) + } + + result + } ?: "" + copyTemplate(dir, replacements, "gitignore", GIT_GITIGNORE_FILE) + File(dir, GIT_GITIGNORE_FILE) + .appendText(gitignore) + } copyTemplate(dir, replacements, "gitattributes", GIT_GITATTRIBUTES_FILE) - val git = Git.init() - .setDirectory(dir) - .call() - call(git.add()) { - addFilepattern(".") - } - call(git.commit()) { - message = "Initial commit" - } - call(git.checkout()) { - setCreateBranch(true) - setName(BRANCH_DEV) + + + return if (isGitRepo(dir)) git + else { + Git.init() + .setDirectory(dir) + .call() + .also { git -> + call(git.add()) { + addFilepattern(".") + } + call(git.commit()) { + message = "Initial commit" + } + call(git.checkout()) { + setCreateBranch(true) + setName(BRANCH_DEV) + } + } } - return git } val git = initGit() @@ -210,6 +260,7 @@ open class Create : BaseCommand() { throw NoSuchOption(it) } } + val private = confirm("Should the repository be private?", default = true) ?: true val repoBuilder = organization?.createRepository(name) @@ -223,7 +274,6 @@ open class Create : BaseCommand() { repoBuilder.init(false) } else throw e } - setProjectConfig(getProjectConfig(dir).copy(githubName = repo.fullName), dir) echo("Uploading") call(git.remoteAdd()) { @@ -234,39 +284,43 @@ open class Create : BaseCommand() { git.trackBranch(BRANCH_DEV) call(git.push()) { setPushAll() + isForce = true } return repo } - val githubRepo = uploadToGithub() - fun configureGithub() { - echo("Configuring GitHub...") - - // Labels - echo("Creating labels") - for (label in githubRepo.listLabels()) - label.delete() - - val labels = readConfig("github-labels.yaml", object : TypeReference>() {}) - for (label in labels) - githubRepo.createLabel(label.name, label.color) - - // Default branch - echo("Setting $BRANCH_DEV as default branch") - githubRepo.defaultBranch = BRANCH_DEV - - // Branch protection - echo("Setting up branch protection") - githubRepo.apply { - for (branch in listOf(getBranch(BRANCH_MASTER), getBranch(BRANCH_DEV))) - branch.enableProtection() - .requiredReviewers(1) - .includeAdmins(false) - .enable() + if (githubRepo == null) { + val githubRepo = uploadToGithub() + + fun configureGithub() { + echo("Configuring GitHub...") + + // Labels + echo("Creating labels") + for (label in githubRepo.listLabels()) + label.delete() + + val labels = readConfig("github-labels.yaml", object : TypeReference>() {}) + for (label in labels) + githubRepo.createLabel(label.name, label.color) + + // Default branch + echo("Setting $BRANCH_DEV as default branch") + githubRepo.defaultBranch = BRANCH_DEV + + // Branch protection + echo("Setting up branch protection") + githubRepo.apply { + for (branch in listOf(getBranch(BRANCH_MASTER), getBranch(BRANCH_DEV))) + branch.enableProtection() + .requiredReviewers(1) + .includeAdmins(false) + .enable() + } } + configureGithub() } - configureGithub() newLine() echo("Done!") @@ -274,9 +328,26 @@ open class Create : BaseCommand() { data class Label(val name: String, val color: String) + + private fun fileExists(dir: File, fileName: String): Boolean { + return File(dir, fileName).exists() + } + + private fun isGitRepo(dir: File): Boolean { + if (!dir.isDirectory) return false + + return RepositoryBuilder().apply { + addCeilingDirectory(dir) + findGitDir(dir) + }.gitDir != null + } + // region Resources private fun copyTemplate(dir: File, replacements: Replacements, resource: String, file: String = resource) { - File(dir, file).outputStream().bufferedWriter().use { writer -> + val dest = File(dir, file) + if (dest.exists()) return + + dest.outputStream().bufferedWriter().use { writer -> javaClass.getResourceAsStream("/templates/$resource") .reader() .forEachLine { diff --git a/src/main/kotlin/com/jonaswanke/unicorn/commands/issue/CompleteIssue.kt b/src/main/kotlin/com/jonaswanke/unicorn/commands/issue/CompleteIssue.kt index b9d9d0a..d3a7b78 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/commands/issue/CompleteIssue.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/commands/issue/CompleteIssue.kt @@ -42,7 +42,7 @@ class CompleteIssue : BaseCommand(name = "complete") { // Open prefilled compare-webpage to create a PR fun String.encode() = URLEncoder.encode(this, "UTF-8") - var link = "https://github.com/${getProjectConfig().githubName}/compare/${branch.encode()}" + + var link = "${repo.htmlUrl}/compare/${branch.encode()}" + "?expand=1" + "&title=${(if (component != null) "$type($component): $title" else "$type: $title").encode()}" + "&${labels.joinToString("&") { "labels=${it.name.encode()}" }}" + diff --git a/src/main/kotlin/com/jonaswanke/unicorn/utils/GitCommandUtils.kt b/src/main/kotlin/com/jonaswanke/unicorn/utils/GitCommandUtils.kt index a0146b6..71519eb 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/utils/GitCommandUtils.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/utils/GitCommandUtils.kt @@ -8,8 +8,8 @@ import org.eclipse.jgit.api.TransportCommand import kotlin.contracts.ExperimentalContracts @ExperimentalContracts -fun , T> BaseCommand.call(command: C, configure: C.() -> Unit = {}) { - command.also { +fun , T> BaseCommand.call(command: C, configure: C.() -> Unit = {}): T { + return command.also { if (it is TransportCommand<*, *>) it.setCredentialsProvider(githubCp) it.configure() From 4f5a353e16a98f98d43a0aebfd9865d38005d857 Mon Sep 17 00:00:00 2001 From: Jonas Wanke Date: Sat, 6 Apr 2019 17:23:08 +0200 Subject: [PATCH 02/12] fix(commands/init): remove github folder from gitignore --- res/templates/gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/res/templates/gitignore b/res/templates/gitignore index 821c19d..e69de29 100644 --- a/res/templates/gitignore +++ b/res/templates/gitignore @@ -1 +0,0 @@ -.github \ No newline at end of file From e95465b1adf48402329ea0b2514d309e5b298358 Mon Sep 17 00:00:00 2001 From: Jonas Wanke Date: Sat, 6 Apr 2019 17:23:44 +0200 Subject: [PATCH 03/12] build: fix naming and gradle distribution --- .idea/compiler.xml | 4 +--- .idea/misc.xml | 2 +- gradle/wrapper/gradle-wrapper.properties | 3 ++- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index c0eadca..d7bf0de 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -2,10 +2,8 @@ - - - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 5f1296e..fab4bed 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -6,7 +6,7 @@ - + \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 115e6ac..d465783 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Thu Apr 04 16:06:29 CEST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-all.zip From 24bfba865564f7ee02813e570e3069b966b40b6e Mon Sep 17 00:00:00 2001 From: Jonas Wanke Date: Sat, 6 Apr 2019 17:31:16 +0200 Subject: [PATCH 04/12] feat: use unicorn --- .unicornfig.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .unicornfig.yml diff --git a/.unicornfig.yml b/.unicornfig.yml new file mode 100644 index 0000000..559f153 --- /dev/null +++ b/.unicornfig.yml @@ -0,0 +1,6 @@ +--- +unicornVersion: "0.0.1" +type: "OTHER" +name: "Unicorn" +description: "\U0001f984 A tool to create, work on, test and deploy projects." +version: "0.0.1" From 05d76881e406aa2baebe8bc18cfb397046d5e0c7 Mon Sep 17 00:00:00 2001 From: Jonas Wanke Date: Sat, 6 Apr 2019 17:55:04 +0200 Subject: [PATCH 05/12] fix: rename project config to .unicorn.yaml --- .unicornfig.yml => .unicorn.yml | 0 src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename .unicornfig.yml => .unicorn.yml (100%) diff --git a/.unicornfig.yml b/.unicorn.yml similarity index 100% rename from .unicornfig.yml rename to .unicorn.yml diff --git a/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt b/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt index 6c5378a..3e5024f 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt @@ -27,7 +27,7 @@ abstract class BaseCommand( ) : CliktCommand(help, epilog, name, invokeWithoutSubcommand) { companion object { private const val CONFIG_GLOBAL_FILE = ".config.yml" - private const val CONFIG_PROJECT_FILE = ".unicornfig.yml" + private const val CONFIG_PROJECT_FILE = ".unicorn.yml" } init { From 996b01a951accabcb3d19fe7f5b729cdd5e879f0 Mon Sep 17 00:00:00 2001 From: Jonas Wanke Date: Sat, 6 Apr 2019 17:56:00 +0200 Subject: [PATCH 06/12] fix: rename global config to config.yaml and move it to parent folder --- .../kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt b/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt index 3e5024f..11c46e4 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt @@ -26,7 +26,7 @@ abstract class BaseCommand( invokeWithoutSubcommand: Boolean = false ) : CliktCommand(help, epilog, name, invokeWithoutSubcommand) { companion object { - private const val CONFIG_GLOBAL_FILE = ".config.yml" + private const val CONFIG_GLOBAL_FILE = "config.yml" private const val CONFIG_PROJECT_FILE = ".unicorn.yml" } @@ -41,7 +41,7 @@ abstract class BaseCommand( .default(File(System.getProperty("user.dir"))) // region Global config - private val installDir = File(javaClass.protectionDomain.codeSource.location.toURI()).parentFile + private val installDir = File(javaClass.protectionDomain.codeSource.location.toURI()).parentFile.parentFile private val globalConfigFile: File get() = File(installDir, CONFIG_GLOBAL_FILE).apply { if (!exists()) { From 463971a2f2aa9eb8d519d1d1ce809dbdd3a61294 Mon Sep 17 00:00:00 2001 From: Jonas Wanke Date: Sat, 6 Apr 2019 18:43:16 +0200 Subject: [PATCH 07/12] fix(commands/init): only create .gitignore if templates were selected --- .../kotlin/com/jonaswanke/unicorn/commands/Init.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt b/src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt index 0fb569c..a9832a2 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt @@ -177,7 +177,7 @@ open class Create : BaseCommand() { ) { input -> val templates = input?.split(",") ?.map { it.trim().toLowerCase() } - ?: emptyList() + if (templates.isNullOrEmpty()) return@promptOptional null val request = Request.Builder() .get() @@ -196,10 +196,12 @@ open class Create : BaseCommand() { } result - } ?: "" - copyTemplate(dir, replacements, "gitignore", GIT_GITIGNORE_FILE) - File(dir, GIT_GITIGNORE_FILE) - .appendText(gitignore) + } + if (gitignore != null) { + copyTemplate(dir, replacements, "gitignore", GIT_GITIGNORE_FILE) + File(dir, GIT_GITIGNORE_FILE) + .appendText(gitignore) + } } copyTemplate(dir, replacements, "gitattributes", GIT_GITATTRIBUTES_FILE) From 4b9e7cd78d7c878acb548f3829c35df5e6358e0d Mon Sep 17 00:00:00 2001 From: Jonas Wanke Date: Sat, 6 Apr 2019 18:44:12 +0200 Subject: [PATCH 08/12] fix(commands/init): only request GitHub config for existing projects --- src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt b/src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt index a9832a2..c299f47 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/commands/Init.kt @@ -64,8 +64,8 @@ open class Create : BaseCommand() { } val description = description - ?: githubRepo?.description - ?: promptOptional("Provide a short description") + ?: if (initInExisting) githubRepo?.description else null + ?: promptOptional("Provide a short description") val type: ProjectConfig.Type = type ?: prompt( "What describes your project best? " + @@ -81,7 +81,7 @@ open class Create : BaseCommand() { ?: prompt( if (initInExisting) "What's the current version of your project?" else "What's the initial version of your project?", - default = githubRepo?.latestRelease?.tagName?.removePrefix("v") + default = (if (initInExisting) githubRepo?.latestRelease?.tagName?.removePrefix("v") else null) ?: "0.0.1" ) { try { From 6f8f975f84bce03881faef648e446c02e566d78b Mon Sep 17 00:00:00 2001 From: Jonas Wanke Date: Sat, 6 Apr 2019 20:12:41 +0200 Subject: [PATCH 09/12] feat(commands/login): remove password support --- .../com/jonaswanke/unicorn/GlobalConfig.kt | 4 +--- .../unicorn/commands/BaseCommand.kt | 24 ++++--------------- .../jonaswanke/unicorn/utils/ConfigUtils.kt | 2 ++ 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/src/main/kotlin/com/jonaswanke/unicorn/GlobalConfig.kt b/src/main/kotlin/com/jonaswanke/unicorn/GlobalConfig.kt index 3d41088..184ea53 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/GlobalConfig.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/GlobalConfig.kt @@ -8,14 +8,12 @@ data class GlobalConfig( ) { data class GithubConfig( val username: String, - val password: String?, - val oauthToken: String?, + val oauthToken: String, val endpoint: String? ) { fun buildGithub(): GitHub { return GitHubBuilder().apply { withOAuthToken(oauthToken, username) - withPassword(username, password) if (endpoint != null) withEndpoint(endpoint) }.build() } diff --git a/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt b/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt index 11c46e4..4b0e66d 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/commands/BaseCommand.kt @@ -81,7 +81,6 @@ abstract class BaseCommand( fun githubAuthenticate( forceNew: Boolean = false, username: String? = null, - password: String? = null, token: String? = null, endpoint: String? = null ) { @@ -100,32 +99,19 @@ abstract class BaseCommand( } } + echo("Please enter your GitHub credentials (They will be stored unencrypted in the installation directory):") while (true) { - echo("Please enter your GitHub credentials (They will be stored unencrypted in the installation directory):") val usernameAct = username ?: prompt("GitHub username") ?: throw MissingParameter("username") - val (passwordAct, tokenAct) = - if (confirm( - "Use password (alternative: OAuth-token) (When 2FA is enabled, only OAuth will work)", - default = true - ) != false - ) { - val passwordAct = password - ?: prompt("Password", hideInput = true) - ?: throw MissingParameter("password") - passwordAct to null - } else { - val tokenAct = token - ?: prompt("Personal access token", hideInput = true) - ?: throw MissingParameter("personal access token") - null to tokenAct - } + val tokenAct = token + ?: prompt("Personal access token (with repo scope)", hideInput = true) + ?: throw MissingParameter("personal access token") val endpointAct = endpoint ?: promptOptional("Custom GitHub endpoint?") val githubConfig = GlobalConfig.GithubConfig( - username = usernameAct, password = passwordAct, oauthToken = tokenAct, endpoint = endpointAct + username = usernameAct, oauthToken = tokenAct, endpoint = endpointAct ) globalConfig = globalConfig.copy(github = githubConfig) val github = githubConfig.buildGithub() diff --git a/src/main/kotlin/com/jonaswanke/unicorn/utils/ConfigUtils.kt b/src/main/kotlin/com/jonaswanke/unicorn/utils/ConfigUtils.kt index fcff087..5ed57ef 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/utils/ConfigUtils.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/utils/ConfigUtils.kt @@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.SerializerProvider import com.fasterxml.jackson.databind.deser.std.StdDeserializer @@ -15,6 +16,7 @@ import java.io.InputStream import java.io.OutputStream val mapper: ObjectMapper = ObjectMapper(YAMLFactory()) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .registerModule(KotlinModule() .addSerializer(SemVer::class.java, object : StdSerializer(SemVer::class.java) { override fun serialize(value: SemVer?, gen: JsonGenerator?, provider: SerializerProvider?) { From 6392a0fa71541ba6c947f703f04809264f4930a4 Mon Sep 17 00:00:00 2001 From: Jonas Wanke Date: Tue, 9 Apr 2019 19:12:21 +0200 Subject: [PATCH 10/12] docs: fix/shorten templates and labels --- .github/ISSUE_TEMPLATE/1-bug-report.md | 17 +++++++++-------- .github/ISSUE_TEMPLATE/2-feature-request.md | 13 +++++-------- .github/PULL_REQUEST_TEMPLATE.md | 18 ++++++++---------- res/config/github-labels.yaml | 6 ++++-- .../github/ISSUE_TEMPLATE/1-bug-report.md | 16 +++++++++------- .../github/ISSUE_TEMPLATE/2-feature-request.md | 13 +++++-------- res/templates/github/PULL_REQUEST_TEMPLATE.md | 17 +++++++---------- 7 files changed, 47 insertions(+), 53 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/1-bug-report.md b/.github/ISSUE_TEMPLATE/1-bug-report.md index f3b42f5..1afb3db 100644 --- a/.github/ISSUE_TEMPLATE/1-bug-report.md +++ b/.github/ISSUE_TEMPLATE/1-bug-report.md @@ -27,20 +27,21 @@ Please select the component label (C: abc) this bug is related to from the right + - -| Description 1 | Description 2 | Description 3 | -| :------------: | :------------: | :------------: | -| | | | +| Description 1 | Description 2 | +| :------------: | :------------: | +| | | +--> **Environment:** - - Device: - - Android version: + - OS: + - Unicorn version: + +--> diff --git a/.github/ISSUE_TEMPLATE/2-feature-request.md b/.github/ISSUE_TEMPLATE/2-feature-request.md index 2d4ecad..57ae29b 100644 --- a/.github/ISSUE_TEMPLATE/2-feature-request.md +++ b/.github/ISSUE_TEMPLATE/2-feature-request.md @@ -2,24 +2,21 @@ name: "\U0001F680 Feature request" about: Suggest an idea for this project title: '' -labels: 'T: feature' +labels: 'T: feat' assignees: '' --- **Description** - - - -**Solution** - + + +--> diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 38bd169..8384e25 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,7 +3,7 @@ @@ -12,27 +12,25 @@ - [ ] Commit messages follow conventionalcommits.org -- [ ] Tested in production - [ ] Tests for the changes have been added (for bug fixes / features) - [ ] Docs have been added / updated (for bug fixes / features) **Changes** - + -- -- -- + +--> + diff --git a/res/config/github-labels.yaml b/res/config/github-labels.yaml index 64ca49f..e07dac2 100644 --- a/res/config/github-labels.yaml +++ b/res/config/github-labels.yaml @@ -10,15 +10,17 @@ - name: "PR: wip" color: "64eac4" +- name: "PR: breaking" + color: "64eac4" -- name: "C: /" +- name: "C: " color: "c2e0c6" - name: "T: ci" color: "c5def5" - name: "T: docs" color: "c5def5" -- name: "T: feature" +- name: "T: feat" color: "c5def5" - name: "T: fix" color: "c5def5" diff --git a/res/templates/github/ISSUE_TEMPLATE/1-bug-report.md b/res/templates/github/ISSUE_TEMPLATE/1-bug-report.md index f3b42f5..e4db799 100644 --- a/res/templates/github/ISSUE_TEMPLATE/1-bug-report.md +++ b/res/templates/github/ISSUE_TEMPLATE/1-bug-report.md @@ -27,20 +27,22 @@ Please select the component label (C: abc) this bug is related to from the right + - -| Description 1 | Description 2 | Description 3 | -| :------------: | :------------: | :------------: | -| | | | +| Description 1 | Description 2 | +| :------------: | :------------: | +| | | +--> **Environment:** - Device: - - Android version: + - OS: + - Program/library version: + +--> diff --git a/res/templates/github/ISSUE_TEMPLATE/2-feature-request.md b/res/templates/github/ISSUE_TEMPLATE/2-feature-request.md index 2d4ecad..57ae29b 100644 --- a/res/templates/github/ISSUE_TEMPLATE/2-feature-request.md +++ b/res/templates/github/ISSUE_TEMPLATE/2-feature-request.md @@ -2,24 +2,21 @@ name: "\U0001F680 Feature request" about: Suggest an idea for this project title: '' -labels: 'T: feature' +labels: 'T: feat' assignees: '' --- **Description** - - - -**Solution** - + + +--> diff --git a/res/templates/github/PULL_REQUEST_TEMPLATE.md b/res/templates/github/PULL_REQUEST_TEMPLATE.md index c3d5862..8384e25 100644 --- a/res/templates/github/PULL_REQUEST_TEMPLATE.md +++ b/res/templates/github/PULL_REQUEST_TEMPLATE.md @@ -3,7 +3,7 @@ @@ -12,28 +12,25 @@ - [ ] Commit messages follow conventionalcommits.org -- [ ] Tested on actual devices - [ ] Tests for the changes have been added (for bug fixes / features) - [ ] Docs have been added / updated (for bug fixes / features) **Changes** - + -- -- -- + +--> From 5fb5bc1b525d5eebf65951a8c63914a4151c6e41 Mon Sep 17 00:00:00 2001 From: Jonas Wanke Date: Tue, 9 Apr 2019 19:39:12 +0200 Subject: [PATCH 11/12] chore: update changelog --- CHANGELOG.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45b6dab..36a55ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,10 +23,37 @@ Optional intro comment. ## [Unreleased] - see [milestones] for our roadmap + +## [0.0.2](https://github.com/JonasWanke/Unicorn/compare/v0.0.1...v0.0.2) - 2019-04-09 + + +### Features + +- use unicorn ([#37](https://github.com/JonasWanke/Unicorn/pull/37)), fixes [#34](https://github.com/JonasWanke/Unicorn/issues/34) +- **commands/init:** support init in existing repo ([#36](https://github.com/JonasWanke/Unicorn/pull/36)), fixes [#28](https://github.com/JonasWanke/Unicorn/issues/28), [#20](https://github.com/JonasWanke/Unicorn/issues/20), [#27](https://github.com/JonasWanke/Unicorn/issues/27) +- **commands/login:** remove password support ([#42](https://github.com/JonasWanke/Unicorn/pull/42)), fixes [#32](https://github.com/JonasWanke/Unicorn/issues/32) + + +### Bug Fixes + +- **commands/init:** only create .gitignore if templates were selected ([#41](https://github.com/JonasWanke/Unicorn/pull/41)), fixes [#30](https://github.com/JonasWanke/Unicorn/issues/30) + + +### Docs + +- **commands/init:** fix/shorten templates and labels ([#44](https://github.com/JonasWanke/Unicorn/pull/44)), fixes [#35](https://github.com/JonasWanke/Unicorn/issues/35) + + +### Refactor + +- rename config files ([#40](https://github.com/JonasWanke/Unicorn/pull/40)), fixes [#29](https://github.com/JonasWanke/Unicorn/issues/29) + + + ## 0.0.1 - 2019-01-30 Initial release supporting repository initialization. [milestones]: https://github.com/JonasWanke/Unicorn/milestones -[Unreleased]: https://github.com/JonasWanke/Unicorn/compare/v0.0.1...dev +[Unreleased]: https://github.com/JonasWanke/Unicorn/compare/v0.0.2...dev From 4e305468f92f89d843dcbfdfc25937706846a065 Mon Sep 17 00:00:00 2001 From: Jonas Wanke Date: Tue, 9 Apr 2019 19:42:31 +0200 Subject: [PATCH 12/12] chore: update version --- .unicorn.yml | 4 ++-- src/main/kotlin/com/jonaswanke/unicorn/ProgramConfig.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.unicorn.yml b/.unicorn.yml index 559f153..75570ad 100644 --- a/.unicorn.yml +++ b/.unicorn.yml @@ -1,6 +1,6 @@ --- -unicornVersion: "0.0.1" +unicornVersion: "0.0.2" type: "OTHER" name: "Unicorn" description: "\U0001f984 A tool to create, work on, test and deploy projects." -version: "0.0.1" +version: "0.0.2" diff --git a/src/main/kotlin/com/jonaswanke/unicorn/ProgramConfig.kt b/src/main/kotlin/com/jonaswanke/unicorn/ProgramConfig.kt index 15ab55a..312d836 100644 --- a/src/main/kotlin/com/jonaswanke/unicorn/ProgramConfig.kt +++ b/src/main/kotlin/com/jonaswanke/unicorn/ProgramConfig.kt @@ -3,5 +3,5 @@ package com.jonaswanke.unicorn import net.swiftzer.semver.SemVer object ProgramConfig { - val VERSION = SemVer.parse("0.0.1") + val VERSION = SemVer.parse("0.0.2") }