Cli.kt (4195B)
1 /* 2 * This file is part of LibEuFin. 3 * Copyright (C) 2023-2025 Taler Systems S.A. 4 5 * LibEuFin is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Affero General Public License as 7 * published by the Free Software Foundation; either version 3, or 8 * (at your option) any later version. 9 10 * LibEuFin is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General 13 * Public License for more details. 14 15 * You should have received a copy of the GNU Affero General Public 16 * License along with LibEuFin; see the file COPYING. If not, see 17 * <http://www.gnu.org/licenses/> 18 */ 19 20 package tech.libeufin.common 21 22 import com.github.ajalt.clikt.core.CliktCommand 23 import com.github.ajalt.clikt.core.Context 24 import com.github.ajalt.clikt.core.ProgramResult 25 import com.github.ajalt.clikt.core.subcommands 26 import com.github.ajalt.clikt.parameters.arguments.argument 27 import com.github.ajalt.clikt.parameters.groups.OptionGroup 28 import com.github.ajalt.clikt.parameters.groups.provideDelegate 29 import com.github.ajalt.clikt.parameters.options.default 30 import com.github.ajalt.clikt.parameters.options.flag 31 import com.github.ajalt.clikt.parameters.options.option 32 import com.github.ajalt.clikt.parameters.types.enum 33 import com.github.ajalt.clikt.parameters.types.path 34 import kotlinx.coroutines.runBlocking 35 import org.slf4j.Logger 36 import org.slf4j.LoggerFactory 37 import org.slf4j.event.Level 38 39 private val logger: Logger = LoggerFactory.getLogger("libeufin-config") 40 41 abstract class TalerCmd(name: String? = null): CliktCommand(name) { 42 val config by option( 43 "--config", "-c", 44 help = "Specifies the configuration file", 45 metavar = "config_file" 46 ).path() 47 val log by option( 48 "--log", "-L", 49 help = "Configure logging to use LOGLEVEL" 50 ).enum<Level>().default(Level.INFO) 51 52 fun cliCmd(logger: Logger, lambda: suspend () -> Unit) { 53 // Set log level 54 TalerServiceProvider.currentLevel = log 55 // Run cli command catching all errors 56 try { 57 runBlocking { 58 lambda() 59 } 60 } catch (e: ProgramResult) { 61 throw e 62 } catch (e: TalerConfigError) { 63 e.fmtLog(logger) 64 throw ProgramResult(6) 65 } catch (e: Throwable) { 66 e.fmtLog(logger) 67 throw ProgramResult(1) 68 } 69 } 70 } 71 72 class CliConfigCmd(configSource: ConfigSource) : TalerCmd("config") { 73 init { 74 subcommands(CliConfigGet(configSource), CliConfigDump(configSource), CliConfigPathsub(configSource)) 75 } 76 77 override fun help(context: Context) = "Inspect or change the configuration" 78 79 override fun run() = Unit 80 } 81 82 private class CliConfigGet(private val configSource: ConfigSource) : TalerCmd("get") { 83 override fun help(context: Context) = "Lookup config value" 84 85 private val isPath by option( 86 "--filename", "-f", 87 help = "Interpret value as path with dollar-expansion" 88 ).flag() 89 private val section by argument() 90 private val option by argument() 91 92 override fun run() = cliCmd(logger) { 93 val config = configSource.fromFile(config) 94 val sect = config.section(section) 95 if (isPath) { 96 println(sect.path(option).require()) 97 } else { 98 println(sect.string(option).require()) 99 } 100 } 101 } 102 103 104 105 private class CliConfigPathsub(private val configSource: ConfigSource) : TalerCmd("pathsub") { 106 override fun help(context: Context) = "Substitute variables in a path" 107 108 private val pathExpr by argument() 109 110 override fun run() = cliCmd(logger) { 111 val config = configSource.fromFile(config) 112 println(config.pathsub(pathExpr)) 113 } 114 } 115 116 private class CliConfigDump(private val configSource: ConfigSource) : TalerCmd("dump") { 117 override fun help(context: Context) = "Dump the configuration" 118 119 override fun run() = cliCmd(logger) { 120 val config = configSource.fromFile(config) 121 println("# install path: ${configSource.installPath()}") 122 println(config.stringify()) 123 } 124 }