diff --git a/.idea/artifacts/gpm_main_jar.xml b/.idea/artifacts/gpm_main_jar.xml new file mode 100644 index 0000000..383e02e --- /dev/null +++ b/.idea/artifacts/gpm_main_jar.xml @@ -0,0 +1,36 @@ + + + $PROJECT_DIR$ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gpm.iml b/.idea/gpm.iml new file mode 100644 index 0000000..78b2cc5 --- /dev/null +++ b/.idea/gpm.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 2266f6b..32e560b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,6 +4,9 @@ + + diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 0000000..3235440 --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: com.theapache64.gpm.MainKt + diff --git a/README.md b/README.md index 0c1fed3..9450dd3 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ | `uninstall` | To uninstall the dependency from `implementation` | ✔️ | Done | v1.0.0-alpha01 | | `uninstall dev` | To uninstall the dependency from `testImplementation` | ✔️ | Done | v1.0.0-alpha01 | | `uninstall dev-android` | To uninstall the dependency from `androidTestImplementation` | ✔️ | Done | v1.0.0-alpha01 | -| `docs` | To open the documentation in default browser | ⏳ | Implementing | v1.0.0-alpha01 | +| `docs` | To open the documentation in default browser | ✔️ | Done | v1.0.0-alpha01 | | `update` | To update the dependency version to latest | ❌ | Pending | - | | `list` | To list all the dependencies | ❌ | Pending | - | diff --git a/build.gradle b/build.gradle index a71a398..67863ea 100644 --- a/build.gradle +++ b/build.gradle @@ -59,6 +59,9 @@ dependencies { // DaggerMock testImplementation 'com.github.fabioCollini.daggermock:daggermock:0.8.5' testImplementation 'com.github.fabioCollini.daggermock:daggermock-kotlin:0.8.5' + + // OkHttp:For networking + implementation 'com.squareup.okhttp3:okhttp:4.6.0' } compileKotlin { diff --git a/gpm_completion b/gpm_completion new file mode 100644 index 0000000..3042e66 --- /dev/null +++ b/gpm_completion @@ -0,0 +1,262 @@ +#!/usr/bin/env bash +# +# gpm Bash Completion +# ======================= +# +# Bash completion support for the `gpm` command, +# generated by [picocli](http://picocli.info/) version 4.2.0. +# +# Installation +# ------------ +# +# 1. Source all completion scripts in your .bash_profile +# +# cd $YOUR_APP_HOME/bin +# for f in $(find . -name "*_completion"); do line=". $(pwd)/$f"; grep "$line" ~/.bash_profile || echo "$line" >> ~/.bash_profile; done +# +# 2. Open a new bash console, and type `gpm [TAB][TAB]` +# +# 1a. Alternatively, if you have [bash-completion](https://github.com/scop/bash-completion) installed: +# Place this file in a `bash-completion.d` folder: +# +# * /etc/bash-completion.d +# * /usr/local/etc/bash-completion.d +# * ~/bash-completion.d +# +# Documentation +# ------------- +# The script is called by bash whenever [TAB] or [TAB][TAB] is pressed after +# 'gpm (..)'. By reading entered command line parameters, +# it determines possible bash completions and writes them to the COMPREPLY variable. +# Bash then completes the user input if only one entry is listed in the variable or +# shows the options if more than one is listed in COMPREPLY. +# +# References +# ---------- +# [1] http://stackoverflow.com/a/12495480/1440785 +# [2] http://tiswww.case.edu/php/chet/bash/FAQ +# [3] https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html +# [4] http://zsh.sourceforge.net/Doc/Release/Options.html#index-COMPLETE_005fALIASES +# [5] https://stackoverflow.com/questions/17042057/bash-check-element-in-array-for-elements-in-another-array/17042655#17042655 +# [6] https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html#Programmable-Completion +# [7] https://stackoverflow.com/questions/3249432/can-a-bash-tab-completion-script-be-used-in-zsh/27853970#27853970 +# + +if [ -n "$BASH_VERSION" ]; then + # Enable programmable completion facilities when using bash (see [3]) + shopt -s progcomp +elif [ -n "$ZSH_VERSION" ]; then + # Make alias a distinct command for completion purposes when using zsh (see [4]) + setopt COMPLETE_ALIASES + alias compopt=complete + + # Enable bash completion in zsh (see [7]) + autoload -U +X compinit && compinit + autoload -U +X bashcompinit && bashcompinit +fi + +# CompWordsContainsArray takes an array and then checks +# if all elements of this array are in the global COMP_WORDS array. +# +# Returns zero (no error) if all elements of the array are in the COMP_WORDS array, +# otherwise returns 1 (error). +function CompWordsContainsArray() { + declare -a localArray + localArray=("$@") + local findme + for findme in "${localArray[@]}"; do + if ElementNotInCompWords "$findme"; then return 1; fi + done + return 0 +} +function ElementNotInCompWords() { + local findme="$1" + local element + for element in "${COMP_WORDS[@]}"; do + if [[ "$findme" = "$element" ]]; then return 1; fi + done + return 0 +} + +# The `currentPositionalIndex` function calculates the index of the current positional parameter. +# +# currentPositionalIndex takes three parameters: +# the command name, +# a space-separated string with the names of options that take a parameter, and +# a space-separated string with the names of boolean options (that don't take any params). +# When done, this function echos the current positional index to std_out. +# +# Example usage: +# local currIndex=$(currentPositionalIndex "mysubcommand" "$ARG_OPTS" "$FLAG_OPTS") +function currentPositionalIndex() { + local commandName="$1" + local optionsWithArgs="$2" + local booleanOptions="$3" + local previousWord + local result=0 + + for i in $(seq $((COMP_CWORD - 1)) -1 0); do + previousWord=${COMP_WORDS[i]} + if [ "${previousWord}" = "$commandName" ]; then + break + fi + if [[ "${optionsWithArgs}" =~ ${previousWord} ]]; then + ((result-=2)) # Arg option and its value not counted as positional param + elif [[ "${booleanOptions}" =~ ${previousWord} ]]; then + ((result-=1)) # Flag option itself not counted as positional param + fi + ((result++)) + done + echo "$result" +} + +# Bash completion entry point function. +# _complete_gpm finds which commands and subcommands have been specified +# on the command line and delegates to the appropriate function +# to generate possible options and subcommands for the last specified subcommand. +function _complete_gpm() { + local cmds0=(install) + local cmds1=(i) + local cmds2=(uninstall) + local cmds3=(u) + local cmds4=(docs) + local cmds5=(d) + + if CompWordsContainsArray "${cmds5[@]}"; then _picocli_gpm_d; return $?; fi + if CompWordsContainsArray "${cmds4[@]}"; then _picocli_gpm_docs; return $?; fi + if CompWordsContainsArray "${cmds3[@]}"; then _picocli_gpm_u; return $?; fi + if CompWordsContainsArray "${cmds2[@]}"; then _picocli_gpm_uninstall; return $?; fi + if CompWordsContainsArray "${cmds1[@]}"; then _picocli_gpm_i; return $?; fi + if CompWordsContainsArray "${cmds0[@]}"; then _picocli_gpm_install; return $?; fi + + # No subcommands were specified; generate completions for the top-level command. + _picocli_gpm; return $?; +} + +# Generates completions for the options and subcommands of the `gpm` command. +function _picocli_gpm() { + # Get completion data + local curr_word=${COMP_WORDS[COMP_CWORD]} + + local commands="install i uninstall u docs d" + local flag_opts="-h --help -V --version" + local arg_opts="" + + if [[ "${curr_word}" == -* ]]; then + COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") ) + else + local positionals="" + COMPREPLY=( $(compgen -W "${commands} ${positionals}" -- "${curr_word}") ) + fi +} + +# Generates completions for the options and subcommands of the `install` subcommand. +function _picocli_gpm_install() { + # Get completion data + local curr_word=${COMP_WORDS[COMP_CWORD]} + + local commands="" + local flag_opts="-S --save -D --save-dev -DA --save-dev-android" + local arg_opts="" + + if [[ "${curr_word}" == -* ]]; then + COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") ) + else + local positionals="" + COMPREPLY=( $(compgen -W "${commands} ${positionals}" -- "${curr_word}") ) + fi +} + +# Generates completions for the options and subcommands of the `i` subcommand. +function _picocli_gpm_i() { + # Get completion data + local curr_word=${COMP_WORDS[COMP_CWORD]} + + local commands="" + local flag_opts="-S --save -D --save-dev -DA --save-dev-android" + local arg_opts="" + + if [[ "${curr_word}" == -* ]]; then + COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") ) + else + local positionals="" + COMPREPLY=( $(compgen -W "${commands} ${positionals}" -- "${curr_word}") ) + fi +} + +# Generates completions for the options and subcommands of the `uninstall` subcommand. +function _picocli_gpm_uninstall() { + # Get completion data + local curr_word=${COMP_WORDS[COMP_CWORD]} + + local commands="" + local flag_opts="-S --save -D --save-dev -DA --save-dev-android" + local arg_opts="" + + if [[ "${curr_word}" == -* ]]; then + COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") ) + else + local positionals="" + COMPREPLY=( $(compgen -W "${commands} ${positionals}" -- "${curr_word}") ) + fi +} + +# Generates completions for the options and subcommands of the `u` subcommand. +function _picocli_gpm_u() { + # Get completion data + local curr_word=${COMP_WORDS[COMP_CWORD]} + + local commands="" + local flag_opts="-S --save -D --save-dev -DA --save-dev-android" + local arg_opts="" + + if [[ "${curr_word}" == -* ]]; then + COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") ) + else + local positionals="" + COMPREPLY=( $(compgen -W "${commands} ${positionals}" -- "${curr_word}") ) + fi +} + +# Generates completions for the options and subcommands of the `docs` subcommand. +function _picocli_gpm_docs() { + # Get completion data + local curr_word=${COMP_WORDS[COMP_CWORD]} + + local commands="" + local flag_opts="" + local arg_opts="" + + if [[ "${curr_word}" == -* ]]; then + COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") ) + else + local positionals="" + COMPREPLY=( $(compgen -W "${commands} ${positionals}" -- "${curr_word}") ) + fi +} + +# Generates completions for the options and subcommands of the `d` subcommand. +function _picocli_gpm_d() { + # Get completion data + local curr_word=${COMP_WORDS[COMP_CWORD]} + + local commands="" + local flag_opts="" + local arg_opts="" + + if [[ "${curr_word}" == -* ]]; then + COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") ) + else + local positionals="" + COMPREPLY=( $(compgen -W "${commands} ${positionals}" -- "${curr_word}") ) + fi +} + +# Define a completion specification (a compspec) for the +# `gpm`, `gpm.sh`, and `gpm.bash` commands. +# Uses the bash `complete` builtin (see [6]) to specify that shell function +# `_complete_gpm` is responsible for generating possible completions for the +# current word on the command line. +# The `-o default` option means that if the function generated no matches, the +# default Bash completions and the Readline default filename completions are performed. +complete -F _complete_gpm -o default gpm gpm.sh gpm.bash diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..e69de29 diff --git a/src/main/kotlin/com/theapache64/gpm/Main.kt b/src/main/kotlin/com/theapache64/gpm/Main.kt index d62d182..ccea83e 100644 --- a/src/main/kotlin/com/theapache64/gpm/Main.kt +++ b/src/main/kotlin/com/theapache64/gpm/Main.kt @@ -1,5 +1,15 @@ package com.theapache64.gpm -fun main(args: Array) { +import com.theapache64.gpm.commands.gpm.Gpm +import picocli.CommandLine +import kotlin.system.exitProcess +fun main(args: Array) { + val cmd = CommandLine(Gpm(false)) + if (args.isEmpty()) { + cmd.usage(System.out) + } else { + val exitCode = cmd.execute(*args) + exitProcess(exitCode) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/commands/Gpm.kt b/src/main/kotlin/com/theapache64/gpm/commands/Gpm.kt deleted file mode 100644 index 3a854b9..0000000 --- a/src/main/kotlin/com/theapache64/gpm/commands/Gpm.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.theapache64.gpm.commands - -import com.theapache64.gpm.commands.subcommands.install.Install -import com.theapache64.gpm.commands.subcommands.uninstall.Uninstall -import picocli.CommandLine -import javax.inject.Inject -import javax.inject.Singleton - -@CommandLine.Command( - name = "gpm", - version = ["v1.0.0-alpha01"], - subcommands = [ - Install::class, - Uninstall::class - ] -) -@Singleton -class Gpm @Inject constructor() { -} \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/commands/base/BaseCommand.kt b/src/main/kotlin/com/theapache64/gpm/commands/base/BaseCommand.kt index 99b7b1e..77cf1a6 100644 --- a/src/main/kotlin/com/theapache64/gpm/commands/base/BaseCommand.kt +++ b/src/main/kotlin/com/theapache64/gpm/commands/base/BaseCommand.kt @@ -1,6 +1,5 @@ package com.theapache64.gpm.commands.base -import com.theapache64.gpm.utils.GpmConfig import com.theapache64.gpm.utils.InputUtils import kotlinx.coroutines.delay import java.util.concurrent.Callable @@ -20,7 +19,7 @@ abstract class BaseCommand( @Suppress("ConstantConditionIf") return if (isFromTest) { delay(1000) - 1 + 0 } else { InputUtils.getInt("Choose one", 1, items.size) - 1 } diff --git a/src/main/kotlin/com/theapache64/gpm/commands/base/BaseInstallUninstallViewModel.kt b/src/main/kotlin/com/theapache64/gpm/commands/base/BaseInstallUninstallViewModel.kt index 0d434c9..46b6633 100644 --- a/src/main/kotlin/com/theapache64/gpm/commands/base/BaseInstallUninstallViewModel.kt +++ b/src/main/kotlin/com/theapache64/gpm/commands/base/BaseInstallUninstallViewModel.kt @@ -5,9 +5,9 @@ import com.theapache64.gpm.core.gm.GradleDep abstract class BaseInstallUninstallViewModel : BaseViewModel() { fun getDepTypes( - isSave : Boolean, - isSaveDev : Boolean, - isSaveDevAndroid:Boolean, + isSave: Boolean, + isSaveDev: Boolean, + isSaveDevAndroid: Boolean, defaultType: String? ): List = mutableListOf().apply { diff --git a/src/main/kotlin/com/theapache64/gpm/commands/base/BaseViewModel.kt b/src/main/kotlin/com/theapache64/gpm/commands/base/BaseViewModel.kt index 17691ae..0bed580 100644 --- a/src/main/kotlin/com/theapache64/gpm/commands/base/BaseViewModel.kt +++ b/src/main/kotlin/com/theapache64/gpm/commands/base/BaseViewModel.kt @@ -1,5 +1,5 @@ package com.theapache64.gpm.commands.base abstract class BaseViewModel { - abstract suspend fun call(command: T) : Int + abstract suspend fun call(command: T): Int } \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/commands/gpm/Gpm.kt b/src/main/kotlin/com/theapache64/gpm/commands/gpm/Gpm.kt new file mode 100644 index 0000000..5ed6deb --- /dev/null +++ b/src/main/kotlin/com/theapache64/gpm/commands/gpm/Gpm.kt @@ -0,0 +1,35 @@ +package com.theapache64.gpm.commands.gpm + +import com.theapache64.gpm.commands.base.BaseCommand +import com.theapache64.gpm.commands.subcommands.docs.Docs +import com.theapache64.gpm.commands.subcommands.install.Install +import com.theapache64.gpm.commands.subcommands.uninstall.Uninstall +import kotlinx.coroutines.runBlocking +import picocli.CommandLine +import javax.inject.Inject +import javax.inject.Singleton + +@CommandLine.Command( + name = "gpm", + version = ["v1.0.0-alpha01"], + mixinStandardHelpOptions = true, + subcommands = [ + Install::class, + Uninstall::class, + Docs::class + ] +) +@Singleton +class Gpm @Inject constructor(isFromTest: Boolean = false) : BaseCommand(isFromTest) { + + init { + DaggerGpmComponent.create().inject(this) + } + + @Inject + lateinit var viewModel: GpmViewModel + + override fun call(): Int = runBlocking { + viewModel.call(this@Gpm) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/commands/gpm/GpmComponent.kt b/src/main/kotlin/com/theapache64/gpm/commands/gpm/GpmComponent.kt new file mode 100644 index 0000000..e2e4808 --- /dev/null +++ b/src/main/kotlin/com/theapache64/gpm/commands/gpm/GpmComponent.kt @@ -0,0 +1,10 @@ +package com.theapache64.gpm.commands.gpm + +import dagger.Component +import javax.inject.Singleton + +@Singleton +@Component +interface GpmComponent { + fun inject(gpm: Gpm) +} \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/commands/gpm/GpmViewModel.kt b/src/main/kotlin/com/theapache64/gpm/commands/gpm/GpmViewModel.kt new file mode 100644 index 0000000..0438692 --- /dev/null +++ b/src/main/kotlin/com/theapache64/gpm/commands/gpm/GpmViewModel.kt @@ -0,0 +1,10 @@ +package com.theapache64.gpm.commands.gpm + +import com.theapache64.gpm.commands.base.BaseViewModel +import javax.inject.Inject + +class GpmViewModel @Inject constructor() : BaseViewModel() { + override suspend fun call(command: Gpm): Int { + return 0 + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/commands/subcommands/docs/Docs.kt b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/docs/Docs.kt new file mode 100644 index 0000000..93fdc79 --- /dev/null +++ b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/docs/Docs.kt @@ -0,0 +1,37 @@ +package com.theapache64.gpm.commands.subcommands.docs + +import com.theapache64.gpm.commands.base.BaseCommand +import com.theapache64.gpm.di.modules.TransactionModule +import kotlinx.coroutines.runBlocking +import picocli.CommandLine +import javax.inject.Inject + +@CommandLine.Command( + name = "docs", + aliases = ["d"], + description = ["To open library docs"] +) +class Docs( + isFromTest: Boolean = false +) : BaseCommand(isFromTest) { + @CommandLine.Parameters(index = "0", description = ["Dependency name"]) + lateinit var depName: String + + @Inject + lateinit var docsViewModel: DocsViewModel + + init { + DaggerDocsComponent.builder() + .transactionModule(TransactionModule(isFromTest)) + .build() + .inject(this) + } + + override fun call(): Int = runBlocking { + docsViewModel.call(this@Docs) + } + + fun onDocUrl(docsUrl: String) { + println("Docs -> $docsUrl") + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/commands/subcommands/docs/DocsComponent.kt b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/docs/DocsComponent.kt new file mode 100644 index 0000000..ba92f41 --- /dev/null +++ b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/docs/DocsComponent.kt @@ -0,0 +1,20 @@ +package com.theapache64.gpm.commands.subcommands.docs + +import com.theapache64.gpm.core.TransactionManager +import com.theapache64.gpm.di.GpmJsonFile +import com.theapache64.gpm.di.modules.NetworkModule +import com.theapache64.gpm.di.modules.TransactionModule +import dagger.Component +import java.io.File +import javax.inject.Singleton + +@Singleton +@Component(modules = [TransactionModule::class, NetworkModule::class]) +interface DocsComponent { + + fun transactionManager(): TransactionManager + fun inject(docs: Docs) + + @GpmJsonFile + fun gpmJsonFile(): File +} \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/commands/subcommands/docs/DocsViewModel.kt b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/docs/DocsViewModel.kt new file mode 100644 index 0000000..3929936 --- /dev/null +++ b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/docs/DocsViewModel.kt @@ -0,0 +1,47 @@ +package com.theapache64.gpm.commands.subcommands.docs + +import com.theapache64.gpm.commands.base.BaseViewModel +import com.theapache64.gpm.core.TransactionManager +import com.theapache64.gpm.data.repos.GpmRepo +import javax.inject.Inject + +class DocsViewModel @Inject constructor( + private val tm: TransactionManager, + private val gpmRepo: GpmRepo +) : BaseViewModel() { + + companion object { + const val RESULT_DOC_FOUND = 123 + const val RESULT_NOT_FOUND = 404 + } + + override suspend fun call(command: Docs): Int { + + val depName = command.depName.trim().toLowerCase() + val transaction = tm.getInstalled(null, depName) + + if (transaction.isEmpty()) { + // check if remote registry got info about the repo in question + val remoteDep = gpmRepo.getDep(depName) ?: return RESULT_NOT_FOUND + + command.onDocUrl(remoteDep.docs) + return RESULT_DOC_FOUND + + } else { + + val index = if (transaction.size > 1) { + command.chooseIndex(transaction.map { + "${it.type} ${it.gpmDep.groupId}:${it.gpmDep.artifactId}" + }) + } else { + 0 + } + + val selDep = transaction[index] + command.onDocUrl(selDep.gpmDep.docs) + + return RESULT_DOC_FOUND + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/commands/subcommands/install/Install.kt b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/install/Install.kt index a603a22..fda4502 100644 --- a/src/main/kotlin/com/theapache64/gpm/commands/subcommands/install/Install.kt +++ b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/install/Install.kt @@ -1,24 +1,21 @@ package com.theapache64.gpm.commands.subcommands.install import com.theapache64.gpm.commands.base.BaseCommand -import com.theapache64.gpm.di.components.DaggerInstallComponent +import com.theapache64.gpm.core.gm.GradleDep +import com.theapache64.gpm.data.remote.gpm.models.GpmDep +import com.theapache64.gpm.di.modules.CommandModule import com.theapache64.gpm.di.modules.GradleModule import com.theapache64.gpm.di.modules.TransactionModule -import com.theapache64.gpm.utils.GpmConfig -import com.theapache64.gpm.utils.InputUtils -import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import picocli.CommandLine -import java.util.concurrent.Callable import javax.inject.Inject -import javax.inject.Singleton @CommandLine.Command( name = "install", aliases = ["i"], description = ["To install the dependency"] ) -class Install(isFromTest: Boolean) : BaseCommand(isFromTest) { +class Install(isFromTest: Boolean = false) : BaseCommand(isFromTest) { @CommandLine.Option( names = ["-S", "--save"], @@ -47,6 +44,7 @@ class Install(isFromTest: Boolean) : BaseCommand(isFromTest) { init { DaggerInstallComponent .builder() + .commandModule(CommandModule(isFromTest = false)) .gradleModule(GradleModule(isFromTest = false)) .transactionModule(TransactionModule(false)) .build() @@ -56,4 +54,28 @@ class Install(isFromTest: Boolean) : BaseCommand(isFromTest) { override fun call(): Int = runBlocking { installViewModel.call(this@Install) } + + fun onBeforeGetDep() { + println("🔍 Searching for '$depName'") + } + + fun onDepGot() { + println("✔️ Found dependency") + } + + fun onBeforeSearchingInGpmRegistry() { + println("🔍 Searching in gpm registry for '$depName'...") + } + + fun onBeforeSearchingInMavenCentral() { + println("🔍 Searching in maven for '$depName'") + } + + fun onDepNotFoundAnywhere() { + println("❌ Couldn't find dependency with name '$depName'") + } + + fun onBeforeAddDependency(depType: GradleDep.Type) { + println("⌨️ Adding ${depType.key} to build.gradle...") + } } \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/di/components/InstallComponent.kt b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/install/InstallComponent.kt similarity index 85% rename from src/main/kotlin/com/theapache64/gpm/di/components/InstallComponent.kt rename to src/main/kotlin/com/theapache64/gpm/commands/subcommands/install/InstallComponent.kt index 871040b..0cb22cc 100644 --- a/src/main/kotlin/com/theapache64/gpm/di/components/InstallComponent.kt +++ b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/install/InstallComponent.kt @@ -1,8 +1,7 @@ -package com.theapache64.gpm.di.components +package com.theapache64.gpm.commands.subcommands.install import com.squareup.moshi.Moshi -import com.theapache64.gpm.commands.Gpm -import com.theapache64.gpm.commands.subcommands.install.Install +import com.theapache64.gpm.commands.gpm.Gpm import com.theapache64.gpm.core.TransactionManager import com.theapache64.gpm.data.remote.gpm.GpmApiInterface import com.theapache64.gpm.data.remote.maven.MavenApiInterface @@ -17,7 +16,6 @@ import javax.inject.Singleton @Singleton @Component( modules = [ - ViewModelModule::class, NetworkModule::class, MoshiModule::class, GradleModule::class, diff --git a/src/main/kotlin/com/theapache64/gpm/commands/subcommands/install/InstallViewModel.kt b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/install/InstallViewModel.kt index 14e19c1..953cf5e 100644 --- a/src/main/kotlin/com/theapache64/gpm/commands/subcommands/install/InstallViewModel.kt +++ b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/install/InstallViewModel.kt @@ -15,6 +15,7 @@ class InstallViewModel @Inject constructor( private val gradleManager: GradleManager ) : BaseInstallUninstallViewModel() { + companion object { const val RESULT_DEP_INSTALLED = 200 const val RESULT_REPO_NOT_FOUND = 404 @@ -25,22 +26,23 @@ class InstallViewModel @Inject constructor( val depName = command.depName.trim().toLowerCase() // first get from + command.onBeforeGetDep() val gpmDep = getDep(command, depName) ?: return RESULT_REPO_NOT_FOUND - + command.onDepGot() val depTypes = getDepTypes( command.isSave, command.isSaveDev, command.isSaveDevAndroid, gpmDep.defaultType ) - require(depTypes.isNotEmpty()) { "Dependency type can't be empty" } - // Getting latest version + require(depTypes.isNotEmpty()) { "Dependency type can't be empty" } // Adding each dependency for (depType in depTypes) { + command.onBeforeAddDependency(depType) gradleManager.addDep( depName, depType, @@ -48,41 +50,61 @@ class InstallViewModel @Inject constructor( ) } + return RESULT_DEP_INSTALLED } - private suspend fun getDep(install: Install, depName: String): GpmDep? { + private suspend fun getDep( + install: Install, + depName: String + ): GpmDep? { + + install.onBeforeSearchingInGpmRegistry() var gpmDep = gpmRepo.getDep(depName) if (gpmDep == null) { // Searching for maven + install.onBeforeSearchingInMavenCentral() gpmDep = getFromMaven(install, depName) } + if (gpmDep == null) { + install.onDepNotFoundAnywhere() + } + return gpmDep } private suspend fun getFromMaven(install: Install, depName: String): GpmDep? { - val mavenDeps = mavenRepo.search(depName) if (mavenDeps.isNotEmpty()) { - val mostUsed = mavenDeps.maxBy { it.usage }!! - val selDepIndex = install.chooseIndex( - mavenDeps.map { - val text = "${it.groupId}:${it.artifactId}" - if (it == mostUsed) { - // color text - CommandLine.Help.Ansi.AUTO.string("@|bold,green $text|@") - } else { - //normal text - text + + val mostUsed = mavenDeps.maxBy { it.usage ?: 0 }!! + val selDepIndex = if (mavenDeps.size > 1) { + + val index = install.chooseIndex( + mavenDeps.map { + val text = "${it.groupId}:${it.artifactId}" + if (it == mostUsed) { + // color text + CommandLine.Help.Ansi.AUTO.string("@|bold,green $text|@") + } else { + //normal text + text + } } - } - ) + ) + + index + } else { + 0 + } + val selMavenDep = mavenDeps[selDepIndex] - // Getting last version + // Getting latest version + val artifactInfo = mavenRepo.getLatestVersion( selMavenDep.groupId, selMavenDep.artifactId @@ -98,6 +120,7 @@ class InstallViewModel @Inject constructor( null, selMavenDep.groupId, selMavenDep.name, + selMavenDep.description, artifactInfo.version ) } else { diff --git a/src/main/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/Uninstall.kt b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/Uninstall.kt index 827daaa..c56b1eb 100644 --- a/src/main/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/Uninstall.kt +++ b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/Uninstall.kt @@ -2,7 +2,6 @@ package com.theapache64.gpm.commands.subcommands.uninstall import com.theapache64.gpm.commands.base.BaseCommand import com.theapache64.gpm.core.gm.GradleDep -import com.theapache64.gpm.di.components.DaggerUninstallComponent import com.theapache64.gpm.di.modules.GradleModule import com.theapache64.gpm.di.modules.TransactionModule import kotlinx.coroutines.runBlocking @@ -14,7 +13,7 @@ import javax.inject.Inject aliases = ["u"], description = ["To uninstall a dependency"] ) -class Uninstall(isFromTest: Boolean) : BaseCommand(isFromTest) { +class Uninstall(isFromTest: Boolean = false) : BaseCommand(isFromTest) { @CommandLine.Option( names = ["-S", "--save"], @@ -54,10 +53,10 @@ class Uninstall(isFromTest: Boolean) : BaseCommand(isFromTest) { } fun onNoDepInstalled(depType: GradleDep.Type, depName: String) { - println("No dependency named '$depName' installed as '${depType.key}' using gpm. You might have installed it manually.") + println("⚠️ No dependency named '$depName' installed as '${depType.key}' using gpm. You might have installed it manually.") } - fun onBeforeDepRemove(depType: GradleDep.Type, depName: String) { - println("Removing '${depType.key}' of $depName...'") + fun onAfterDepRemove(depType: GradleDep.Type, depName: String) { + println("🗑️ Removed '${depType.key}' of '$depName'...") } } \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/di/components/UninstallComponent.kt b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/UninstallComponent.kt similarity index 71% rename from src/main/kotlin/com/theapache64/gpm/di/components/UninstallComponent.kt rename to src/main/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/UninstallComponent.kt index 9e0b670..c1a132a 100644 --- a/src/main/kotlin/com/theapache64/gpm/di/components/UninstallComponent.kt +++ b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/UninstallComponent.kt @@ -1,20 +1,18 @@ -package com.theapache64.gpm.di.components +package com.theapache64.gpm.commands.subcommands.uninstall -import com.theapache64.gpm.commands.subcommands.uninstall.Uninstall import com.theapache64.gpm.core.TransactionManager import com.theapache64.gpm.core.gm.GradleManager +import com.theapache64.gpm.di.GpmJsonFile +import com.theapache64.gpm.di.GradleFile import com.theapache64.gpm.di.modules.GradleModule import com.theapache64.gpm.di.modules.TransactionModule -import com.theapache64.gpm.di.modules.ViewModelModule import dagger.Component import java.io.File -import com.theapache64.gpm.di.GpmJsonFile -import com.theapache64.gpm.di.GradleFile import javax.inject.Singleton @Singleton @Component( - modules = [ViewModelModule::class, GradleModule::class, TransactionModule::class] + modules = [GradleModule::class, TransactionModule::class] ) interface UninstallComponent { fun inject(uninstall: Uninstall) diff --git a/src/main/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/UninstallViewModel.kt b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/UninstallViewModel.kt index 37e1466..fb56dd1 100644 --- a/src/main/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/UninstallViewModel.kt +++ b/src/main/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/UninstallViewModel.kt @@ -29,9 +29,8 @@ class UninstallViewModel @Inject constructor( for (depType in depTypes) { - command.onBeforeDepRemove(depType, depName) + val installedDeps = tm.getInstalled(depType.key, depName) - println("Size is ${installedDeps.size}") if (installedDeps.isEmpty()) { command.onNoDepInstalled(depType, depName) @@ -51,6 +50,7 @@ class UninstallViewModel @Inject constructor( } gradleManager.removeDep(depToRemove) + command.onAfterDepRemove(depType, depName) } return RESULT_DEP_UNINSTALLED diff --git a/src/main/kotlin/com/theapache64/gpm/core/TransactionManager.kt b/src/main/kotlin/com/theapache64/gpm/core/TransactionManager.kt index 652c613..8e23118 100644 --- a/src/main/kotlin/com/theapache64/gpm/core/TransactionManager.kt +++ b/src/main/kotlin/com/theapache64/gpm/core/TransactionManager.kt @@ -72,9 +72,9 @@ class TransactionManager @Inject constructor( gpmJsonFile.writeText(gpmFileDataJson) } - fun getInstalled(type: String, depName: String): List { + fun getInstalled(type: String?, depName: String): List { return getData()?.deps?.filter { - it.installedName == depName && it.type == type + it.installedName == depName && (type == null || it.type == type) } ?: listOf() } diff --git a/src/main/kotlin/com/theapache64/gpm/core/gm/GradleManager.kt b/src/main/kotlin/com/theapache64/gpm/core/gm/GradleManager.kt index 87c7e19..423592d 100644 --- a/src/main/kotlin/com/theapache64/gpm/core/gm/GradleManager.kt +++ b/src/main/kotlin/com/theapache64/gpm/core/gm/GradleManager.kt @@ -8,7 +8,6 @@ import com.theapache64.gpm.utils.StringUtils import com.theapache64.gpm.utils.insertAt import java.io.File import java.io.IOException -import java.lang.IllegalArgumentException /** * Currently supports 'implementation' and 'testImplementation' only. diff --git a/src/main/kotlin/com/theapache64/gpm/data/remote/gpm/GpmApiInterface.kt b/src/main/kotlin/com/theapache64/gpm/data/remote/gpm/GpmApiInterface.kt index 1bb7996..fa518dc 100644 --- a/src/main/kotlin/com/theapache64/gpm/data/remote/gpm/GpmApiInterface.kt +++ b/src/main/kotlin/com/theapache64/gpm/data/remote/gpm/GpmApiInterface.kt @@ -9,6 +9,6 @@ interface GpmApiInterface { @GET("registry/{name}.json") suspend fun getDependency( @Path("name") repoName: String - ): GpmDep + ): GpmDep? } \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/data/remote/gpm/models/GpmDep.kt b/src/main/kotlin/com/theapache64/gpm/data/remote/gpm/models/GpmDep.kt index 1e1b916..6872007 100644 --- a/src/main/kotlin/com/theapache64/gpm/data/remote/gpm/models/GpmDep.kt +++ b/src/main/kotlin/com/theapache64/gpm/data/remote/gpm/models/GpmDep.kt @@ -21,6 +21,6 @@ data class GpmDep( val description: String, @Transient var version: String? = null // OkHttp -){ +) { } \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/data/remote/maven/models/SearchResult.kt b/src/main/kotlin/com/theapache64/gpm/data/remote/maven/models/SearchResult.kt index 095c960..3899711 100644 --- a/src/main/kotlin/com/theapache64/gpm/data/remote/maven/models/SearchResult.kt +++ b/src/main/kotlin/com/theapache64/gpm/data/remote/maven/models/SearchResult.kt @@ -8,7 +8,7 @@ data class SearchResult( val groupId: String, val artifactId: String, val description: String, - val usage: Int, + val usage: Int?, val lastRelease: Date ) { val url = "https://mvnrepository.com/artifact/$groupId/$artifactId" diff --git a/src/main/kotlin/com/theapache64/gpm/data/repos/GpmRepo.kt b/src/main/kotlin/com/theapache64/gpm/data/repos/GpmRepo.kt index d77c3ec..1bab2a0 100644 --- a/src/main/kotlin/com/theapache64/gpm/data/repos/GpmRepo.kt +++ b/src/main/kotlin/com/theapache64/gpm/data/repos/GpmRepo.kt @@ -2,7 +2,6 @@ package com.theapache64.gpm.data.repos import com.theapache64.gpm.data.remote.gpm.GpmApiInterface import com.theapache64.gpm.data.remote.gpm.models.GpmDep -import retrofit2.HttpException import javax.inject.Inject import javax.inject.Singleton @@ -15,14 +14,20 @@ class GpmRepo @Inject constructor( /** * To get dependency from GPM github registry */ - suspend fun getDep(depName: String): GpmDep? = - try { + suspend fun getDep(depName: String): GpmDep? { + return try { val dep = gpmApiInterface.getDependency(depName) - val versionInfo = mavenRepo.getLatestVersion(dep.groupId, dep.artifactId) - require(versionInfo != null) { "Couldn't get version info for '$depName'" } - dep.version = versionInfo.version - dep - } catch (e: HttpException) { + if (dep == null) { + null + } else { + val versionInfo = mavenRepo.getLatestVersion(dep.groupId, dep.artifactId) + require(versionInfo != null) { "Couldn't get version info for '$depName'" } + dep.version = versionInfo.version + dep + } + } catch (e: Exception) { null } + } + } \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/data/repos/MavenRepo.kt b/src/main/kotlin/com/theapache64/gpm/data/repos/MavenRepo.kt index a5ace8f..40dfffd 100644 --- a/src/main/kotlin/com/theapache64/gpm/data/repos/MavenRepo.kt +++ b/src/main/kotlin/com/theapache64/gpm/data/repos/MavenRepo.kt @@ -15,11 +15,11 @@ class MavenRepo @Inject constructor( ) { companion object { private val SEARCH_RESULT_REGEX by lazy { - "
.+?(?\\d+?)\\. <\\/span>.+?)\\/(?.+?)\">(?.+?)<\\/a>.+?(?.+?)<\\/b> usages<\\/a>.+?im-description\">(?.+?).+?)<\\/div>".toRegex() + "
.+?(?\\d+?)\\. <\\/span>.+?)\\/(?.+?)\">(?.+?)<\\/a>.+?(?:(?.+?)<\\/b> usages<\\/a>.+?)?im-description\">(?.+?).+?)<\\/div".toRegex() } private val ARTIFACT_VERSION_REGEX by lazy { - ".+?vbtn release\">(?.+?)<\\/a><\\/td>.+?)\">(?.+?)<\\/a>".toRegex() + ".+?vbtn release\">(?.+?)<\\/a>.+?.+?)\">(?.+?)<\\/a>".toRegex() } //Apr 29, 2020 @@ -27,8 +27,8 @@ class MavenRepo @Inject constructor( } suspend fun search(depName: String): List { - - val htmlResp = mavenApiInterface.search(depName).removeNewLinesAndMultipleSpaces() + val searchHtml = mavenApiInterface.search(depName) + val htmlResp = searchHtml.removeNewLinesAndMultipleSpaces() val matches = SEARCH_RESULT_REGEX.findAll(htmlResp) val searchResults = mutableListOf() for (match in matches) { @@ -43,6 +43,13 @@ class MavenRepo @Inject constructor( lastRelease ) = match.destructured + val usage = usages.trim().replace(",", "").let { + if (it.isEmpty()) { + null + } else { + it.toInt() + } + } searchResults.add( SearchResult( number.trim().toInt(), @@ -50,7 +57,7 @@ class MavenRepo @Inject constructor( groupId.trim(), artifactId.trim(), StringEscapeUtils.unescapeHtml4(description.trim()), - usages.trim().replace(",", "").toInt(), + usage, SEARCH_RESULT_DATE_FORMAT.parse(lastRelease.trim()) ) ) diff --git a/src/main/kotlin/com/theapache64/gpm/di/modules/CommandModule.kt b/src/main/kotlin/com/theapache64/gpm/di/modules/CommandModule.kt index 8f7a2d8..80f0bc6 100644 --- a/src/main/kotlin/com/theapache64/gpm/di/modules/CommandModule.kt +++ b/src/main/kotlin/com/theapache64/gpm/di/modules/CommandModule.kt @@ -1,16 +1,16 @@ package com.theapache64.gpm.di.modules -import com.theapache64.gpm.commands.Gpm +import com.theapache64.gpm.commands.gpm.Gpm import dagger.Module import dagger.Provides import javax.inject.Singleton @Module -class CommandModule { +class CommandModule(private val isFromTest: Boolean) { @Singleton @Provides fun provideGpm(): Gpm { - return Gpm() + return Gpm(isFromTest) } } \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/di/modules/GradleModule.kt b/src/main/kotlin/com/theapache64/gpm/di/modules/GradleModule.kt index 55477a0..7dc0f93 100644 --- a/src/main/kotlin/com/theapache64/gpm/di/modules/GradleModule.kt +++ b/src/main/kotlin/com/theapache64/gpm/di/modules/GradleModule.kt @@ -2,11 +2,10 @@ package com.theapache64.gpm.di.modules import com.theapache64.gpm.core.TransactionManager import com.theapache64.gpm.core.gm.GradleManager +import com.theapache64.gpm.di.GradleFile import dagger.Module import dagger.Provides import java.io.File -import com.theapache64.gpm.di.GpmJsonFile -import com.theapache64.gpm.di.GradleFile @Module(includes = [TransactionModule::class]) class GradleModule( diff --git a/src/main/kotlin/com/theapache64/gpm/di/modules/NetworkModule.kt b/src/main/kotlin/com/theapache64/gpm/di/modules/NetworkModule.kt index e92eed4..9ec647a 100644 --- a/src/main/kotlin/com/theapache64/gpm/di/modules/NetworkModule.kt +++ b/src/main/kotlin/com/theapache64/gpm/di/modules/NetworkModule.kt @@ -1,7 +1,6 @@ package com.theapache64.gpm.di.modules import com.squareup.moshi.Moshi -import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import com.theapache64.gpm.data.remote.gpm.GpmApiInterface import com.theapache64.gpm.data.remote.maven.MavenApiInterface import dagger.Module @@ -19,6 +18,7 @@ class NetworkModule { return Retrofit.Builder() } + @Singleton @Provides fun provideGpmApiInterface(retrofitBuilder: Retrofit.Builder, moshi: Moshi): GpmApiInterface { return retrofitBuilder diff --git a/src/main/kotlin/com/theapache64/gpm/di/modules/TransactionModule.kt b/src/main/kotlin/com/theapache64/gpm/di/modules/TransactionModule.kt index a687fdd..9812049 100644 --- a/src/main/kotlin/com/theapache64/gpm/di/modules/TransactionModule.kt +++ b/src/main/kotlin/com/theapache64/gpm/di/modules/TransactionModule.kt @@ -2,11 +2,10 @@ package com.theapache64.gpm.di.modules import com.squareup.moshi.Moshi import com.theapache64.gpm.core.TransactionManager +import com.theapache64.gpm.di.GpmJsonFile import dagger.Module import dagger.Provides import java.io.File -import com.theapache64.gpm.di.GpmJsonFile -import com.theapache64.gpm.di.GradleFile @Module(includes = [MoshiModule::class]) class TransactionModule(private val isFromTest: Boolean) { diff --git a/src/main/kotlin/com/theapache64/gpm/di/modules/ViewModelModule.kt b/src/main/kotlin/com/theapache64/gpm/di/modules/ViewModelModule.kt deleted file mode 100644 index 619ae95..0000000 --- a/src/main/kotlin/com/theapache64/gpm/di/modules/ViewModelModule.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.theapache64.gpm.di.modules - -import com.theapache64.gpm.commands.subcommands.install.InstallViewModel -import com.theapache64.gpm.core.gm.GradleManager -import com.theapache64.gpm.data.repos.GpmRepo -import com.theapache64.gpm.data.repos.MavenRepo -import dagger.Module -import dagger.Provides - -@Module(includes = [GradleModule::class]) -class ViewModelModule { - - @Provides - fun provideInstallViewModel( - gpmRepo: GpmRepo, - mavenRepo: MavenRepo, - gradleManager: GradleManager - ): InstallViewModel { - return InstallViewModel( - gpmRepo, - mavenRepo, - gradleManager - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/gpm/utils/InputUtils.kt b/src/main/kotlin/com/theapache64/gpm/utils/InputUtils.kt index 1c05398..5059311 100644 --- a/src/main/kotlin/com/theapache64/gpm/utils/InputUtils.kt +++ b/src/main/kotlin/com/theapache64/gpm/utils/InputUtils.kt @@ -1,6 +1,5 @@ package com.theapache64.gpm.utils -import java.lang.NumberFormatException import java.util.* /** diff --git a/src/main/kotlin/com/theapache64/gpm/utils/Logger.kt b/src/main/kotlin/com/theapache64/gpm/utils/Logger.kt new file mode 100644 index 0000000..d17d815 --- /dev/null +++ b/src/main/kotlin/com/theapache64/gpm/utils/Logger.kt @@ -0,0 +1,2 @@ +package com.theapache64.gpm.utils + diff --git a/src/main/kotlin/com/theapache64/gpm/utils/StringUtils.kt b/src/main/kotlin/com/theapache64/gpm/utils/StringUtils.kt index 19a087f..b45acde 100644 --- a/src/main/kotlin/com/theapache64/gpm/utils/StringUtils.kt +++ b/src/main/kotlin/com/theapache64/gpm/utils/StringUtils.kt @@ -3,7 +3,7 @@ package com.theapache64.gpm.utils object StringUtils { - fun getClosingIndexOf(text: String, openingChar: Char, openingIndex: Int, closingChar : Char): Int { + fun getClosingIndexOf(text: String, openingChar: Char, openingIndex: Int, closingChar: Char): Int { var closePos: Int = openingIndex var counter = 1 while (counter > 0) { diff --git a/src/test/kotlin/com/theapache64/gpm/commands/subcommands/InstallTest.kt b/src/test/kotlin/com/theapache64/gpm/commands/subcommands/InstallTest.kt index 1b428f0..134f24e 100644 --- a/src/test/kotlin/com/theapache64/gpm/commands/subcommands/InstallTest.kt +++ b/src/test/kotlin/com/theapache64/gpm/commands/subcommands/InstallTest.kt @@ -1,45 +1,29 @@ package com.theapache64.gpm.commands.subcommands -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.whenever +import com.theapache64.gpm.commands.subcommands.install.DaggerInstallComponent import com.theapache64.gpm.commands.subcommands.install.Install +import com.theapache64.gpm.commands.subcommands.install.InstallComponent import com.theapache64.gpm.commands.subcommands.install.InstallViewModel -import com.theapache64.gpm.core.gm.GradleDep -import com.theapache64.gpm.data.remote.gpm.GpmApiInterface -import com.theapache64.gpm.data.remote.gpm.models.GpmDep -import com.theapache64.gpm.data.remote.maven.MavenApiInterface -import com.theapache64.gpm.di.components.DaggerInstallComponent -import com.theapache64.gpm.di.components.InstallComponent +import com.theapache64.gpm.di.modules.CommandModule import com.theapache64.gpm.di.modules.GradleModule import com.theapache64.gpm.di.modules.NetworkModule import com.theapache64.gpm.di.modules.TransactionModule import com.theapache64.gpm.runBlockingUnitTest import com.winterbe.expekt.should import it.cosenonjaviste.daggermock.DaggerMock -import it.cosenonjaviste.daggermock.InjectFromComponent import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test import picocli.CommandLine -import retrofit2.HttpException import java.io.File import java.io.PrintWriter import java.io.StringWriter -import com.theapache64.gpm.di.GpmJsonFile -import com.theapache64.gpm.di.GradleFile class InstallTest { - companion object { - private const val OKHTTP = "okhttp" - private const val RETROFIT = "retrofit" - private const val INVALID_REPO = "^%&^%some-invalid-repo&^%" - } private lateinit var installCmd: CommandLine - private val install = Install(true) @@ -51,6 +35,7 @@ class InstallTest { customizeBuilder { it.gradleModule(GradleModule(isFromTest = true)) .transactionModule(TransactionModule(true)) + .commandModule(CommandModule(true)) } set { tempBuildGradle = it.gradleFile() @@ -60,47 +45,9 @@ class InstallTest { } - private var fakeGpmApi: GpmApiInterface = mock() - private var fakeMavenApi: MavenApiInterface = mock() - @Before fun setUp() = runBlockingUnitTest { - whenever(fakeGpmApi.getDependency(OKHTTP)).thenReturn( - GpmDep( - "okhttp", - GradleDep.Type.IMP.key, - "https://square.github.io/okhttp/", - "jcenter", - "https://github.com/square/okhttp/", - "com.squareup.okhttp3", - "OkHttp", - "Square’s meticulous HTTP client for Java and Kotlin.\n", - "4.6.0" - ) - ) - - whenever(fakeGpmApi.getDependency(RETROFIT)).thenReturn( - GpmDep( - "retrofit", - GradleDep.Type.IMP.key, - "https://square.github.io/retrofit/", - "jcenter", - "https://github.com/square/retrofit/", - "com.squareup.retrofit2", - "Retrofit", - "Square’s meticulous type-safe HTTP client for Java and Kotlin.\n", - "2.8.1" - ) - ) - - whenever(fakeMavenApi.getArtifact(any(), any())).thenReturn( - File("src/test/resources/okhttp.mavenrepository.com.html").readText() - ) - - whenever(fakeMavenApi.search(INVALID_REPO)).thenReturn("") - whenever(fakeGpmApi.getDependency(INVALID_REPO)).thenThrow(HttpException::class.java) - this.installCmd = CommandLine(install) installCmd.out = PrintWriter(StringWriter()) } @@ -112,6 +59,14 @@ class InstallTest { tempBuildGradle.readText().should.contain("implementation 'com.squareup.okhttp3:okhttp:") } + @Test + fun `Install default another`() { + val exitCode = installCmd.execute("progressbar") + exitCode.should.equal(InstallViewModel.RESULT_DEP_INSTALLED) + /* + tempBuildGradle.readText().should.contain("implementation 'com.squareup.okhttp3:okhttp:")*/ + } + @Test fun `Install non existing registry`() { val exitCode = installCmd.execute("retrofit") @@ -142,7 +97,7 @@ class InstallTest { @Test fun `Install not existing library`() { - val exitCode = installCmd.execute(INVALID_REPO) + val exitCode = installCmd.execute("gdfhdfghdfghfdg") exitCode.should.equal(InstallViewModel.RESULT_REPO_NOT_FOUND) } diff --git a/src/test/kotlin/com/theapache64/gpm/commands/subcommands/docs/DocsTest.kt b/src/test/kotlin/com/theapache64/gpm/commands/subcommands/docs/DocsTest.kt new file mode 100644 index 0000000..621d8bc --- /dev/null +++ b/src/test/kotlin/com/theapache64/gpm/commands/subcommands/docs/DocsTest.kt @@ -0,0 +1,113 @@ +package com.theapache64.gpm.commands.subcommands.docs + +import com.theapache64.gpm.core.TransactionManager +import com.theapache64.gpm.core.gm.GradleDep +import com.theapache64.gpm.data.remote.gpm.models.GpmDep +import com.theapache64.gpm.di.modules.TransactionModule +import com.winterbe.expekt.should +import it.cosenonjaviste.daggermock.DaggerMock +import it.cosenonjaviste.daggermock.InjectFromComponent +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import picocli.CommandLine +import java.io.File + +class DocsTest { + + private lateinit var gpmJsonFile: File + private lateinit var docsCmd: CommandLine + private val docs = Docs(true) + + @InjectFromComponent + private lateinit var tm: TransactionManager + + @get:Rule + val daggerRule = DaggerMock.rule(TransactionModule(true)) { + set { + tm = it.transactionManager() + gpmJsonFile = it.gpmJsonFile() + } + } + + @Before + fun setUp() { + this.docsCmd = CommandLine(docs) + } + + @After + fun tearDown() { + gpmJsonFile.delete() + } + + @Test + fun `Opening docs for installed dependency`() { + // Adding fake transaction + tm.add( + "okhttp", + GradleDep.Type.IMP, + GpmDep( + "okhttp", + GradleDep.Type.IMP.key, + "https://square.github.io/okhttp/", + "jcenter", + "https://github.com/square/okhttp/", + "com.square.okhttp3", + "Material Colors", + "A networking library", + "1.0.0" + ) + ) + + val exitCode = docsCmd.execute("okhttp") + exitCode.should.equal(DocsViewModel.RESULT_DOC_FOUND) + + } + + @Test + fun `Opening docs for not installed dependency`() { + val exitCode = docsCmd.execute("not-installed-dep") + exitCode.should.equal(DocsViewModel.RESULT_NOT_FOUND) + } + + @Test + fun `Opening docs for dependency installed with similar name`() { + tm.add( + "okhttp", + GradleDep.Type.IMP, + GpmDep( + "okhttp", + GradleDep.Type.IMP.key, + "https://square.github.io/okhttp/", + "jcenter", + "https://github.com/square/okhttp/", + "com.square.okhttp3", + "Material Colors", + "A networking library", + "1.0.0" + ) + ) + + tm.add( + "okhttp", + GradleDep.Type.IMP, + GpmDep( + "some-other-lib", + GradleDep.Type.IMP.key, + "https://square.github.io/okhttp/", + "jcenter", + "https://github.com/square/okhttp/", + "some-other-lib", + "some-other-lib", + "Some lib", + "1.0.0" + ) + ) + + val exitCode = docsCmd.execute("okhttp") + exitCode.should.equal(DocsViewModel.RESULT_DOC_FOUND) + } + + +} \ No newline at end of file diff --git a/src/test/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/UninstallTest.kt b/src/test/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/UninstallTest.kt index 6ef5ce3..66c27e3 100644 --- a/src/test/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/UninstallTest.kt +++ b/src/test/kotlin/com/theapache64/gpm/commands/subcommands/uninstall/UninstallTest.kt @@ -3,8 +3,6 @@ package com.theapache64.gpm.commands.subcommands.uninstall import com.theapache64.gpm.core.gm.GradleDep import com.theapache64.gpm.core.gm.GradleManager import com.theapache64.gpm.data.remote.gpm.models.GpmDep -import com.theapache64.gpm.di.components.DaggerUninstallComponent -import com.theapache64.gpm.di.components.UninstallComponent import com.theapache64.gpm.di.modules.GradleModule import com.theapache64.gpm.di.modules.TransactionModule import com.winterbe.expekt.should diff --git a/src/test/kotlin/com/theapache64/gpm/core/gm/GradleDependencyTest.kt b/src/test/kotlin/com/theapache64/gpm/core/gm/GradleDependencyTest.kt index 0deb418..254d5d3 100644 --- a/src/test/kotlin/com/theapache64/gpm/core/gm/GradleDependencyTest.kt +++ b/src/test/kotlin/com/theapache64/gpm/core/gm/GradleDependencyTest.kt @@ -1,8 +1,5 @@ package com.theapache64.gpm.core.gm -import com.winterbe.expekt.should -import org.junit.Test - class GradleDependencyTest { diff --git a/src/test/kotlin/com/theapache64/gpm/data/repos/MavenRepoTest.kt b/src/test/kotlin/com/theapache64/gpm/data/repos/MavenRepoTest.kt index 0ff0d42..92e8877 100644 --- a/src/test/kotlin/com/theapache64/gpm/data/repos/MavenRepoTest.kt +++ b/src/test/kotlin/com/theapache64/gpm/data/repos/MavenRepoTest.kt @@ -46,9 +46,18 @@ class MavenRepoTest { info.repoUrl.should.equal("/repos/central") } + @Test + fun `Getting valid artifact information 2`() = runBlockingUnitTest { + val info = mavenRepo.getLatestVersion("me.tongfei", "progressbar") + info.should.not.`null` + info!!.version.should.not.empty + } + + @Test(expected = HttpException::class) fun `Getting invalid artifact information`() = runBlockingUnitTest { val info = mavenRepo.getLatestVersion("gfh", "jhj") info.should.`null` } + } \ No newline at end of file diff --git a/src/test/kotlin/com/theapache64/gpm/rules/MyDaggerMockRule.kt b/src/test/kotlin/com/theapache64/gpm/rules/MyDaggerMockRule.kt index c0b8bf5..f69701a 100644 --- a/src/test/kotlin/com/theapache64/gpm/rules/MyDaggerMockRule.kt +++ b/src/test/kotlin/com/theapache64/gpm/rules/MyDaggerMockRule.kt @@ -1,7 +1,9 @@ package com.theapache64.gpm.rules -import com.theapache64.gpm.di.components.DaggerInstallComponent -import com.theapache64.gpm.di.components.InstallComponent +import com.theapache64.gpm.commands.subcommands.install.DaggerInstallComponent +import com.theapache64.gpm.commands.subcommands.install.InstallComponent +import com.theapache64.gpm.di.modules.CommandModule + import com.theapache64.gpm.di.modules.GradleModule import com.theapache64.gpm.di.modules.NetworkModule import com.theapache64.gpm.di.modules.TransactionModule @@ -15,6 +17,7 @@ class MyDaggerMockRule : DaggerMockRule( init { customizeBuilder { it.transactionModule(TransactionModule(true)) + .commandModule(CommandModule(true)) } } } \ No newline at end of file diff --git a/src/test/kotlin/com/theapache64/gpm/utils/GradleManagerTest.kt b/src/test/kotlin/com/theapache64/gpm/utils/GradleManagerTest.kt index c647576..4ba1bde 100644 --- a/src/test/kotlin/com/theapache64/gpm/utils/GradleManagerTest.kt +++ b/src/test/kotlin/com/theapache64/gpm/utils/GradleManagerTest.kt @@ -1,11 +1,11 @@ package com.theapache64.gpm.utils +import com.theapache64.gpm.commands.subcommands.install.InstallComponent import com.theapache64.gpm.core.TransactionManager import com.theapache64.gpm.core.gm.GradleDep import com.theapache64.gpm.core.gm.GradleManager import com.theapache64.gpm.data.remote.gpm.models.GpmDep -import com.theapache64.gpm.di.GradleFile -import com.theapache64.gpm.di.components.InstallComponent +import com.theapache64.gpm.di.modules.CommandModule import com.theapache64.gpm.di.modules.GradleModule import com.theapache64.gpm.di.modules.TransactionModule import com.winterbe.expekt.should @@ -25,7 +25,8 @@ class GradleManagerTest { @get:Rule val daggerRule = DaggerMock.rule( GradleModule(true), - TransactionModule(true) + TransactionModule(true), + CommandModule(true) ) { set { gradleFile = it.gradleFile() diff --git a/src/test/resources/okhttp.mavenrepository.com.html b/src/test/resources/okhttp.mavenrepository.com.txt similarity index 100% rename from src/test/resources/okhttp.mavenrepository.com.html rename to src/test/resources/okhttp.mavenrepository.com.txt