spring-projects / spring-cli Goto Github PK
View Code? Open in Web Editor NEWA CLI focused on developer productivity
License: Apache License 2.0
A CLI focused on developer productivity
License: Apache License 2.0
When using the catalog
spring catalog add gs https://github.com/rd-1-2022/spring-gs-catalog
and executing
spring:>boot new --from graphql --name demo
Using project name demo
Using package name com.example
Cloning project from https://github.com/rd-1-2022/rpt-spring-graphql
Refactoring to package name com.example
Project demo created in directory demo
The project is not correctly refactored from the com.example.graphql
package name which is what is contained in the graphql repository here - https://github.com/rd-1-2022/rpt-spring-graphql
There is still the three part package directory structure, yet import statements have been changed to two parts inside class files.
package com.example.graphql.service;
import com.example.model.Coffee;
import com.example.model.Size;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
@Service
public class CoffeeService {
The issue is that
import com.example.model.Coffee;
import com.example.model.Size;
don't exist.
Now there is no safeguard for adding a Java 17 project to a Java 11 project. The pom file ends up with both java versions being set as properties and the issue is only exposed when trying to build the project. Should pro-actively check Java version numbers and also in the future if it is a maven vs. gradle build.
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
- <java.version>1.8</java.version>
+ <java.version>17</java.version>
<spring-cloud.version>2021.0.0</spring-cloud.version>
</properties>
A centrally controlled list of catalogs and project can be browsed after installation of the CLI. The location to look for these lists can be customized, but there are default values to get users started with the CLI.
The current command names would introduce too much overlap, project catalog add
and project add
are confusing. Restructure to the following
Catalog project Commands
catalog project add: Add a project catalog
catalog project list available: List project catalogs that are available to add
catalog project list installed: List locally installed project catalogs
catalog project remove: Remove a project catalog
Project Commands
project add: Add a project
project list: List projects available to use
project remove: Remove project
Catalog Command Commands
catalog command add: Add a command catalog
catalog command list available: List command catalogs that are available to add
catalog command list installed: List locally installed command catalogs
catalog command remove: Remove a command catalog
Command Commands
command add: Add a user-defined command
command remove: Delete a user-defined command
command new: Create a new user-defined command
See https://rustup.rs/ , notably the .exe installer for windows
Adding commands to ${user.dir}/.spring.commands
instead of the project directory is a requested features and also one that is available in hygen.
If a command is also in the project directory as well as the global shared directory, the project directory takes priority.
Fatal error: org.graalvm.compiler.debug.GraalError: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of org.apache.commons.logging.impl.SLF4JLocationAwareLog are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=org.apache.commons.logging.impl.SLF4JLocationAwareLog.
at com.oracle.graal.pointsto.util.AnalysisFuture.setException(AnalysisFuture.java:49)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:269)
at com.oracle.graal.pointsto.util.AnalysisFuture.ensureDone(AnalysisFuture.java:63)
at com.oracle.graal.pointsto.heap.ImageHeapScanner.lambda$postTask$9(ImageHeapScanner.java:611)
at com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:193)
at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:177)
at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of org.apache.commons.logging.impl.SLF4JLocationAwareLog are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=org.apache.commons.logging.impl.SLF4JLocationAwareLog.
at com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.checkImageHeapInstance(ClassInitializationFeature.java:135)
------------------------------------------------------------------------------------------------------------------------
1.7s (11.6% of total time) in 23 GCs | Peak RSS: 1.91GB | CPU load: 7.29
========================================================================================================================
Failed generating 'spring-up' after 14.0s.
at com.oracle.graal.pointsto.meta.AnalysisUniverse.replaceObject(AnalysisUniverse.java:582)
at com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.replaceObject(AnalysisConstantReflectionProvider.java:257)
at com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.interceptValue(AnalysisConstantReflectionProvider.java:228)
at com.oracle.svm.hosted.heap.SVMImageHeapScanner.transformFieldValue(SVMImageHeapScanner.java:126)
at com.oracle.graal.pointsto.heap.ImageHeapScanner.onFieldValueReachable(ImageHeapScanner.java:331)
at com.oracle.graal.pointsto.heap.ImageHeapScanner.lambda$createImageHeapObject$3(ImageHeapScanner.java:272)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
... 10 more
This same error happens if logback.xml
is in classpath but we don't have it. I looked dependencies and rewrite-maven
has org.slf4j:jcl-over-slf4j
which enables this failure in a same way than logback.xml
.
+--- org.openrewrite:rewrite-maven -> 7.20.0-SNAPSHOT
| +--- guru.nidi:graphviz-java:0.18.1
| | +--- org.webjars.npm:viz.js-graphviz-java:2.1.3
| | +--- guru.nidi.com.kitfox:svgSalamander:1.1.3
| | +--- net.arnx:nashorn-promise:0.1.1
| | +--- org.apache.commons:commons-exec:1.3
| | +--- com.google.code.findbugs:jsr305:3.0.2
| | +--- org.slf4j:jcl-over-slf4j:1.7.30 -> 1.7.36
Tried it and excluding it makes graal happy again:
dependency("org.openrewrite:rewrite-maven:${openrewriteVersion}") {
exclude 'org.slf4j:jcl-over-slf4j'
}
Now they are randomly printed, most often out of sequence, under the heading 'user defined commands'. This should be more structured.
for M1
alphabetical sorting is ok, for M2
define a higher level grouping structure.
If for any reason command-defaults.yml
is empty or any other reason for parsing errors things fail. We need to make sure we're able to continue for reasons which we can handle.
$ java -jar build/libs/spring-cli-0.0.1-SNAPSHOT.jar config list
Unable to read from path /home/jvalkealahti/.config/springcli/command-defaults.yml
java.lang.RuntimeException: Unable to read from path /home/jvalkealahti/.config/springcli/command-defaults.yml
at org.springframework.cli.support.configfile.YamlConfigFile.read(YamlConfigFile.java:46)
at org.springframework.cli.support.configfile.UserConfig.getConfig(UserConfig.java:60)
at org.springframework.cli.support.SpringCliUserConfig.getCommandDefaults(SpringCliUserConfig.java:188)
at org.springframework.cli.command.ConfigCommands.configList(ConfigCommands.java:117)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.shell.command.invocation.InvocableShellMethod.doInvoke(InvocableShellMethod.java:308)
at org.springframework.shell.command.invocation.InvocableShellMethod.invoke(InvocableShellMethod.java:233)
at org.springframework.shell.command.CommandExecution$DefaultCommandExecution.evaluate(CommandExecution.java:151)
at org.springframework.shell.Shell.evaluate(Shell.java:205)
at org.springframework.shell.Shell.run(Shell.java:137)
at org.springframework.shell.jline.NonInteractiveShellRunner.run(NonInteractiveShellRunner.java:104)
at org.springframework.shell.DefaultShellApplicationRunner.run(DefaultShellApplicationRunner.java:65)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:762)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:752)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
at org.springframework.cli.SpringCliApplication.main(SpringCliApplication.java:30)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65)
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input
at [Source: (DataInputStream); line: 1, column: 1]
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4765)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4667)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3666)
at org.springframework.cli.support.configfile.YamlConfigFile.read(YamlConfigFile.java:44)
... 28 more
This allows for the repo to be cloned 'as is' and not force a change of package name.
tbd
There was a report of them not working and I do not think there is a specific test for that functionality
Instead of using start.spring.io
, make this configurable on a user settings level.
Frontmatter should have conditional execution based on
Add error handler that prints the exception message and logs the stacktrace to a temp file.
When executing config commands there is an error with native image.
$ spring-cli config list
Unable to read from path /home/jvalkealahti/.config/springcli/command-defaults.yml
java.lang.RuntimeException: Unable to read from path /home/jvalkealahti/.config/springcli/command-defaults.yml
at org.springframework.cli.support.configfile.YamlConfigFile.read(YamlConfigFile.java:46)
at org.springframework.cli.support.configfile.UserConfig.getConfig(UserConfig.java:60)
at org.springframework.cli.support.SpringCliUserConfig.getCommandDefaults(SpringCliUserConfig.java:188)
at org.springframework.cli.command.ConfigCommands.configList(ConfigCommands.java:117)
at java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.shell.command.invocation.InvocableShellMethod.doInvoke(InvocableShellMethod.java:308)
at org.springframework.shell.command.invocation.InvocableShellMethod.invoke(InvocableShellMethod.java:233)
at org.springframework.shell.command.CommandExecution$DefaultCommandExecution.evaluate(CommandExecution.java:151)
at org.springframework.shell.Shell.evaluate(Shell.java:205)
at org.springframework.shell.Shell.run(Shell.java:137)
at org.springframework.shell.jline.NonInteractiveShellRunner.run(NonInteractiveShellRunner.java:104)
at org.springframework.shell.DefaultShellApplicationRunner.run(DefaultShellApplicationRunner.java:65)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:762)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:752)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
at org.springframework.cli.SpringCliApplication.main(SpringCliApplication.java:30)
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.springframework.cli.support.SpringCliUserConfig$CommandDefaults` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (DataInputStream); line: 2, column: 1]
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1904)
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1349)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1415)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:351)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:184)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3666)
at org.springframework.cli.support.configfile.YamlConfigFile.read(YamlConfigFile.java:44)
... 17 more
Initial project with basic features.
Error is:
2022-12-02T08:32:40.988Z ERROR 30771 --- [main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'projectCatalogInitializer': Unable to read from path /home/jvalkealahti/.config/springcli/project-catalogs.yml
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1751) ~[spring:6.0.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[spring:6.0.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring:6.0.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring:6.0.2]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring:6.0.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring:6.0.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring:6.0.2]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:961) ~[spring:6.0.2]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:915) ~[spring:6.0.2]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[spring:6.0.2]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring:3.0.0]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[spring:3.0.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring:3.0.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring:3.0.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[spring:3.0.0]
at org.springframework.cli.SpringCliApplication.main(SpringCliApplication.java:30) ~[spring:na]
Caused by: java.lang.RuntimeException: Unable to read from path /home/jvalkealahti/.config/springcli/project-catalogs.yml
at org.springframework.cli.support.configfile.YamlConfigFile.read(YamlConfigFile.java:48) ~[na:na]
at org.springframework.cli.support.configfile.UserConfig.getConfig(UserConfig.java:60) ~[na:na]
at org.springframework.cli.config.SpringCliUserConfig.getProjectCatalogs(SpringCliUserConfig.java:163) ~[spring:na]
at org.springframework.cli.config.ProjectCatalogInitializer.afterPropertiesSet(ProjectCatalogInitializer.java:45) ~[spring:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1797) ~[spring:6.0.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1747) ~[spring:6.0.2]
... 15 common frames omitted
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input
at [Source: (DataInputStream); line: 1, column: 1]
at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4821) ~[spring:2.14.1]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4723) ~[spring:2.14.1]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3714) ~[spring:2.14.1]
at org.springframework.cli.support.configfile.YamlConfigFile.read(YamlConfigFile.java:46) ~[na:na]
... 20 common frames omitted
We can't error at startup i.e. you have something stale or whatever is a reason.
Support would be similar to rust's cargo command to generate a new app.
importing the user defined hello new
command lets you hit tab multiple times for the greeting
argument
hello new --greeting --greeting --greeting --greeting
The default catalog are projects derived from popular getting started guides. There are some projects, e.g. graphql, native, that do not have getting started guide but can be included.
The url/name for the default catalog
spring catalog add gs https://github.com/rd-1-2022/spring-gs-catalog
Allow the user to override the default by setting the property spring.cli.project.catalog.default-url
and spring.cli.project.catalog.default-name
Mercurial
bitbucket
That was a hack before using Handlebar's helper library
Npm module is wip in https://github.com/spring-projects/spring-shell/tree/main/e2e/spring-shell-e2e so we can use it directly from there until at some point it's published to npmjs.
glibc issues arise when using shared libs across various linux/ubuntu distros.
This should be done to be consistent with usage is other commands, from
can be a name (translated to a url) or a url.
Check docs to look for usage.
Test for failure to merge a Java 17 project into a Java 8 project and so on.
User should be able to login into gitlab instance in a same way github auth login
works. It should just be host and pasting a token so that user level settings would have token mapping to hosts.
Metadata from start.spring.io
is giving defaults for choices which at this moment are i.e. maven
and jdk11
. Flow just picks first one:
spring:>initializr new
? Path /tmp/up/test1
? Project [Use arrows to move], type to filter
> Gradle Project
Maven Project
? Java [Use arrows to move], type to filter
> 8
11
17
18
It'd be nice if we can auto select default choices so that user can just press enter.
This is important to help users see what projects can be combined.
Add ability to exec a shell command via front matter declaration
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.