Git Product home page Git Product logo

spring-cli's Introduction

A CLI focused on developer productivity

Build

Note
Use JDK17

Normal build without native:

./gradlew clean build

Which you can then run with:

java -jar build/libs/spring-cli-0.0.1-SNAPSHOT.jar

For native build:

./gradlew clean build nativeCompile -PspringCliNative=true
Note
You need to have GRAALVM_HOME pointing to your graal installation

Which you can then run with:

build/native/nativeCompile/spring
Tip
There is a CI workflow which builds native binaries for linux, macos and windows. Published artifacts in CI workflow will get removed daily so take it from a latest run which is scheduled nightly.

Code Formatting

This project uses Spring Javaformat and is enabled by default.

Run individual tasks:

./gradlew checkFormat
./gradlew checkstyleMain
./gradlew checkstyleTest
./gradlew format

You can temporarily disable checks by setting property springCliChecks to false:

./gradlew build -PspringCliChecks=false

Building Documentation

./gradlew antora

Output is in ./docs/build/site/index.html

For more information on the build see README in the docs-build branch.

Shell Completion

Shell completion for bash can be generated with completion bash command:

$ source <(spring completion bash)

spring-cli's People

Contributors

boykoalex avatar fabapp2 avatar jvalkeal avatar mackey0225 avatar markpollack avatar msaifasif avatar olegz avatar s50600822 avatar zakimak9 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring-cli's Issues

Empty command-defaults.yml fails with config commands

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

Add conditional execution

Frontmatter should have conditional execution based on

  • project dependencies being present or not
  • platform (unix, mac, windows)

Auth with gitlab

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.

Better grouping of user defined commands

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.

Native fails with SLF4JLocationAwareLog

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'
}

Pre-merge check for Java versions

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>

Missing hints in config commands for jackson

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

Local config for project-catalogs.yml fails

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.

Add support to add commands in a shared directory

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.

Add support for listing available catalogs and projects

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

Issue refactoring to `com.example` from `com.example.graphql

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.

Load a project catalog by default, allow user to override.

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

initializr new flow should pick defaults

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.

Demos

This is a demo of using initializr new to create a project from start.spring.io

initializr demo

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.