Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ See our [book](https://lca-as-code.com/book) to learn more about the language.

From the source
```bash
git checkout v1.8.1
git checkout v2.0.0
./gradlew :cli:installDist
alias lcaac=$GIT_ROOT/cli/build/install/lcaac/bin/lcaac
lcaac version
Expand Down
2 changes: 2 additions & 0 deletions cli/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ dependencies {
implementation("org.apache.commons:commons-csv:1.10.0")

implementation("com.charleskorn.kaml:kaml:0.59.0")

implementation("org.apache.commons:commons-compress:1.28.0")
}

tasks.build {
Expand Down
62 changes: 15 additions & 47 deletions cli/src/main/kotlin/ch/kleis/lcaac/cli/cmd/AssessCommand.kt
Original file line number Diff line number Diff line change
@@ -1,73 +1,41 @@
package ch.kleis.lcaac.cli.cmd

import ch.kleis.lcaac.cli.csv.assess.AssessCsvProcessor
import ch.kleis.lcaac.cli.csv.CsvRequest
import ch.kleis.lcaac.cli.csv.CsvRequestReader
import ch.kleis.lcaac.cli.csv.assess.AssessCsvProcessor
import ch.kleis.lcaac.cli.csv.assess.AssessCsvResultWriter
import ch.kleis.lcaac.core.config.LcaacConfig
import ch.kleis.lcaac.core.math.basic.BasicOperations
import ch.kleis.lcaac.grammar.Loader
import ch.kleis.lcaac.grammar.LoaderOption
import com.charleskorn.kaml.decodeFromStream
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.help
import com.github.ajalt.clikt.parameters.options.associate
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.help
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.types.file
import java.io.File

const val assessCommandName = "assess"

@Suppress("MemberVisibilityCanBePrivate", "DuplicatedCode")
class AssessCommand : CliktCommand(name = "assess", help = "Returns the unitary impacts of a process in CSV format") {
class AssessCommand : CliktCommand(name = assessCommandName, help = "Returns the unitary impacts of a process in CSV format") {
val name: String by argument().help("Process name")
val labels: Map<String, String> by option("-l", "--label")
.help(
"""
Specify a process label as a key value pair.
Example: lcaac assess <process name> -l model="ABC" -l geo="FR".
""".trimIndent())
.associate()
private val getProjectPath = option("-p", "--project").file()
.default(File(defaultLcaacFilename))
.help("Path to project folder or yaml file.")
val projectPath: File by getProjectPath

val file: File? by option("-f", "--file").file(canBeDir = false)
.help("""
CSV file with parameter values.
Example: `lcaac assess <process name> -f params.csv`.
""".trimIndent())
val arguments: Map<String, String> by option("-D", "--parameter")
.help(
"""
Override parameter value as a key value pair.
Example: `lcaac assess <process name> -D x="12 kg" -D geo="UK" -f params.csv`.
""".trimIndent())
.associate()
val globals: Map<String, String> by option("-G", "--global")
.help(
"""
Override global variable as a key value pair.
Example: `lcaac assess <process name> -G x="12 kg"`.
""".trimIndent()
).associate()
val configFile: File by configFileOption()
val source: File by sourceOption()
val file: File? by fileOption(assessCommandName)
val labels: Map<String, String> by labelsOption(assessCommandName)
val arguments: Map<String, String> by argumentsOption(assessCommandName)
val globals: Map<String, String> by globalsOption(assessCommandName)

override fun run() {
val (workingDirectory, lcaacConfigFile) = parseProjectPath(projectPath)
val yamlConfig = if (lcaacConfigFile.exists()) projectPath.inputStream().use {
yaml.decodeFromStream(LcaacConfig.serializer(), it)
}
else LcaacConfig()
val sourceDirectory = parseSource(source)
val projectDirectory = configFile.parentFile
val yamlConfig = parseLcaacConfig(configFile)

val files = lcaFiles(workingDirectory)
val files = lcaFiles(sourceDirectory)
val symbolTable = Loader(
ops = BasicOperations,
overriddenGlobals = dataExpressionMap(BasicOperations, globals),
).load(files, listOf(LoaderOption.WITH_PRELUDE))

val processor = AssessCsvProcessor(yamlConfig, symbolTable, workingDirectory.path)
val processor = AssessCsvProcessor(yamlConfig, symbolTable, projectDirectory.path)
val iterator = loadRequests()
val writer = AssessCsvResultWriter()
var first = true
Expand Down
58 changes: 58 additions & 0 deletions cli/src/main/kotlin/ch/kleis/lcaac/cli/cmd/SharedOptions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package ch.kleis.lcaac.cli.cmd

import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.options.associate
import com.github.ajalt.clikt.parameters.options.convert
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.help
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.types.file
import java.io.File
import kotlin.io.path.Path

fun CliktCommand.configFileOption() = option("-c", "--config", help = "Path to LCAAC config file")
.file(canBeDir = false)
.convert { it.absoluteFile } // allow to retrieve its parent file when a relative path is given (useful for finding the project directory)
.default(File("./$defaultLcaacFilename"))
.help("""
Path to LCAAC config file. Defaults to 'lcaac.yaml'
The location of the config file is the project directory. Defaults to current working directory.
""".trimIndent())

fun CliktCommand.sourceOption() = option("-s", "--source", help = "Path to LCA source folder or zip/tar.gz/tgz file")
.file()
.default(Path(".").toFile())
.help("Path to LCAAC source folder or zip/tar.gz/tgz file. Defaults to current working directory.")

fun CliktCommand.fileOption(commandName: String) = option("-f", "--file")
.file(canBeDir = false)
.help("""
CSV file with parameter values.
Example: `lcaac $commandName <process name> -f params.csv`
""".trimIndent()
)

fun CliktCommand.labelsOption(commandName: String) = option("-l", "--label")
.help("""
Specify a process label as a key value pair.
Example: lcaac $commandName <process name> -l model="ABC" -l geo="FR".
""".trimIndent())
.associate()

fun CliktCommand.argumentsOption(commandName: String) = option("-D", "--parameter")
.help(
"""
Override parameter value as a key value pair.
Example: `lcaac $commandName <process name> -D x="12 kg" -D geo="UK" -f params.csv`.
""".trimIndent())
.associate()

fun CliktCommand.globalsOption(commandName: String) = option("-G", "--global")
.help(
"""
Override global variable as a key value pair.
Example: `lcaac $commandName <process name> -G x="12 kg"`.
""".trimIndent()
).associate()


41 changes: 12 additions & 29 deletions cli/src/main/kotlin/ch/kleis/lcaac/cli/cmd/TestCommand.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package ch.kleis.lcaac.cli.cmd

import ch.kleis.lcaac.core.config.LcaacConfig
import ch.kleis.lcaac.core.datasource.ConnectorFactory
import ch.kleis.lcaac.core.datasource.DefaultDataSourceOperations
import ch.kleis.lcaac.core.datasource.csv.CsvConnectorBuilder
Expand All @@ -13,62 +12,46 @@ import ch.kleis.lcaac.grammar.CoreTestMapper
import ch.kleis.lcaac.grammar.Loader
import ch.kleis.lcaac.grammar.LoaderOption
import ch.kleis.lcaac.grammar.parser.LcaLangParser
import com.charleskorn.kaml.decodeFromStream
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.ProgramResult
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.default
import com.github.ajalt.clikt.parameters.arguments.help
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.help
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.types.file
import java.io.File

private const val greenTick = "\u2705"
private const val redCross = "\u274C"

const val testCommandName = "test"

@Suppress("MemberVisibilityCanBePrivate", "DuplicatedCode")
class TestCommand : CliktCommand(name = "test", help = "Run specified tests") {
class TestCommand : CliktCommand(name = testCommandName, help = "Run specified tests") {
val name: String by argument().help("Process name").default("")

private val getProjectPath = option("-p", "--project").file()
.default(File(defaultLcaacFilename))
.help("Path to project folder or yaml file.")
val projectPath: File by getProjectPath

val file: File? by option("-f", "--file").file(canBeDir = false)
.help("""
CSV file with parameter values.
Example: `lcaac assess <process name> -f params.csv`.
""".trimIndent())
val configFile: File by configFileOption()
val source: File by sourceOption()
val file: File? by fileOption(testCommandName)
val showSuccess: Boolean by option("--show-success").flag(default = false).help("Show successful assertions")

override fun run() {
val (workingDirectory, lcaacConfigFile) = parseProjectPath(projectPath)

val yamlConfig = if (lcaacConfigFile.exists()) projectPath.inputStream().use {
yaml.decodeFromStream(LcaacConfig.serializer(), it)
}
else LcaacConfig()
val sourceDirectory = parseSource(source)
val projectDirectory = configFile.parentFile
val yamlConfig = parseLcaacConfig(configFile)

val ops = BasicOperations
val files = lcaFiles(workingDirectory)
val files = lcaFiles(sourceDirectory)
val symbolTable = Loader(ops).load(files, listOf(LoaderOption.WITH_PRELUDE))

val factory = ConnectorFactory(
workingDirectory.path,
projectDirectory.path,
yamlConfig,
ops,
symbolTable,
listOf(CsvConnectorBuilder())
)
val sourceOps = DefaultDataSourceOperations(
ops,
yamlConfig,
factory.buildConnectors(),
)
val sourceOps = DefaultDataSourceOperations(ops,yamlConfig, factory.buildConnectors())

val mapper = CoreTestMapper()
val cases = files
Expand Down
56 changes: 15 additions & 41 deletions cli/src/main/kotlin/ch/kleis/lcaac/cli/cmd/TraceCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ import ch.kleis.lcaac.cli.csv.CsvRequest
import ch.kleis.lcaac.cli.csv.CsvRequestReader
import ch.kleis.lcaac.cli.csv.trace.TraceCsvProcessor
import ch.kleis.lcaac.cli.csv.trace.TraceCsvResultWriter
import ch.kleis.lcaac.core.config.LcaacConfig
import ch.kleis.lcaac.core.math.basic.BasicOperations
import ch.kleis.lcaac.grammar.Loader
import ch.kleis.lcaac.grammar.LoaderOption
import com.charleskorn.kaml.decodeFromStream
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.help
Expand All @@ -18,56 +16,32 @@ import com.github.ajalt.clikt.parameters.options.help
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.types.file
import java.io.File
import kotlin.io.path.Path

const val traceCommandName = "trace"

@Suppress("MemberVisibilityCanBePrivate", "DuplicatedCode")
class TraceCommand : CliktCommand(name = "trace", help = "Trace the contributions") {
class TraceCommand : CliktCommand(name = traceCommandName, help = "Trace the contributions") {
val name: String by argument().help("Process name")
val labels: Map<String, String> by option("-l", "--label")
.help(
"""
Specify a process label as a key value pair.
Example: lcaac assess <process name> -l model="ABC" -l geo="FR".
""".trimIndent())
.associate()
private val getProjectPath = option("-p", "--project").file()
.default(File(defaultLcaacFilename))
.help("Path to project folder or yaml file.")
val projectPath: File by getProjectPath

val file: File? by option("-f", "--file").file(canBeDir = false)
.help("""
CSV file with parameter values.
Example: `lcaac trace <process name> -f params.csv`.
""".trimIndent())
val arguments: Map<String, String> by option("-D", "--parameter")
.help(
"""
Override parameter value as a key value pair.
Example: `lcaac assess <process name> -D x="12 kg" -D geo="UK" -f params.csv`.
""".trimIndent())
.associate()
val globals: Map<String, String> by option("-G", "--global")
.help(
"""
Override global variable as a key value pair.
Example: `lcaac assess <process name> -G x="12 kg"`.
""".trimIndent()
).associate()
val configFile: File by configFileOption()
val source: File by sourceOption()
val file: File? by fileOption(traceCommandName)
val labels: Map<String, String> by labelsOption(traceCommandName)
val arguments: Map<String, String> by argumentsOption(traceCommandName)
val globals: Map<String, String> by globalsOption(traceCommandName)

override fun run() {
val (workingDirectory, lcaacConfigFile) = parseProjectPath(projectPath)
val yamlConfig = if (lcaacConfigFile.exists()) projectPath.inputStream().use {
yaml.decodeFromStream(LcaacConfig.serializer(), it)
}
else LcaacConfig()
val sourceDirectory = parseSource(source)
val projectDirectory = configFile.parentFile
val yamlConfig = parseLcaacConfig(configFile)

val files = lcaFiles(workingDirectory)
val files = lcaFiles(sourceDirectory)
val symbolTable = Loader(
ops = BasicOperations,
overriddenGlobals = dataExpressionMap(BasicOperations, globals),
).load(files, listOf(LoaderOption.WITH_PRELUDE))

val processor = TraceCsvProcessor(yamlConfig, symbolTable, workingDirectory.path)
val processor = TraceCsvProcessor(yamlConfig, symbolTable, projectDirectory.path)
val iterator = loadRequests()
val writer = TraceCsvResultWriter()
var first = true
Expand Down
Loading