├── docs
├── settings.gradle
├── modules
│ └── ROOT
│ │ ├── pages
│ │ ├── ref
│ │ │ ├── project
│ │ │ │ ├── index.adoc
│ │ │ │ └── adding-to-existing-projects.adoc
│ │ │ ├── actionfile
│ │ │ │ └── index.adoc
│ │ │ ├── catalog
│ │ │ │ └── index.adoc
│ │ │ ├── index.adoc
│ │ │ ├── ai
│ │ │ │ ├── index.adoc
│ │ │ │ └── readme-command-guide.adoc
│ │ │ └── usercommand
│ │ │ │ └── index.adoc
│ │ ├── contributing-project-catalogs.adoc
│ │ ├── glossary.adoc
│ │ ├── howto
│ │ │ ├── index.adoc
│ │ │ └── create-application.adoc
│ │ ├── commands
│ │ │ ├── version.adoc
│ │ │ ├── role-list.adoc
│ │ │ ├── vars-new.adoc
│ │ │ ├── completion-zsh.adoc
│ │ │ ├── completion-bash.adoc
│ │ │ ├── role-add.adoc
│ │ │ ├── github-auth-login.adoc
│ │ │ ├── github-auth-logout.adoc
│ │ │ ├── script.adoc
│ │ │ ├── role-remove.adoc
│ │ │ ├── help.adoc
│ │ │ ├── project-remove.adoc
│ │ │ ├── history.adoc
│ │ │ ├── command-add.adoc
│ │ │ ├── role-get.adoc
│ │ │ ├── project-catalog-remove.adoc
│ │ │ ├── project-catalog-list.adoc
│ │ │ ├── project-list.adoc
│ │ │ ├── github-auth-status.adoc
│ │ │ ├── role-set.adoc
│ │ │ ├── project-catalog-available.adoc
│ │ │ ├── command-remove.adoc
│ │ │ ├── boot-add.adoc
│ │ │ ├── project-add.adoc
│ │ │ ├── project-catalog-add.adoc
│ │ │ ├── footers
│ │ │ │ └── boot-start-footer.adoc
│ │ │ ├── command-new.adoc
│ │ │ ├── guide-apply.adoc
│ │ │ ├── ai-add.adoc
│ │ │ ├── boot-new.adoc
│ │ │ └── boot-start.adoc
│ │ └── getting-started.adoc
│ │ ├── nav.adoc
│ │ └── nav-commands.adoc
├── help-commands-adoc.stg
├── antora.yml
├── local-antora-playbook.yml
├── antora-playbook.yml
└── help-command-adoc.stg
├── gradle.properties
├── e2e
└── spring-cli-e2e-tests
│ ├── .gitignore
│ ├── .prettierignore
│ ├── .prettierrc.json
│ ├── jest.config.js
│ ├── tsconfig.json
│ ├── src
│ └── utils.ts
│ └── package.json
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── src
├── jreleaser
│ ├── images
│ │ ├── spring-cli.ico
│ │ └── spring-cli.svg
│ └── templates
│ │ └── jlink
│ │ └── brew
│ │ └── formula-multi.rb.tpl
├── test
│ ├── resources
│ │ ├── command-scanner-tests
│ │ │ └── k8s-simple
│ │ │ │ ├── new
│ │ │ │ ├── hello.txt
│ │ │ │ └── command.yaml
│ │ │ │ └── new-services
│ │ │ │ └── command.yaml
│ │ ├── org
│ │ │ └── springframework
│ │ │ │ └── cli
│ │ │ │ ├── runtime
│ │ │ │ ├── command
│ │ │ │ │ ├── exec
│ │ │ │ │ │ ├── util
│ │ │ │ │ │ │ └── mkdir
│ │ │ │ │ │ │ │ └── mkdir-action.yml
│ │ │ │ │ │ ├── working
│ │ │ │ │ │ │ └── dir
│ │ │ │ │ │ │ │ └── ls-action.yml
│ │ │ │ │ │ ├── define
│ │ │ │ │ │ │ └── var
│ │ │ │ │ │ │ │ ├── 10-use-var.yml
│ │ │ │ │ │ │ │ ├── 00-define-var.yml
│ │ │ │ │ │ │ │ └── echo-command.txt
│ │ │ │ │ │ └── assert
│ │ │ │ │ │ │ └── json
│ │ │ │ │ │ │ ├── 02-provision-postgresql.yml
│ │ │ │ │ │ │ ├── 00-assert-cli-version.yml
│ │ │ │ │ │ │ ├── 01-assert-resource.yml
│ │ │ │ │ │ │ └── 03-conditional-strawman.yml
│ │ │ │ │ ├── inject
│ │ │ │ │ │ ├── myfile-before.txt
│ │ │ │ │ │ ├── myfile-before.txt.bak
│ │ │ │ │ │ ├── myfile-after.txt
│ │ │ │ │ │ ├── myfile-after.txt.bak
│ │ │ │ │ │ ├── myfile-after.txt.expected
│ │ │ │ │ │ ├── myfile-before.txt.expected
│ │ │ │ │ │ ├── after
│ │ │ │ │ │ │ └── text
│ │ │ │ │ │ │ │ └── action-inject-after.txt
│ │ │ │ │ │ └── before
│ │ │ │ │ │ │ └── text
│ │ │ │ │ │ │ └── action-inject-before.txt
│ │ │ │ │ └── manifest-full-deserialization.yaml
│ │ │ │ └── engine
│ │ │ │ │ └── actions
│ │ │ │ │ ├── ActionsFileReaderTests-vars-data.yaml
│ │ │ │ │ ├── ActionsFileReaderTests-actions.yaml
│ │ │ │ │ ├── ActionsFileReaderTests-actions-with-name.yaml
│ │ │ │ │ ├── ActionsFileReaderTests-bad-vars.yaml
│ │ │ │ │ ├── ActionsFileReaderTests-vars.yaml
│ │ │ │ │ └── ActionsFileReaderTests-inject-maven-deps.yaml
│ │ │ │ └── merger
│ │ │ │ ├── ai
│ │ │ │ └── OpenAiHandlerTests-request.md
│ │ │ │ └── pom-java-8.xml
│ │ ├── application-deser-test.yml
│ │ └── pom-existing-project.xml
│ └── java
│ │ └── org
│ │ └── springframework
│ │ └── cli
│ │ ├── SpringCliApplicationTests.java
│ │ ├── support
│ │ ├── configfile
│ │ │ └── UserConfigTests.java
│ │ └── IntegrationTestSupport.java
│ │ ├── runtime
│ │ ├── engine
│ │ │ └── spel
│ │ │ │ ├── MySpringAppConfig.java
│ │ │ │ ├── Greeter.java
│ │ │ │ ├── SimpleBeanResolver.java
│ │ │ │ └── Person.java
│ │ └── command
│ │ │ └── InjectTests.java
│ │ ├── CliTags.java
│ │ ├── testutil
│ │ └── TableAssertions.java
│ │ ├── command
│ │ └── SpecialCommandsTests.java
│ │ └── util
│ │ └── ClassNameExtractorTests.java
├── main
│ ├── resources
│ │ ├── org
│ │ │ └── springframework
│ │ │ │ └── cli
│ │ │ │ ├── commands
│ │ │ │ ├── hello.yml
│ │ │ │ └── command.yaml
│ │ │ │ └── merger
│ │ │ │ └── ai
│ │ │ │ ├── openai-user-name-heuristic-prompt.txt
│ │ │ │ ├── openai-user-rewrite-description-prompt.txt
│ │ │ │ ├── openai-system-rewrite-description-prompt.txt
│ │ │ │ ├── openai-user-ai-add-prompt.txt
│ │ │ │ ├── openai-system-name-heuristic-prompt.txt
│ │ │ │ └── openai-user-rewrite-info-fields.txt
│ │ ├── META-INF
│ │ │ └── native-image
│ │ │ │ ├── native-image.properties
│ │ │ │ └── resource-config.json
│ │ └── springcliapp.yml
│ └── java
│ │ └── org
│ │ └── springframework
│ │ └── cli
│ │ ├── util
│ │ ├── YmlMerger.java
│ │ ├── MavenBuildPluginReader.java
│ │ ├── MavenDependencyReader.java
│ │ ├── MavenRepositoryReader.java
│ │ ├── NamingUtils.java
│ │ ├── TerminalMessage.java
│ │ └── ClassNameExtractor.java
│ │ ├── merger
│ │ ├── ai
│ │ │ ├── service
│ │ │ │ ├── OpenAiService.java
│ │ │ │ └── DescriptionRewriteAiService.java
│ │ │ ├── ProjectArtifactType.java
│ │ │ ├── ProjectArtifactCreator.java
│ │ │ ├── ProjectDependency.java
│ │ │ ├── PromptRequest.java
│ │ │ ├── ProcessArtifactResult.java
│ │ │ ├── ProjectName.java
│ │ │ └── ProjectArtifact.java
│ │ └── AddImportRecipe.java
│ │ ├── runtime
│ │ ├── engine
│ │ │ ├── templating
│ │ │ │ └── TemplateEngine.java
│ │ │ ├── actions
│ │ │ │ ├── handlers
│ │ │ │ │ └── json
│ │ │ │ │ │ ├── IRegion.java
│ │ │ │ │ │ └── BadLocationException.java
│ │ │ │ ├── Var.java
│ │ │ │ ├── Options.java
│ │ │ │ ├── From.java
│ │ │ │ ├── ActionStatus.java
│ │ │ │ ├── InjectMavenDependency.java
│ │ │ │ ├── InjectMavenRepository.java
│ │ │ │ ├── InjectMavenBuildPlugin.java
│ │ │ │ ├── InjectMavenDependencyManagement.java
│ │ │ │ ├── ActionsFile.java
│ │ │ │ ├── ActionResult.java
│ │ │ │ └── Vars.java
│ │ │ └── model
│ │ │ │ ├── ModelPopulator.java
│ │ │ │ └── RootPackageModelPopulator.java
│ │ └── command
│ │ │ ├── CommandFileReader.java
│ │ │ └── CommandScanResults.java
│ │ ├── recipe
│ │ ├── RecipeCreationException.java
│ │ └── RecipeUtils.java
│ │ ├── initializr
│ │ └── model
│ │ │ ├── IdName.java
│ │ │ ├── Dependencies.java
│ │ │ ├── Name.java
│ │ │ ├── GroupId.java
│ │ │ ├── Version.java
│ │ │ ├── Dependency.java
│ │ │ ├── ArtifactId.java
│ │ │ ├── Description.java
│ │ │ ├── PackageName.java
│ │ │ ├── DependencyCategory.java
│ │ │ └── BootVersion.java
│ │ ├── SpringCliException.java
│ │ ├── git
│ │ └── SourceRepositoryService.java
│ │ ├── config
│ │ └── SpringCliPromptProvider.java
│ │ ├── support
│ │ └── configfile
│ │ │ └── ConfigFile.java
│ │ └── SpringCliApplication.java
└── checkstyle
│ └── checkstyle.xml
├── test-data
├── commands
│ ├── exec
│ │ └── util
│ │ │ └── mkdir
│ │ │ └── mkdir-action.yml
│ ├── inject
│ │ ├── after
│ │ │ └── inject
│ │ │ │ ├── inject-after.yaml
│ │ │ │ └── sample.txt
│ │ ├── before
│ │ │ └── inject
│ │ │ │ ├── inject-before.yaml
│ │ │ │ └── sample.txt
│ │ └── skip
│ │ │ └── inject
│ │ │ ├── sample.txt
│ │ │ └── inject-skip.yaml
│ ├── exec-redirect
│ │ └── working
│ │ │ └── dir
│ │ │ └── ls-action.yml
│ ├── exec-define
│ │ ├── varjsonpath
│ │ │ └── define
│ │ │ │ ├── 10-use-var.yml
│ │ │ │ ├── 00-define-var.yml
│ │ │ │ └── echo-command.txt
│ │ └── varoutput
│ │ │ └── define
│ │ │ └── 00-define-var.yml
│ ├── if
│ │ ├── vars
│ │ │ ├── notdefined
│ │ │ │ └── vars-notdefined.yml
│ │ │ └── define
│ │ │ │ └── vars-if.yml
│ │ └── run
│ │ │ └── define
│ │ │ ├── run-define.yml
│ │ │ └── echo-command.txt
│ ├── vars
│ │ └── vars
│ │ │ ├── iftrue
│ │ │ └── vars-if-data.yml
│ │ │ ├── iffalse
│ │ │ └── vars-if-data.yml
│ │ │ ├── data
│ │ │ └── vars-data.yml
│ │ │ ├── data-handlebars
│ │ │ └── vars-data.yml
│ │ │ └── define
│ │ │ ├── echo-command.txt
│ │ │ └── vars-define.yml
│ ├── generate
│ │ ├── hello
│ │ │ └── new
│ │ │ │ ├── generate.yaml
│ │ │ │ └── command.yaml
│ │ └── controller
│ │ │ └── new
│ │ │ ├── create-controller.yaml
│ │ │ ├── command.yaml
│ │ │ └── RestController.java
│ ├── inject-maven-repository
│ │ └── repository
│ │ │ ├── add
│ │ │ └── repository-add.yaml
│ │ │ └── add-using-var
│ │ │ └── repository-add-using-var.yaml
│ ├── inject-maven-dependency-mgmt
│ │ └── dependency
│ │ │ ├── add
│ │ │ └── dependency-add.yaml
│ │ │ └── add-using-var
│ │ │ └── dependency-add-using-var.yaml
│ ├── inject-maven-build-plugin
│ │ └── buildplugin
│ │ │ └── add
│ │ │ └── build-plugin-add.yaml
│ └── inject-maven
│ │ └── dependency
│ │ ├── add
│ │ └── dependency-add.yaml
│ │ └── add-using-var
│ │ └── dependency-add-using-var.yaml
└── projects
│ ├── config-client
│ ├── src
│ │ └── main
│ │ │ ├── resources
│ │ │ └── application.properties
│ │ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── configurationclient
│ │ │ ├── ConfigurationClientApplication.java
│ │ │ └── controller
│ │ │ └── MessageRestController.java
│ ├── target
│ │ └── classes
│ │ │ └── application.properties
│ └── README.md
│ ├── spring-data-jpa
│ ├── src
│ │ └── main
│ │ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── up
│ │ │ ├── Application.java
│ │ │ └── customer
│ │ │ ├── CustomerRepository.java
│ │ │ └── Customer.java
│ ├── README.md
│ └── pom.xml
│ ├── rest-service
│ ├── src
│ │ └── main
│ │ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── restservice
│ │ │ ├── Application.java
│ │ │ └── greeting
│ │ │ ├── Greeting.java
│ │ │ └── GreetingController.java
│ ├── README.adoc
│ └── pom.xml
│ └── spring-scheduling-tasks
│ ├── src
│ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── schedulingtasks
│ │ │ ├── SchedulingTasksApplication.java
│ │ │ └── scheduling
│ │ │ └── ScheduledTasks.java
│ └── test
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── schedulingtasks
│ │ ├── SchedulingTasksApplicationTest.java
│ │ └── scheduling
│ │ └── ScheduledTasksTest.java
│ ├── README.md
│ └── pom.xml
├── CONTRIBUTING.adoc
├── .vscode
├── launch.json
└── settings.json
├── settings.gradle
├── .github
├── rlnotes.mustache
└── workflows
│ ├── label-manage.yml
│ ├── pr.yml
│ ├── dev-native.yml
│ ├── deploy-docs.yml
│ ├── jr-build.yml
│ ├── jr-assemble-javaarchive.yml
│ ├── ci.yml
│ ├── jr-ga.yml
│ ├── jr-ea.yml
│ ├── jr-assemble-jlink.yml
│ └── e2e.yml
├── .gitignore
└── .devcontainer
└── devcontainer.json
/docs/settings.gradle:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | version=0.10.0-SNAPSHOT
2 |
--------------------------------------------------------------------------------
/e2e/spring-cli-e2e-tests/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | junit.xml
3 |
4 |
--------------------------------------------------------------------------------
/e2e/spring-cli-e2e-tests/.prettierignore:
--------------------------------------------------------------------------------
1 | # dont care about typings
2 | types/
3 |
4 | # for test data
5 | test/data/
6 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/ref/project/index.adoc:
--------------------------------------------------------------------------------
1 | = Project
2 |
3 | A "Plain Old Java Project" hosted in GitHub or GitLab.
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-attic/spring-cli/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/src/jreleaser/images/spring-cli.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-attic/spring-cli/HEAD/src/jreleaser/images/spring-cli.ico
--------------------------------------------------------------------------------
/test-data/commands/exec/util/mkdir/mkdir-action.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - exec:
3 | command: mkdir {{directory-to-create}}
4 |
5 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/ref/actionfile/index.adoc:
--------------------------------------------------------------------------------
1 | = Action Files
2 |
3 | These define the actions that can be taken on a project.
4 |
--------------------------------------------------------------------------------
/src/test/resources/command-scanner-tests/k8s-simple/new/hello.txt:
--------------------------------------------------------------------------------
1 | ---
2 | actions:
3 | generate: hello.yml
4 | ---
5 | hello world
6 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/ref/catalog/index.adoc:
--------------------------------------------------------------------------------
1 | = Catalog
2 |
3 | The Project Catalog is a collection of projects that share a common theme.
4 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/ref/index.adoc:
--------------------------------------------------------------------------------
1 | = Reference Guides
2 |
3 | This section provides information on using the feature and capabilities of Spring CLI.
4 |
--------------------------------------------------------------------------------
/CONTRIBUTING.adoc:
--------------------------------------------------------------------------------
1 | If you have not previously done so, please fill out and
2 | submit the https://cla.pivotal.io/sign/spring[Contributor License Agreement].
3 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/ref/ai/index.adoc:
--------------------------------------------------------------------------------
1 | = AI
2 |
3 | Large Language Models such at OpenAI's ChatGPT offer a powerful solution for generating code using AI.
4 |
--------------------------------------------------------------------------------
/test-data/commands/inject/after/inject/inject-after.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - inject:
3 | to: sample.txt
4 | text: "INJECTED AFTER"
5 | after: marker2
--------------------------------------------------------------------------------
/src/main/resources/org/springframework/cli/commands/hello.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - generate:
3 | to: hello.txt
4 | text: Hello {{greeting}} on {{os-name}}.
5 |
--------------------------------------------------------------------------------
/test-data/commands/inject/after/inject/sample.txt:
--------------------------------------------------------------------------------
1 | hello there
2 | this is a test file
3 | we are going to insert before the line that has the word marker1
4 | marker2
--------------------------------------------------------------------------------
/test-data/commands/inject/before/inject/inject-before.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - inject:
3 | to: sample.txt
4 | text: "INJECTED BEFORE"
5 | before: marker1
--------------------------------------------------------------------------------
/test-data/commands/inject/before/inject/sample.txt:
--------------------------------------------------------------------------------
1 | hello there
2 | this is a test file
3 | we are going to insert before the line that has the word marker1
4 | marker2
--------------------------------------------------------------------------------
/test-data/commands/inject/skip/inject/sample.txt:
--------------------------------------------------------------------------------
1 | hello there
2 | this is a test file
3 | we are going to insert before the line that has the word marker1
4 | marker2
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/exec/util/mkdir/mkdir-action.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - exec:
3 | command: mkdir {{directory-to-create}}
4 |
5 |
--------------------------------------------------------------------------------
/test-data/commands/exec-redirect/working/dir/ls-action.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - exec:
3 | command: ls
4 | to: "{{output}}"
5 | dir: "{{work-dir}}"
6 |
7 |
--------------------------------------------------------------------------------
/test-data/commands/exec-define/varjsonpath/define/10-use-var.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - generate:
3 | to: "{{output-temp-file}}"
4 | text: Hello {{phone-type.[0]}}
5 |
6 |
--------------------------------------------------------------------------------
/test-data/commands/if/vars/notdefined/vars-notdefined.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - if: "#{ ['functions'].varNotDefined('name') }"
3 | vars:
4 | data:
5 | name: "{{name}}"
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/contributing-project-catalogs.adoc:
--------------------------------------------------------------------------------
1 | = Contributing Project Catalogs
2 |
3 | You can register project catalogs by using the `spring catalog add` command.
4 |
5 | TBD
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/ref/usercommand/index.adoc:
--------------------------------------------------------------------------------
1 | = User Commands
2 |
3 | User Commands are declaratively defined commands that let you add or modify code and configuration files.
4 |
--------------------------------------------------------------------------------
/test-data/commands/inject/skip/inject/inject-skip.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - inject:
3 | to: sample.txt
4 | text: "INJECTED BEFORE"
5 | before: marker1
6 | skip: marker2
--------------------------------------------------------------------------------
/test-data/commands/vars/vars/iftrue/vars-if-data.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - if: "#{ true }"
3 | vars:
4 | data:
5 | name: John
6 | age: 30
7 | person: true
8 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/glossary.adoc:
--------------------------------------------------------------------------------
1 | = Glossary
2 |
3 | Action File::
4 | A file that contains an array of actions to perform, such as generating code or executing other commands.
5 |
--------------------------------------------------------------------------------
/test-data/commands/vars/vars/iffalse/vars-if-data.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - if: "#{ false }"
3 | vars:
4 | data:
5 | name: John
6 | age: 30
7 | person: true
8 |
--------------------------------------------------------------------------------
/test-data/commands/vars/vars/data/vars-data.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - if: "#{ ['name'] == null }"
3 | vars:
4 | data:
5 | name: John
6 | age: 30
7 | person: true
8 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/exec/working/dir/ls-action.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - exec:
3 | command: ls
4 | to: "{{output}}"
5 | dir: "{{work-dir}}"
6 |
7 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/exec/define/var/10-use-var.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - generate:
3 | to: "{{output-temp-file}}"
4 | text: Hello {{phone-type.[0]}}
5 |
6 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/inject/myfile-before.txt:
--------------------------------------------------------------------------------
1 | hello there
2 | this is a test file
3 | we are going to insert before the line that has the word marker1
4 | marker2
5 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/inject/myfile-before.txt.bak:
--------------------------------------------------------------------------------
1 | hello there
2 | this is a test file
3 | we are going to insert before the line that has the word marker1
4 | marker2
5 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/engine/actions/ActionsFileReaderTests-vars-data.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - vars:
3 | data:
4 | name: John
5 | age: 30
6 | person: true
7 |
--------------------------------------------------------------------------------
/test-data/commands/exec-define/varjsonpath/define/00-define-var.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - exec:
3 | command-file: echo-command.txt
4 | define:
5 | name: phone-type
6 | jsonPath: $.phoneNumbers[:1].type
7 |
--------------------------------------------------------------------------------
/test-data/commands/generate/hello/new/generate.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - generate:
3 | to: hello.txt
4 | text: "Hello {{greeting}} with Java {{java-version}} Root package {{root-package-dir}} Temp dir {{tmp-dir}}"
5 |
--------------------------------------------------------------------------------
/test-data/commands/if/run/define/run-define.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - if: "#{ (['functions'].runFile('echo-command.txt')).contains( 'John' ) }"
3 | vars:
4 | data:
5 | name: "John is present in the output"
6 |
--------------------------------------------------------------------------------
/test-data/projects/config-client/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=a-bootiful-client
2 | spring.config.import=optional:configserver:http://localhost:8888/
3 | management.endpoints.web.exposure.include=*
4 |
--------------------------------------------------------------------------------
/test-data/projects/config-client/target/classes/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=a-bootiful-client
2 | spring.config.import=optional:configserver:http://localhost:8888/
3 | management.endpoints.web.exposure.include=*
4 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/howto/index.adoc:
--------------------------------------------------------------------------------
1 | = How-to Guides
2 |
3 | This section provides answers to some common ‘how do I do that…’ questions that often arise when using Spring CLI. Its coverage is not exhaustive, but it does cover quite a lot.
4 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/inject/myfile-after.txt:
--------------------------------------------------------------------------------
1 | hello there
2 | this is a test file
3 | we are going to insert after the line that has the word marker1
4 | HELLO
5 | INJECTED
6 | WORLD
7 | marker2
8 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/inject/myfile-after.txt.bak:
--------------------------------------------------------------------------------
1 | hello there
2 | this is a test file
3 | we are going to insert after the line that has the word marker1
4 | HELLO
5 | INJECTED
6 | WORLD
7 | marker2
8 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/inject/myfile-after.txt.expected:
--------------------------------------------------------------------------------
1 | hello there
2 | this is a test file
3 | we are going to insert after the line that has the word marker1
4 | HELLO
5 | INJECTED
6 | WORLD
7 | marker2
--------------------------------------------------------------------------------
/test-data/commands/generate/controller/new/create-controller.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - generate:
3 | to: src/main/java/{{root-package-dir}}/{{feature}}/{{capitalizeFirst feature}}Controller.java
4 | from: RestController.java
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/exec/define/var/00-define-var.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - exec:
3 | command-file: echo-command.txt
4 | define:
5 | name: phone-type
6 | jsonPath: $.phoneNumbers[:1].type
7 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/inject/myfile-before.txt.expected:
--------------------------------------------------------------------------------
1 | hello there
2 | this is a test file
3 | HELLO
4 | INJECTED
5 | WORLD
6 | we are going to insert before the line that has the word marker1
7 | marker2
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/engine/actions/ActionsFileReaderTests-actions.yaml:
--------------------------------------------------------------------------------
1 | conditional:
2 | artifact-id: spring-cloud-azure-starter-jdbc-postgresql
3 | actions:
4 | - generate:
5 | to: hello.txt
6 | text: Hello World
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/inject/after/text/action-inject-after.txt:
--------------------------------------------------------------------------------
1 | ---
2 | actions:
3 | inject:
4 | after: marker1
5 | to: myfile-after.txt
6 | skip: INJECTED
7 | ---
8 | HELLO
9 | INJECTED
10 | WORLD
11 |
12 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/inject/before/text/action-inject-before.txt:
--------------------------------------------------------------------------------
1 | ---
2 | action:
3 | inject:
4 | before: marker1
5 | to: myfile-before.txt
6 | skip: INJECTED
7 | ---
8 | HELLO
9 | INJECTED
10 | WORLD
11 |
--------------------------------------------------------------------------------
/test-data/commands/exec-define/varoutput/define/00-define-var.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - exec:
3 | command: echo 'from echo'
4 | define:
5 | name: message
6 | - generate:
7 | to: "{{output-temp-file}}"
8 | text: Hello {{message}}
9 |
10 |
--------------------------------------------------------------------------------
/src/main/resources/org/springframework/cli/merger/ai/openai-user-name-heuristic-prompt.txt:
--------------------------------------------------------------------------------
1 | Here is the description of the Java application that uses Spring projects
2 |
3 | {{description}}
4 |
5 | Response in JSON format using the fields 'springProjectName' and 'shortName'
6 |
--------------------------------------------------------------------------------
/test-data/commands/inject-maven-repository/repository/add/repository-add.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - inject-maven-repository:
3 | text: |
4 |
5 | spring-snapshots
6 | https://repo.spring.io/snapshot
7 |
--------------------------------------------------------------------------------
/test-data/commands/generate/hello/new/command.yaml:
--------------------------------------------------------------------------------
1 | command:
2 | description: Generate a new file with a hello message
3 | options:
4 | - name: greeting
5 | description: who or what to say hello to
6 | dataType: string
7 | defaultValue: World
8 | inputType: text
--------------------------------------------------------------------------------
/test-data/commands/vars/vars/data-handlebars/vars-data.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - if: "#{ ['name'] == null }"
3 | vars:
4 | data:
5 | name: "{{name-to-use}}"
6 | age: "{{age}}"
7 | "height-in-{{height-unit}}": "{{height}}"
8 | person: "{{is-person}}"
9 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/engine/actions/ActionsFileReaderTests-actions-with-name.yaml:
--------------------------------------------------------------------------------
1 | conditional:
2 | artifact-id: spring-cloud-azure-starter-jdbc-postgresql
3 | actions:
4 | - name: create hello world
5 | generate:
6 | to: hello.txt
7 | text: Hello World
--------------------------------------------------------------------------------
/test-data/commands/inject-maven-repository/repository/add-using-var/repository-add-using-var.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - inject-maven-repository:
3 | text: |
4 |
5 | {{repository-id}}
6 | https://repo.spring.io/snapshot
7 |
--------------------------------------------------------------------------------
/e2e/spring-cli-e2e-tests/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 120,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "semi": true,
6 | "singleQuote": true,
7 | "trailingComma": "none",
8 | "bracketSpacing": true,
9 | "arrowParens": "avoid",
10 | "parser": "typescript"
11 | }
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/test-data/commands/if/run/define/echo-command.txt:
--------------------------------------------------------------------------------
1 | echo '{ "firstName": "John", "lastName": "doe", "age": 26, "address": { "streetAddress": "naist street", "city": "Nara", "postalCode": "630-0192" }, "phoneNumbers": [ { "type": "iPhone", "number": "0123-4567-8888" }, { "type": "home", "number": "0123-4567-8910" } ] }'
--------------------------------------------------------------------------------
/test-data/commands/vars/vars/define/echo-command.txt:
--------------------------------------------------------------------------------
1 | echo '{ "firstName": "John", "lastName": "doe", "age": 26, "address": { "streetAddress": "naist street", "city": "Nara", "postalCode": "630-0192" }, "phoneNumbers": [ { "type": "iPhone", "number": "0123-4567-8888" }, { "type": "home", "number": "0123-4567-8910" } ] }'
--------------------------------------------------------------------------------
/src/main/resources/org/springframework/cli/commands/command.yaml:
--------------------------------------------------------------------------------
1 | command:
2 | description: Generate a new file with a hello message
3 | options:
4 | #
5 | - name: greeting
6 | description: who or what to say hello to
7 | dataType: string
8 | defaultValue: World
9 | inputType: text # TEXT
--------------------------------------------------------------------------------
/test-data/commands/generate/controller/new/command.yaml:
--------------------------------------------------------------------------------
1 | command:
2 | description: Generate a new Spring Controller
3 | options:
4 | #
5 | - name: feature
6 | description: name of the feature package
7 | dataType: string
8 | defaultValue: person
9 | inputType: text # TEXT
10 |
--------------------------------------------------------------------------------
/test-data/commands/exec-define/varjsonpath/define/echo-command.txt:
--------------------------------------------------------------------------------
1 | echo '{ "firstName": "John", "lastName": "doe", "age": 26, "address": { "streetAddress": "naist street", "city": "Nara", "postalCode": "630-0192" }, "phoneNumbers": [ { "type": "iPhone", "number": "0123-4567-8888" }, { "type": "home", "number": "0123-4567-8910" } ] }'
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/version.adoc:
--------------------------------------------------------------------------------
1 | = version
2 | Show version info
3 |
4 | == NAME
5 | version
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | version --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--help or -h` help for version *Optional*
17 |
18 |
19 | include::footers/version-footer.adoc[opts=optional]
20 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/role-list.adoc:
--------------------------------------------------------------------------------
1 | = role list
2 | List roles
3 |
4 | == NAME
5 | role list
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | role list --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--help or -h` help for role list *Optional*
17 |
18 |
19 | include::footers/role-list-footer.adoc[opts=optional]
20 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/vars-new.adoc:
--------------------------------------------------------------------------------
1 | = vars new
2 | create a new var
3 |
4 | == NAME
5 | vars new
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | vars new --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--help or -h` help for vars new *Optional*
17 |
18 |
19 | include::footers/vars-new-footer.adoc[opts=optional]
20 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/exec/define/var/echo-command.txt:
--------------------------------------------------------------------------------
1 | echo '{ "firstName": "John", "lastName": "doe", "age": 26, "address": { "streetAddress": "naist street", "city": "Nara", "postalCode": "630-0192" }, "phoneNumbers": [ { "type": "iPhone", "number": "0123-4567-8888" }, { "type": "home", "number": "0123-4567-8910" } ] }'
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "type": "java",
6 | "name": "Cli Interactive",
7 | "request": "launch",
8 | "mainClass": "org.springframework.cli.SpringCliApplication",
9 | "projectName": "spring-cli"
10 | }
11 | ]
12 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | mavenCentral()
4 | gradlePluginPortal()
5 | if (version.contains('-')) {
6 | maven { url "https://repo.spring.io/milestone" }
7 | }
8 | if (version.endsWith('-SNAPSHOT')) {
9 | maven { url "https://repo.spring.io/snapshot" }
10 | }
11 | }
12 | }
13 | rootProject.name = 'spring-cli'
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/merger/ai/OpenAiHandlerTests-request.md:
--------------------------------------------------------------------------------
1 | "Create a Spring Java application using Spring Data JPA and integrate it with a MySQL database. Please include instructions on how to start a MySQL server using Docker. Additionally, add an integration test to ensure the proper functioning of the application using @DataJpaTest"
2 |
3 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/engine/actions/ActionsFileReaderTests-bad-vars.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - vars:
3 | questions:
4 | - question:
5 | # wrong indention of name and text, ActionsFileReader will trigger a more helpful error message when deserializing
6 | name: language
7 | label: What is your primary language?
8 |
--------------------------------------------------------------------------------
/test-data/commands/vars/vars/define/vars-define.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - vars:
3 | questions:
4 | - question:
5 | name: phone-number
6 | label: Select a Phone Number
7 | type: dropdown
8 | options:
9 | exec:
10 | command-file: echo-command.txt
11 | json-path: $.phoneNumbers[*].number
--------------------------------------------------------------------------------
/docs/help-commands-adoc.stg:
--------------------------------------------------------------------------------
1 | command(command) ::= <<
2 |
3 | >>
4 |
5 | commandGroup(commandGroup) ::= <<
6 | :}; separator=":">
7 | >>
8 |
9 | groups(groups) ::= <<
10 | }; separator="\n">
11 | >>
12 |
13 | main(model) ::= <<
14 |
15 | >>
16 |
--------------------------------------------------------------------------------
/src/main/resources/org/springframework/cli/merger/ai/openai-user-rewrite-description-prompt.txt:
--------------------------------------------------------------------------------
1 | Here is the description of the Java application that uses Spring projects. Please rewrite it so that it clearly describes the instructions of the application to create.
2 |
3 | {{description}}
4 |
5 | Provide a response that starts with the words: "Please provide instructions for creating"
6 |
7 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/completion-zsh.adoc:
--------------------------------------------------------------------------------
1 | = completion zsh
2 | Generate zsh completion script
3 |
4 | == NAME
5 | completion zsh
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | completion zsh --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--help or -h` help for completion zsh *Optional*
17 |
18 |
19 | include::footers/completion-zsh-footer.adoc[opts=optional]
20 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/engine/actions/ActionsFileReaderTests-vars.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - vars:
3 | questions:
4 | - question:
5 | name: resource-group
6 | label: Select a resource group.
7 | type: dropdown
8 | options:
9 | exec:
10 | command: az group list
11 | json-path: $[*].name
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/completion-bash.adoc:
--------------------------------------------------------------------------------
1 | = completion bash
2 | Generate bash completion script
3 |
4 | == NAME
5 | completion bash
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | completion bash --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--help or -h` help for completion bash *Optional*
17 |
18 |
19 | include::footers/completion-bash-footer.adoc[opts=optional]
20 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/role-add.adoc:
--------------------------------------------------------------------------------
1 | = role add
2 | Add a role
3 |
4 | == NAME
5 | role add
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | role add [--name String] --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--name` String Role name *Mandatory*
17 |
18 | `--help or -h` help for role add *Optional*
19 |
20 |
21 | include::footers/role-add-footer.adoc[opts=optional]
22 |
--------------------------------------------------------------------------------
/.github/rlnotes.mustache:
--------------------------------------------------------------------------------
1 | {{#headerslength}}
2 | # Generic Notes
3 |
4 | {{/headerslength}}
5 | {{#headers}}
6 | **{{title}}**
7 | {{body}}
8 |
9 | {{/headers}}
10 | # Issues
11 |
12 | {{#issues}}
13 | {{repo}}#{{number}} {{title}}
14 | {{/issues}}
15 |
16 | {{#footerslength}}
17 | # Additional Notes
18 |
19 | {{/footerslength}}
20 | {{#footers}}
21 | **{{title}}**
22 | {{body}}
23 |
24 | {{/footers}}
25 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/github-auth-login.adoc:
--------------------------------------------------------------------------------
1 | = github auth login
2 | Authenticate with GitHub.
3 |
4 | == NAME
5 | github auth login
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | github auth login --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--help or -h` help for github auth login *Optional*
17 |
18 |
19 | include::footers/github-auth-login-footer.adoc[opts=optional]
20 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/github-auth-logout.adoc:
--------------------------------------------------------------------------------
1 | = github auth logout
2 | Log out of GitHub.
3 |
4 | == NAME
5 | github auth logout
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | github auth logout --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--help or -h` help for github auth logout *Optional*
17 |
18 |
19 | include::footers/github-auth-logout-footer.adoc[opts=optional]
20 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/script.adoc:
--------------------------------------------------------------------------------
1 | = script
2 | Read and execute commands from a file.
3 |
4 | == NAME
5 | script
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | script [--file File] --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--file` File *Mandatory*
17 |
18 | `--help or -h` help for script *Optional*
19 |
20 |
21 | include::footers/script-footer.adoc[opts=optional]
22 |
--------------------------------------------------------------------------------
/docs/antora.yml:
--------------------------------------------------------------------------------
1 | name: cli
2 | version: true
3 | title: Spring Cli
4 | nav:
5 | - modules/ROOT/nav.adoc
6 | - modules/ROOT/nav-commands.adoc
7 | ext:
8 | collector:
9 | run:
10 | command: gradlew -q -PbuildSrc.skipTests=true "-Dorg.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError" generateAntoraResources
11 | local: true
12 | scan:
13 | dir: ./../build/generated-antora-resources
14 |
--------------------------------------------------------------------------------
/test-data/commands/inject-maven-dependency-mgmt/dependency/add/dependency-add.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - inject-maven-dependency-management:
3 | text: |
4 |
5 | org.springframework.modulith
6 | spring-modulith-bom
7 | 1.1.1
8 | import
9 | pom
10 |
--------------------------------------------------------------------------------
/test-data/projects/spring-data-jpa/src/main/java/com/example/up/Application.java:
--------------------------------------------------------------------------------
1 | package com.example.up;
2 |
3 |
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 |
7 | @SpringBootApplication
8 | public class Application {
9 |
10 | public static void main(String[] args) {
11 | SpringApplication.run(Application.class);
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/role-remove.adoc:
--------------------------------------------------------------------------------
1 | = role remove
2 | Remove a named role
3 |
4 | == NAME
5 | role remove
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | role remove [--name String] --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--name` String Role name *Mandatory*
17 |
18 | `--help or -h` help for role remove *Optional*
19 |
20 |
21 | include::footers/role-remove-footer.adoc[opts=optional]
22 |
--------------------------------------------------------------------------------
/test-data/commands/generate/controller/new/RestController.java:
--------------------------------------------------------------------------------
1 | package {{root-package}}.{{feature}};
2 |
3 | import org.springframework.web.bind.annotation.GetMapping;
4 | import org.springframework.web.bind.annotation.RestController;
5 |
6 | @RestController
7 | public class {{capitalizeFirst feature}}Controller {
8 |
9 | @GetMapping("/{{feature}}")
10 | public String greeting() {
11 | return "Hello {{feature}}";
12 | }
13 | }
--------------------------------------------------------------------------------
/test-data/commands/if/vars/define/vars-if.yml:
--------------------------------------------------------------------------------
1 | actions:
2 | - if: "#{ ['name'] == null }"
3 | vars:
4 | data:
5 | name: John
6 | - if: "#{ ['name'] == 'John' }"
7 | vars:
8 | data:
9 | middle-name: Sam # middle-name will be set as a variable
10 | - if: "#{ ['name'] != 'John' }"
11 | vars:
12 | data:
13 | last-name: Park # last-name will NOT be set as a variable
14 |
15 |
16 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/help.adoc:
--------------------------------------------------------------------------------
1 | = help
2 | Display help about available commands
3 |
4 | == NAME
5 | help
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | help --command String[] --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--command or -C` String[] The command to obtain help for. *Optional*
17 |
18 | `--help or -h` help for help *Optional*
19 |
20 |
21 | include::footers/help-footer.adoc[opts=optional]
22 |
--------------------------------------------------------------------------------
/e2e/spring-cli-e2e-tests/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | clearMocks: true,
3 | moduleFileExtensions: ['js', 'ts'],
4 | testEnvironment: 'node',
5 | testMatch: ['**/*.test.ts'],
6 | testRunner: 'jest-circus/runner',
7 | transform: {
8 | '^.+\\.ts$': 'ts-jest'
9 | },
10 | reporters: ['default', 'jest-junit'],
11 | verbose: true,
12 | setupFilesAfterEnv: ['jest-extended', '@alex_neo/jest-expect-message']
13 | }
14 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/project-remove.adoc:
--------------------------------------------------------------------------------
1 | = project remove
2 | Remove project
3 |
4 | == NAME
5 | project remove
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | project remove [--name String] --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--name` String Project name *Mandatory*
17 |
18 | `--help or -h` help for project remove *Optional*
19 |
20 |
21 | include::footers/project-remove-footer.adoc[opts=optional]
22 |
--------------------------------------------------------------------------------
/src/main/resources/org/springframework/cli/merger/ai/openai-system-rewrite-description-prompt.txt:
--------------------------------------------------------------------------------
1 | This is a system message. You will receive a user message containing a description of the desired Spring Java program. Your task is to rewrite the description in a clear and concise manner so that ChatGPT can effectively understand and process the information to provide the instructions to create the code for new Spring Java application.
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/history.adoc:
--------------------------------------------------------------------------------
1 | = history
2 | Display or save the history of previously run commands
3 |
4 | == NAME
5 | history
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | history --file File --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--file` File A file to save history to. *Optional*
17 |
18 | `--help or -h` help for history *Optional*
19 |
20 |
21 | include::footers/history-footer.adoc[opts=optional]
22 |
--------------------------------------------------------------------------------
/test-data/commands/inject-maven-dependency-mgmt/dependency/add-using-var/dependency-add-using-var.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - inject-maven-dependency-management:
3 | text: |
4 |
5 | org.springframework.modulith
6 | spring-modulith-bom
7 | {{release}}
8 | import
9 | pom
10 |
--------------------------------------------------------------------------------
/test-data/projects/rest-service/src/main/java/com/example/restservice/Application.java:
--------------------------------------------------------------------------------
1 | package com.example.restservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Application.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/command-add.adoc:
--------------------------------------------------------------------------------
1 | = command add
2 | Add a user-defined command
3 |
4 | == NAME
5 | command add
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | command add --from String --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--from` String Add user-defined command from a URL. *Optional*
17 |
18 | `--help or -h` help for command add *Optional*
19 |
20 |
21 | include::footers/command-add-footer.adoc[opts=optional]
22 |
--------------------------------------------------------------------------------
/test-data/projects/spring-data-jpa/src/main/java/com/example/up/customer/CustomerRepository.java:
--------------------------------------------------------------------------------
1 | package com.example.up.customer;
2 |
3 | import java.util.List;
4 |
5 | import com.example.up.customer.Customer;
6 |
7 | import org.springframework.data.repository.CrudRepository;
8 |
9 | public interface CustomerRepository extends CrudRepository {
10 |
11 | List findByLastName(String lastName);
12 |
13 | Customer findById(long id);
14 | }
15 |
--------------------------------------------------------------------------------
/src/test/resources/command-scanner-tests/k8s-simple/new-services/command.yaml:
--------------------------------------------------------------------------------
1 | command:
2 | description: Create the Kubernetes resource files for the application's services.
3 | options:
4 | - name: services-with-gusto
5 | description: say it loud, say it proud
6 | dataType: boolean
7 | defaultValue: false
8 | - name: services-with-greeting
9 | description: what word to use to say hello
10 | dataType: string
11 | defaultValue: Hello
--------------------------------------------------------------------------------
/src/main/resources/META-INF/native-image/native-image.properties:
--------------------------------------------------------------------------------
1 | Args = --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
2 | --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
3 | -H:+AllowJRTFileSystem \
4 | --initialize-at-build-time=com.ctc.wstx.api.ReaderConfig,com.ctc.wstx.api.CommonConfig,com.ctc.wstx.stax.WstxInputFactory,com.ctc.wstx.util.DefaultXmlSymbolTable,com.ctc.wstx.util.SymbolTable,com.ctc.wstx.util.SymbolTable$Bucket
5 |
--------------------------------------------------------------------------------
/e2e/spring-cli-e2e-tests/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2019",
4 | "module": "commonjs",
5 | "outDir": "./lib",
6 | "rootDirs": ["./src", "./test"],
7 | "strict": true,
8 | "baseUrl": ".",
9 | "noImplicitAny": false,
10 | "paths": {
11 | "*": ["./types/*"]
12 | },
13 | "esModuleInterop": true,
14 | "lib": [
15 | "es2019"
16 | ]
17 | },
18 | "exclude": ["node_modules", "**/*.test.ts"]
19 | }
20 |
--------------------------------------------------------------------------------
/test-data/projects/rest-service/src/main/java/com/example/restservice/greeting/Greeting.java:
--------------------------------------------------------------------------------
1 | package com.example.restservice.greeting;
2 |
3 | public class Greeting {
4 |
5 | private final long id;
6 | private final String content;
7 |
8 | public Greeting(long id, String content) {
9 | this.id = id;
10 | this.content = content;
11 | }
12 |
13 | public long getId() {
14 | return id;
15 | }
16 |
17 | public String getContent() {
18 | return content;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/role-get.adoc:
--------------------------------------------------------------------------------
1 | = role get
2 | Get the value of a key for a role
3 |
4 | == NAME
5 | role get
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | role get [--key String] --name String --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--key` String Property key *Mandatory*
17 |
18 | `--name` String Role name *Optional*
19 |
20 | `--help or -h` help for role get *Optional*
21 |
22 |
23 | include::footers/role-get-footer.adoc[opts=optional]
24 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/project-catalog-remove.adoc:
--------------------------------------------------------------------------------
1 | = project catalog remove
2 | Remove a project catalog
3 |
4 | == NAME
5 | project catalog remove
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | project catalog remove [--name String] --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--name` String Catalog name *Mandatory*
17 |
18 | `--help or -h` help for project catalog remove *Optional*
19 |
20 |
21 | include::footers/project-catalog-remove-footer.adoc[opts=optional]
22 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/howto/create-application.adoc:
--------------------------------------------------------------------------------
1 | = Create Application
2 |
3 | This section includes topics relating to application creation.
4 |
5 | [#initializr]
6 | == Create using start.spring.io
7 |
8 | You can use Spring CLI as a client for https://start.spring.io.
9 |
10 | Shell style project creation mimics how a project is created from the UI. The following image shows an example of it:
11 |
12 | [asciinema,rows=19]
13 | ----
14 | include::example$boot-start-interactive.cast[]
15 | ----
16 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/exec/assert/json/02-provision-postgresql.yml:
--------------------------------------------------------------------------------
1 | ---
2 | action:
3 | conditional:
4 | onArtifactId: spring-cloud-azure-starter-jdbc-postgresql
5 | exec:
6 | args:
7 | - az
8 | - postgres
9 | - flexible-server
10 | - create
11 | - --name
12 | - {{POSTGRESQL_SERVER}}
13 | - --database-name
14 | - {{POSTGRESQL_DB}}
15 | - --active-directory-auth
16 | - Enabled
17 | ---
18 | IGNORED
19 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/project-catalog-list.adoc:
--------------------------------------------------------------------------------
1 | = project catalog list
2 | List installed catalogs
3 |
4 | == NAME
5 | project catalog list
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | project catalog list --json boolean --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--json` boolean JSON format output *Optional, default = false*
17 |
18 | `--help or -h` help for project catalog list *Optional*
19 |
20 |
21 | include::footers/project-catalog-list-footer.adoc[opts=optional]
22 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/project-list.adoc:
--------------------------------------------------------------------------------
1 | = project list
2 | List projects available for use with the 'boot new' and 'boot add' commands
3 |
4 | == NAME
5 | project list
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | project list --json boolean --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--json` boolean JSON format output *Optional, default = false*
17 |
18 | `--help or -h` help for project list *Optional*
19 |
20 |
21 | include::footers/project-list-footer.adoc[opts=optional]
22 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/native-image/resource-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "bundles":[
3 | {
4 | "name":"com.sun.tools.javac.resources.compiler",
5 | "classNames":["com.sun.tools.javac.resources.compiler"]
6 | },
7 | {
8 | "name":"com.sun.tools.javac.resources.ct",
9 | "classNames":["com.sun.tools.javac.resources.ct"]
10 | },
11 | {
12 | "name":"com.sun.tools.javac.resources.javac",
13 | "classNames":["com.sun.tools.javac.resources.javac"]
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/github-auth-status.adoc:
--------------------------------------------------------------------------------
1 | = github auth status
2 | View authentication status.
3 |
4 | == NAME
5 | github auth status
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | github auth status --show-token boolean --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--show-token` boolean Display the auth token. *Optional, default = false*
17 |
18 | `--help or -h` help for github auth status *Optional*
19 |
20 |
21 | include::footers/github-auth-status-footer.adoc[opts=optional]
22 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/role-set.adoc:
--------------------------------------------------------------------------------
1 | = role set
2 | Set a key value pair for a role
3 |
4 | == NAME
5 | role set
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | role set [--key String] [--value ] --name String --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--key` String A key *Mandatory*
17 |
18 | `--value` A value *Mandatory*
19 |
20 | `--name` String Role name *Optional*
21 |
22 | `--help or -h` help for role set *Optional*
23 |
24 |
25 | include::footers/role-set-footer.adoc[opts=optional]
26 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/project-catalog-available.adoc:
--------------------------------------------------------------------------------
1 | = project catalog available
2 | List available catalogs
3 |
4 | == NAME
5 | project catalog available
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | project catalog available --json boolean --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--json` boolean JSON format output *Optional, default = false*
17 |
18 | `--help or -h` help for project catalog available *Optional*
19 |
20 |
21 | include::footers/project-catalog-available-footer.adoc[opts=optional]
22 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/exec/assert/json/00-assert-cli-version.yml:
--------------------------------------------------------------------------------
1 | ---
2 | action:
3 | exec:
4 | assertions: |
5 | #semver(#jsonPath(output, ‘$.azure-cli’), “>=2.46.0”)
6 | #semver(#jsonPath(output, ‘$.extensions.spring’), “>1.7.0”)
7 | fail-message: "You need upgrade Azure CLI to > 2.46.0 and Spring Extensions to version > 1.7.0"
8 | success-message: "Azure CLI version satisfied."
9 | args:
10 | - az
11 | - version
12 | - --output
13 | - json
14 | ---
15 | IGNORED
16 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/command-remove.adoc:
--------------------------------------------------------------------------------
1 | = command remove
2 | Delete a user-defined command
3 |
4 | == NAME
5 | command remove
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | command remove --commandName String --subCommandName String --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--commandName` String Command name *Optional*
17 |
18 | `--subCommandName` String SubCommand name *Optional*
19 |
20 | `--help or -h` help for command remove *Optional*
21 |
22 |
23 | include::footers/command-remove-footer.adoc[opts=optional]
24 |
--------------------------------------------------------------------------------
/test-data/projects/spring-scheduling-tasks/src/main/java/com/example/schedulingtasks/SchedulingTasksApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.schedulingtasks;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.scheduling.annotation.EnableScheduling;
6 |
7 | @SpringBootApplication
8 | @EnableScheduling
9 | public class SchedulingTasksApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(SchedulingTasksApplication.class);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/boot-add.adoc:
--------------------------------------------------------------------------------
1 | = boot add
2 | Merge an existing project into the current Spring Boot project
3 |
4 | == NAME
5 | boot add
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | boot add --from String --path String --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--from` String Add to the current project from an existing project by specifying the existing project's name or URL. *Optional*
17 |
18 | `--path` String Path *Optional*
19 |
20 | `--help or -h` help for boot add *Optional*
21 |
22 |
23 | include::footers/boot-add-footer.adoc[opts=optional]
24 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/exec/assert/json/01-assert-resource.yml:
--------------------------------------------------------------------------------
1 | ---
2 | action:
3 | show-time-estimate: true
4 | exec:
5 | assertions: |
6 | #jsonPath(output, '$.registrationState') == 'Registered'
7 | fail-message: "You need to register the provider 'Microsoft.ServiceLinker'"
8 | success-message: "Microsoft.ServiceLinker provider is already registered."
9 | args:
10 | - az
11 | - provider
12 | - list
13 | - --query
14 | - "[?namespace == 'Microsoft.ServiceLinker']"
15 | - --output
16 | - json
17 | ---
18 | IGNORED
--------------------------------------------------------------------------------
/src/main/resources/org/springframework/cli/merger/ai/openai-user-ai-add-prompt.txt:
--------------------------------------------------------------------------------
1 | Create the Spring Java application with the following placeholder information
2 |
3 | Spring Project Name: {{spring-project-name}}
4 | Description: {{description}}
5 | Build Tool: {{build-tool}}
6 | Package Name: {{package-name}}
7 |
8 | Ensure the solution meets the following additional criteria
9 |
10 | 1. Include import statements in all code files.
11 | 2. When generating markdown for the 'application.properties' file in Spring Boot, please ensure that the markdown 'info' field is set to 'properties' for that specific section.
12 |
13 |
--------------------------------------------------------------------------------
/.github/workflows/label-manage.yml:
--------------------------------------------------------------------------------
1 | name: Labels Manage
2 |
3 | on:
4 | push:
5 | branches:
6 | - 'main'
7 | paths:
8 | - '.github/labels-manage.yml'
9 | - '.github/workflows/label-manage.yml'
10 | workflow_dispatch:
11 |
12 | jobs:
13 | labeler:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v2
17 | - name: Mangle Labels
18 | uses: crazy-max/ghaction-github-labeler@v3
19 | with:
20 | github-token: ${{ secrets.GITHUB_TOKEN }}
21 | yaml-file: .github/labels-manage.yml
22 | dry-run: false
23 | skip-delete: true
24 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/ref/ai/readme-command-guide.adoc:
--------------------------------------------------------------------------------
1 | = Guide to README Commands
2 |
3 | When you have created a `README` file, either manually or as the result of running the `ai add --preview --description "Create a JPA application"` command, you can apply the changes described in that `README` file by using the `readme apply` command.
4 |
5 | For example, if there is a file named `README-ai-jpa.md` in the root of your project, the following command applies the changes:
6 |
7 | [source, bash]
8 | ----
9 | spring guide apply README-ai-jpa.md
10 | ----
11 |
12 | You can keep track of what has changed by committing your work in Git before applying the change.
13 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/project-add.adoc:
--------------------------------------------------------------------------------
1 | = project add
2 | Add a project to use with the 'boot new' and 'boot add' commands
3 |
4 | == NAME
5 | project add
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | project add [--name String] [--url String] --description String --tags List --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--name` String Project name *Mandatory*
17 |
18 | `--url` String Project url *Mandatory*
19 |
20 | `--description` String Project description *Optional*
21 |
22 | `--tags` List Project tags *Optional*
23 |
24 | `--help or -h` help for project add *Optional*
25 |
26 |
27 | include::footers/project-add-footer.adoc[opts=optional]
28 |
--------------------------------------------------------------------------------
/test-data/commands/inject-maven-build-plugin/buildplugin/add/build-plugin-add.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - inject-maven-build-plugin:
3 | text: |
4 |
5 | net.bytebuddy
6 | byte-buddy-maven-plugin
7 | 1.14.4
8 |
9 | true
10 |
11 |
12 |
13 |
14 | transform-extended
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/project-catalog-add.adoc:
--------------------------------------------------------------------------------
1 | = project catalog add
2 | Add a project catalog
3 |
4 | == NAME
5 | project catalog add
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | project catalog add [--name String] [--url String] --description String --tags List --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--name` String Catalog name *Mandatory*
17 |
18 | `--url` String Catalog url *Mandatory*
19 |
20 | `--description` String Catalog description *Optional*
21 |
22 | `--tags` List Project tags *Optional*
23 |
24 | `--help or -h` help for project catalog add *Optional*
25 |
26 |
27 | include::footers/project-catalog-add-footer.adoc[opts=optional]
28 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/footers/boot-start-footer.adoc:
--------------------------------------------------------------------------------
1 | == EXAMPLES
2 |
3 | Create new project.
4 |
5 | ====
6 | [source, bash]
7 | ----
8 | spring boot start
9 | ----
10 | ====
11 |
12 | Create new project with all given options.
13 |
14 | ====
15 | [source, bash]
16 | ----
17 | spring boot start \
18 | --path demo \
19 | --project gradle-project \
20 | --language java \
21 | --boot-version 2.7.0 \
22 | --version 0.0.1-SNAPSHOT \
23 | --group com.example \
24 | --artifact demo \
25 | --name demo \
26 | --description "Demo project" \
27 | --package-name com.example.demo \
28 | --dependencies web \
29 | --packaging jar \
30 | --java-version 17
31 | ----
32 | ====
33 |
--------------------------------------------------------------------------------
/src/test/resources/application-deser-test.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | up:
3 | templateCatalogs:
4 | - name: catalog1
5 | description: The first catalog
6 | url: https://github.com/rd-1-2022/template-catalog
7 | - name: catalog2
8 | description: The second catalog
9 | url: https://github.com/rd-1-2022/template-catalog-2
10 | templateRepositories:
11 | - name: jpa
12 | description: Learn how to work with JPA data persistence using Spring Data JPA.
13 | url: https://github.com/rd-1-2022/rpt-spring-data-jpa
14 | tags:
15 | - jpa
16 | - h2
17 | defaults:
18 | packageName: com.xkcd
19 | templateRepositoryName: jpa
--------------------------------------------------------------------------------
/.github/workflows/pr.yml:
--------------------------------------------------------------------------------
1 | name: PR
2 |
3 | on:
4 | pull_request:
5 |
6 | jobs:
7 | build:
8 | runs-on: ${{ matrix.os }}
9 | strategy:
10 | fail-fast: false
11 | matrix:
12 | include:
13 | - nickname: macos
14 | os: macos-latest
15 | - nickname: linux
16 | os: ubuntu-latest
17 | - nickname: windows
18 | os: windows-latest
19 | name: CI Build ${{ matrix.java }}
20 | steps:
21 | - uses: actions/checkout@v4
22 | - uses: actions/setup-java@v4
23 | with:
24 | distribution: adopt
25 | java-version: 17
26 | cache: gradle
27 | - run: ./gradlew build --no-daemon
28 |
--------------------------------------------------------------------------------
/docs/local-antora-playbook.yml:
--------------------------------------------------------------------------------
1 | site:
2 | title: Spring CLI
3 | url: https://docs.spring.io/spring-cli/reference
4 | start_page: spring-cli::index.adoc
5 | asciidoc:
6 | attributes:
7 | page-pagination: true
8 | content:
9 | sources:
10 | - url: ../
11 | start_path: docs
12 | urls:
13 | latest_version_segment_strategy: redirect:to
14 | latest_version_segment: ''
15 | redirect_facility: static
16 | ui:
17 | bundle:
18 | url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.7/ui-bundle.zip
19 | snapshot: true
20 | supplemental_files:
21 | - path: ui.yml
22 | contents: |
23 | static_files:
24 | - .nojekyll
25 | - path: .nojekyll
26 |
27 |
--------------------------------------------------------------------------------
/test-data/commands/inject-maven/dependency/add/dependency-add.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - inject-maven-dependency:
3 | text: |
4 |
5 | org.springframework.boot
6 | spring-boot-starter-data-jpa
7 |
8 |
9 |
10 | org.springframework.boot
11 | spring-boot-starter-test
12 | test
13 |
14 |
15 |
16 | com.h2database
17 | h2
18 | runtime
19 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/command-new.adoc:
--------------------------------------------------------------------------------
1 | = command new
2 | Create a new user-defined command.
3 |
4 | == NAME
5 | command new
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | command new --command-name String --sub-command-name String --path String --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--command-name` String The name of the user-defined command to create. *Optional, default = hello*
17 |
18 | `--sub-command-name` String The name of the user-defined sub-command to create. *Optional, default = new*
19 |
20 | `--path` String Path on which to run the command. *Optional*
21 |
22 | `--help or -h` help for command new *Optional*
23 |
24 |
25 | include::footers/command-new-footer.adoc[opts=optional]
26 |
--------------------------------------------------------------------------------
/test-data/commands/inject-maven/dependency/add-using-var/dependency-add-using-var.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - inject-maven-dependency:
3 | text: |
4 |
5 | org.springframework.boot
6 | spring-boot-starter-data-jpa
7 |
8 |
9 |
10 | org.springframework.boot
11 | spring-boot-starter-test
12 | test
13 |
14 |
15 |
16 | com.h2database
17 | h2
18 | {{runtime-scope}}
19 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/exec/assert/json/03-conditional-strawman.yml:
--------------------------------------------------------------------------------
1 | action:
2 | conditional:
3 | artifact-id: regex blah blah
4 | missing-file: {{artifact-path}}
5 | env-var: FOO
6 | expression: >
7 | spel expression here
8 | run: |
9 | az foo bar {{asdf}}
10 |
11 |
12 | https://stackoverflow:
13 | com/questions/5928225/how-to-make-pipes-work-with-runtime-exec:
14 |
15 | String[] cmd = {
16 | "/bin/sh",
17 | "-c",
18 | "ls /etc | grep release"
19 | };
20 |
21 | Process p = Runtime.getRuntime().exec(cmd);
22 |
23 | -----
24 | String[] cmd = {
25 | "cmd",
26 | "/C",
27 | "dir /B | findstr /R /C:"release""
28 | };
29 | Process p = Runtime.getRuntime().exec(cmd);
30 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/engine/actions/ActionsFileReaderTests-inject-maven-deps.yaml:
--------------------------------------------------------------------------------
1 | actions:
2 | - inject-maven-dependency:
3 | text: |
4 |
5 | org.springframework.boot
6 | spring-boot-starter-data-jpa
7 |
8 |
9 |
10 | org.springframework.boot
11 | spring-boot-starter-test
12 | test
13 |
14 |
15 |
16 | com.h2database
17 | h2
18 | runtime
19 |
--------------------------------------------------------------------------------
/src/main/resources/org/springframework/cli/merger/ai/openai-system-name-heuristic-prompt.txt:
--------------------------------------------------------------------------------
1 | This is the system chat message. You are going to be given a description of a Java application that uses Spring projects.
2 | The list of Spring projects can be found by crawling the website https://spring.io/projects.
3 |
4 | Given the description, infer the following two pieces of information that describe the application:
5 |
6 | 1. The name of the main Spring project that would be used in the application.
7 | 2. A single word that best describes the name of the main Spring project that would be used in the application. Prefer the single word that comes last in the name of the main Spring project.
8 |
9 | Response in JSON format using the fields 'springProjectName' and 'shortName'
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/test-data/projects/rest-service/src/main/java/com/example/restservice/greeting/GreetingController.java:
--------------------------------------------------------------------------------
1 | package com.example.restservice.greeting;
2 |
3 | import java.util.concurrent.atomic.AtomicLong;
4 |
5 | import org.springframework.web.bind.annotation.GetMapping;
6 | import org.springframework.web.bind.annotation.RequestParam;
7 | import org.springframework.web.bind.annotation.RestController;
8 |
9 | @RestController
10 | public class GreetingController {
11 |
12 | private static final String template = "Hello, %s!";
13 | private final AtomicLong counter = new AtomicLong();
14 |
15 | @GetMapping("/greeting")
16 | public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
17 | return new Greeting(counter.incrementAndGet(), String.format(template, name));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/util/YmlMerger.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.util;
18 |
19 | public class YmlMerger {
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/resources/springcliapp.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | main:
3 | web-application-type: none
4 | banner-mode: off
5 | shell:
6 | interactive:
7 | enabled: true
8 | config:
9 | location: "{userconfig}/springcli"
10 | history:
11 | name: spring-cli-history.log
12 | command:
13 | completion:
14 | root-command: spring
15 | version:
16 | show-git-short-commit-id: true
17 | cli:
18 | github:
19 | client-id: 10a18d1837ecdac59ba2
20 | default-scopes: repo,read:org
21 |
22 | ## disable/enable console logging
23 | logging:
24 | pattern:
25 | console:
26 | ## log debug from a cli
27 | # file:
28 | # name: shell.log
29 | # level:
30 | # root: DEBUG
31 | # org:
32 | # springframework:
33 | # cli: DEBUG
34 | # shell: DEBUG
35 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/runtime/command/manifest-full-deserialization.yaml:
--------------------------------------------------------------------------------
1 | command:
2 | name: new-demo
3 | description: Create a new demo project
4 | options:
5 | - name: platform
6 | description: platform to target
7 | dataType: string
8 | defaultValue: azure
9 | inputType: select # SELECT (single option)
10 | choices:
11 | azure: Microsoft Azure
12 | lambda: AWS Lambda
13 | google: Google Cloud Platform
14 | - name: service-name
15 | description: The name of the service
16 | dataType: string
17 | defaultValue: mckesson-service-template
18 | inputType: text
19 | - name: package-name
20 | description: The package name of the service
21 | dataType: string
22 | defaultValue: com.example.sample
23 | inputType: text
24 |
--------------------------------------------------------------------------------
/src/main/resources/org/springframework/cli/merger/ai/openai-user-rewrite-info-fields.txt:
--------------------------------------------------------------------------------
1 | Rewrite the provided markdown file based on the following criteria
2 |
3 | 1. For each markdown section in the generated application where the 'info' field is set to 'html', please include a comment at the beginning of each HTML file. This comment should contain the full path to the file name, prefixed with 'filename:'
4 | 2. For each markdown section in the generated application where the 'info' field is set to 'sql', please include a comment at the beginning of each sql file. This comment should contain the full path to the file name, prefixed with 'filename:'
5 | 3. For each markdown section in the generated application where the 'info' field is set to 'csv', please include a comment at the beginning of each CSV file. This comment should contain the full path to the file name, prefixed with 'filename:'
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/guide-apply.adoc:
--------------------------------------------------------------------------------
1 | = guide apply
2 | Apply the instructions in the readme to the code base.
3 |
4 | == NAME
5 | guide apply
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | guide apply --file String --path String --lsp-edit boolean --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--file` String The readme file that contains the instructions for how to modify the code base, such as README-ai-jpa.md *Optional*
17 |
18 | `--path` String Path on which to run the command. Most of the time, you can not specify the path and use the default value, which is the current working directory. *Optional*
19 |
20 | `--lsp-edit` boolean LSP Edit Json is produced to be applied by an IDE or Language Server. *Optional, default = false*
21 |
22 | `--help or -h` help for guide apply *Optional*
23 |
24 |
25 | include::footers/guide-apply-footer.adoc[opts=optional]
26 |
--------------------------------------------------------------------------------
/test-data/projects/config-client/README.md:
--------------------------------------------------------------------------------
1 | # Basic Spring Config Client application
2 |
3 | This project demonstrates the use of the Spring Configuration Server client.
4 |
5 | A Controller named `MessageRestController` contains a controller with an `@Value` annotation whose value can be sourced from the Spring Configuration server
6 |
7 |
8 | ```java
9 | @RestController
10 | public class MessageRestController {
11 |
12 | @Value("${message:Hello default}")
13 | private String message;
14 |
15 | @RequestMapping("/message")
16 | public String getMessage() {
17 | return this.message;
18 | }
19 | }
20 | ```
21 |
22 | ## Building and running
23 |
24 | ```bash
25 | ./mvnw spring-boot:run
26 | ```
27 |
28 | Invoking `curl http://localhost:8080/message` will display the message.
29 |
30 | The `application.properties` file contains the configuration to connect to a Configuration server.
31 |
--------------------------------------------------------------------------------
/.github/workflows/dev-native.yml:
--------------------------------------------------------------------------------
1 | name: Dev Native
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | jobs:
7 | native:
8 | runs-on: ${{ matrix.os }}
9 | strategy:
10 | fail-fast: false
11 | matrix:
12 | include:
13 | - nickname: win
14 | os: win22-8-32
15 | graal: dev
16 | name: CI Native ${{ matrix.nickname }}
17 | steps:
18 | - uses: actions/checkout@v2
19 | - uses: graalvm/setup-graalvm@v1
20 | with:
21 | version: ${{ matrix.graal }}
22 | java-version: 21
23 | set-java-home: true
24 | github-token: ${{ secrets.GITHUB_TOKEN }}
25 | - run: ./gradlew build nativeCompile -x test
26 | - uses: actions/upload-artifact@v2
27 | with:
28 | name: spring-up-${{ matrix.nickname }}
29 | path: build/native/nativeCompile/
30 | retention-days: 1
31 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/cli/SpringCliApplicationTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli;
18 |
19 | import org.junit.jupiter.api.Test;
20 |
21 | class SpringCliApplicationTests {
22 |
23 | @Test
24 | void test() {
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/merger/ai/service/OpenAiService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.merger.ai.service;
18 |
19 | import java.util.Map;
20 |
21 | public interface OpenAiService {
22 |
23 | String generate(Map context);
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/cli/support/configfile/UserConfigTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.support.configfile;
18 |
19 | import org.junit.jupiter.api.Test;
20 |
21 | public class UserConfigTests {
22 |
23 | @Test
24 | public void test() {
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/templating/TemplateEngine.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.templating;
18 |
19 | import java.util.Map;
20 |
21 | public interface TemplateEngine {
22 |
23 | String process(String template, Map context);
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/checkstyle/checkstyle.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.github/workflows/deploy-docs.yml:
--------------------------------------------------------------------------------
1 | name: Deploy Docs
2 | on:
3 | workflow_dispatch:
4 | push:
5 | branches: [main, '[0-9].[0-9].x' ]
6 | tags: ['v[0-9].[0-9].[0-9]', 'v[0-9].[0-9].[0-9]-*']
7 |
8 | permissions:
9 | actions: write
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | if: github.repository_owner == 'spring-projects'
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v3
17 | with:
18 | ref: docs-build
19 | fetch-depth: 1
20 | - name: Dispatch (partial build)
21 | if: github.ref_type == 'branch'
22 | env:
23 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24 | run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) -f build-refname=${{ github.ref_name }}
25 | - name: Dispatch (full build)
26 | if: github.ref_type == 'tag'
27 | env:
28 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29 | run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD)
30 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/recipe/RecipeCreationException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021-2023 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.recipe;
18 |
19 | /**
20 | * @author Fabian Krüger
21 | */
22 | public class RecipeCreationException extends RuntimeException {
23 |
24 | public RecipeCreationException(String message) {
25 | super(message);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/handlers/json/IRegion.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions.handlers.json;
18 |
19 | /**
20 | * Mimicks eclipse IRegion (i.e. a region is a offset + length).
21 | */
22 | public interface IRegion {
23 |
24 | int getOffset();
25 |
26 | int getLength();
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/e2e/spring-cli-e2e-tests/src/utils.ts:
--------------------------------------------------------------------------------
1 | import * as os from 'os';
2 | import * as path from 'path';
3 |
4 | export const tempDir = path.join(__dirname, 'spring-cli', 'temp');
5 | export const isWindows = os.platform() === 'win32';
6 | export const cliPathRelative = isWindows
7 | ? '..\\..\\build\\native\\nativeCompile\\spring.exe'
8 | : '../../build/native/nativeCompile/spring';
9 | export const jarPathRelative = isWindows
10 | ? '..\\..\\build\\libs\\spring-cli-0.8.0-SNAPSHOT.jar'
11 | : '../../build/libs/spring-cli-0.8.0-SNAPSHOT.jar';
12 | export const cliPath = path.resolve(cliPathRelative);
13 | export const jarPath = path.resolve(jarPathRelative);
14 | export const nativeDesc = 'native';
15 | export const jarDesc = 'jar';
16 | export const jarCommand = isWindows ? 'java.exe' : 'java';
17 | export const nativeCommand = cliPath;
18 | export const jarOptions = ['-jar', jarPath];
19 | export const waitForExpectDefaultTimeout = 30000;
20 | export const waitForExpectDefaultInterval = 2000;
21 | export const testTimeout = 120000;
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | .gradle
3 | build/
4 | !gradle/wrapper/gradle-wrapper.jar
5 | !**/src/main/**/build/
6 | !**/src/test/**/build/
7 | *.log
8 | *.gz
9 |
10 | ### STS ###
11 | .apt_generated
12 | .classpath
13 | .factorypath
14 | .project
15 | .settings
16 | .springBeans
17 | .sts4-cache
18 | bin/
19 | !**/src/main/**/bin/
20 | !**/src/test/**/bin/
21 |
22 | ### IntelliJ IDEA ###
23 | .idea
24 | *.iws
25 | *.iml
26 | *.ipr
27 | out/
28 | !**/src/main/**/out/
29 | !**/src/test/**/out/
30 |
31 | ### NetBeans ###
32 | /nbproject/private/
33 | /nbbuild/
34 | /dist/
35 | /nbdist/
36 | /.nb-gradle/
37 |
38 | # Visual Studio Code - java
39 | .vscode/*
40 | !.vscode/settings.json
41 | !.vscode/tasks.json
42 | !.vscode/launch.json
43 | !.vscode/extensions.json
44 |
45 | # Visual Studio Code - e2e node
46 | e2e/.vscode/*
47 | !e2e/.vscode/settings.json
48 | !e2e/.vscode/tasks.json
49 | !e2e/.vscode/launch.json
50 | !e2e/.vscode/extensions.json
51 |
52 | # antora output
53 | cached-antora-playbook.yml
54 | docs/build/
55 | docs/node_modules/
56 |
--------------------------------------------------------------------------------
/src/jreleaser/images/spring-cli.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/test-data/projects/spring-data-jpa/README.md:
--------------------------------------------------------------------------------
1 | # Basic Spring Data JPA application
2 |
3 | This project contains a test class that exercises the Spring Data JPA APIs for a `Customer` entity.
4 |
5 | The class `CustomerRepository` extends the `CrudRepository` that provides basic create, retrieve, update and delete functionality for `Customer` entities.
6 |
7 | The test class `CustomerRepositoryTests` exercises the repository by persisting a new `Customer` and then retrieving it.
8 |
9 | All data is persisted in an in memory H2 database.
10 |
11 | ```java
12 | Customer customer = new Customer("first", "last");
13 | entityManager.persist(customer);
14 |
15 | List findByLastName = customers.findByLastName(customer.getLastName());
16 | ```
17 |
18 | If you run the application with the `test-data` profile, a few `Customer` entries will be created.
19 |
20 | ## Running the code
21 |
22 | To run the test and exercise the `CustomerRepository` functionality in a test
23 |
24 | ```bash
25 | ./mvnw clean package
26 | ```
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/test-data/projects/spring-data-jpa/src/main/java/com/example/up/customer/Customer.java:
--------------------------------------------------------------------------------
1 | package com.example.up.customer;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.GeneratedValue;
5 | import jakarta.persistence.GenerationType;
6 | import jakarta.persistence.Id;
7 |
8 | @Entity
9 | public class Customer {
10 |
11 | @Id
12 | @GeneratedValue(strategy=GenerationType.AUTO)
13 | private Long id;
14 | private String firstName;
15 | private String lastName;
16 |
17 | protected Customer() {}
18 |
19 | public Customer(String firstName, String lastName) {
20 | this.firstName = firstName;
21 | this.lastName = lastName;
22 | }
23 |
24 | @Override
25 | public String toString() {
26 | return String.format(
27 | "Customer[id=%d, firstName='%s', lastName='%s']",
28 | id, firstName, lastName);
29 | }
30 |
31 | public Long getId() {
32 | return id;
33 | }
34 |
35 | public String getFirstName() {
36 | return firstName;
37 | }
38 |
39 | public String getLastName() {
40 | return lastName;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/ai-add.adoc:
--------------------------------------------------------------------------------
1 | = ai add
2 | Add code to the project from AI for a Spring project.
3 |
4 | == NAME
5 | ai add
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | ai add [--description String] --path String --preview boolean --rewrite boolean --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--description` String The description of the code to create. This can be as short as a well known Spring project name, such as 'JPA'. *Mandatory*
17 |
18 | `--path` String Path on which to run the command. Most of the time, you can not specify the path and use the default value, which is the current working directory. *Optional*
19 |
20 | `--preview` boolean Create the README.md file but do not apply the changes to the code base. *Optional, default = false*
21 |
22 | `--rewrite` boolean Rewrite the 'description' option of the README.md file but do not apply the changes to the code base. *Optional, default = false*
23 |
24 | `--help or -h` help for ai add *Optional*
25 |
26 |
27 | include::footers/ai-add-footer.adoc[opts=optional]
28 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/merger/ai/ProjectArtifactType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.merger.ai;
18 |
19 | /**
20 | * The type of artifacts returned from an AI generated response to create code
21 | */
22 | public enum ProjectArtifactType {
23 |
24 | APPLICATION_PROPERTIES,
25 |
26 | MAIN_CLASS,
27 |
28 | SOURCE_CODE,
29 |
30 | TEST_CODE,
31 |
32 | MAVEN_DEPENDENCIES,
33 |
34 | HTML
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/test-data/projects/rest-service/README.adoc:
--------------------------------------------------------------------------------
1 | == Basic Spring Web Application
2 |
3 | This project contains a web service that will accept HTTP GET requests at
4 | `http://localhost:8080/greeting`.
5 |
6 | It will respond with a JSON representation of a greeting, as the following listing shows:
7 |
8 | ====
9 | [source,json]
10 | ----
11 | {"id":1,"content":"Hello, World!"}
12 | ----
13 | ====
14 |
15 | You can customize the greeting with an optional `name` parameter in the query string, as
16 | the following listing shows:
17 |
18 | ====
19 | [source,text]
20 | ----
21 | http://localhost:8080/greeting?name=User
22 | ----
23 | ====
24 |
25 | The `name` parameter value overrides the default value of `World` and is reflected in the
26 | response, as the following listing shows:
27 |
28 | ====
29 | [source,json]
30 | ----
31 | {"id":1,"content":"Hello, User!"}
32 | ----
33 | ====
34 |
35 | === Building and running
36 |
37 | [source,bash]
38 | ----
39 | ./mvnw spring-boot:run
40 | ----
41 |
42 | Then access the endpoint
43 |
44 | [source,bash]
45 | ----
46 | curl http://localhost:8080/greeting?name=User
47 | ----
--------------------------------------------------------------------------------
/src/test/java/org/springframework/cli/runtime/engine/spel/MySpringAppConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.spel;
18 |
19 | import org.springframework.context.annotation.Bean;
20 | import org.springframework.context.annotation.Configuration;
21 |
22 | @Configuration
23 | public class MySpringAppConfig {
24 |
25 | @Bean("myGreeter")
26 | public Greeter create() {
27 | return new Greeter("Bonjour ", "!");
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/test-data/projects/spring-scheduling-tasks/README.md:
--------------------------------------------------------------------------------
1 | # Basic Spring Scheudling application
2 |
3 | This project demonstrates Spring's scheduling functionality by scheduling a method to be executed every 5 seconds.
4 |
5 | ## Code
6 |
7 | To enable scheduling support in Spring, the annotation `@EnableScheduling` should be placed on the main application class.
8 |
9 | ```java
10 | @SpringBootApplication
11 | @EnableScheduling
12 | public class SchedulingTasksApplication {
13 |
14 | public static void main(String[] args) {
15 | SpringApplication.run(SchedulingTasksApplication.class);
16 | }
17 |
18 | }
19 | ```
20 |
21 | The method that is to be scheduled has the annotation `@Scheduled` with a time value for a fixed rate of executing the method
22 |
23 |
24 | ```java
25 | @Scheduled(fixedRate = 5000)
26 | public void reportCurrentTime() {
27 | log.info("The time is now {}", dateFormat.format(new Date()));
28 | }
29 | ```
30 |
31 | ## Building and running
32 |
33 | ```bash
34 | ./mvnw spring-boot:run
35 | ```
36 |
37 | You will see log output that contains the message
38 |
39 | ```bash
40 | The time is now 16:27:31
41 | ```
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/util/MavenBuildPluginReader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.util;
18 |
19 | public class MavenBuildPluginReader extends AbstractMavenReader {
20 |
21 | public MavenBuildPluginReader() {
22 | this.sectionName = "plugin";
23 | }
24 |
25 | protected String massageText(String text) {
26 | if (text.contains("")) {
27 | return text;
28 | }
29 | else {
30 | return "" + text + "";
31 | }
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/cli/CliTags.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli;
18 |
19 | /**
20 | * JUnit tags used in tests.
21 | */
22 | public final class CliTags {
23 |
24 | private CliTags() {
25 | }
26 |
27 | public static final String IT = "it";
28 |
29 | public static final String SMOKE = "smoke";
30 |
31 | public static final String AI = "ai";
32 |
33 | public static final String GITHUB = "github";
34 |
35 | public static final String GITLAB = "gitlab";
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/util/MavenDependencyReader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.util;
18 |
19 | public class MavenDependencyReader extends AbstractMavenReader {
20 |
21 | public MavenDependencyReader() {
22 | this.sectionName = "dependency";
23 | }
24 |
25 | protected String massageText(String text) {
26 | if (text.contains("")) {
27 | return text;
28 | }
29 | else {
30 | return "" + text + "";
31 | }
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/util/MavenRepositoryReader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.util;
18 |
19 | public class MavenRepositoryReader extends AbstractMavenReader {
20 |
21 | public MavenRepositoryReader() {
22 | this.sectionName = "repository";
23 | }
24 |
25 | protected String massageText(String text) {
26 | if (text.contains("")) {
27 | return text;
28 | }
29 | else {
30 | return "" + text + "";
31 | }
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/model/ModelPopulator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.model;
18 |
19 | import java.nio.file.Path;
20 | import java.util.Map;
21 |
22 | /**
23 | * Implemented by components that may contribute values to the Model used by the template
24 | * engine
25 | *
26 | * @author Mark Pollack
27 | * @author Eric Bottard
28 | */
29 | public interface ModelPopulator {
30 |
31 | void contributeToModel(Path rootDirectory, Map model);
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/test-data/projects/config-client/src/main/java/com/example/configurationclient/ConfigurationClientApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2020 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.example.configurationclient;
18 |
19 | import org.springframework.boot.SpringApplication;
20 | import org.springframework.boot.autoconfigure.SpringBootApplication;
21 |
22 |
23 | @SpringBootApplication
24 | public class ConfigurationClientApplication {
25 |
26 | public static void main(String[] args) {
27 | SpringApplication.run(ConfigurationClientApplication.class, args);
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/initializr/model/IdName.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.initializr.model;
18 |
19 | public class IdName {
20 |
21 | private String id;
22 |
23 | private String name;
24 |
25 | public IdName() {
26 | }
27 |
28 | public String getId() {
29 | return id;
30 | }
31 |
32 | public void setId(String id) {
33 | this.id = id;
34 | }
35 |
36 | public String getName() {
37 | return name;
38 | }
39 |
40 | public void setName(String name) {
41 | this.name = name;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/boot-new.adoc:
--------------------------------------------------------------------------------
1 | = boot new
2 | Create a new Spring Boot project from an existing project.
3 |
4 | == NAME
5 | boot new
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | boot new [--name String] --from String --group-id String --artifact-id String --version String --description String --package-name String --path String --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--name` String Name of the new project *Mandatory*
17 |
18 | `--from` String Create project from existing project name or URL *Optional*
19 |
20 | `--group-id` String Group ID of the new project *Optional*
21 |
22 | `--artifact-id` String Artifact ID of the new project *Optional*
23 |
24 | `--version` String Version of the new project *Optional*
25 |
26 | `--description` String Description of the new project *Optional*
27 |
28 | `--package-name` String Package name for the new project *Optional*
29 |
30 | `--path` String Path on which to run the command. Most of the time, you can not specify the path and use the default value, which is the current working directory. *Optional*
31 |
32 | `--help or -h` help for boot new *Optional*
33 |
34 |
35 | include::footers/boot-new-footer.adoc[opts=optional]
36 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/initializr/model/Dependencies.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.initializr.model;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | public class Dependencies {
23 |
24 | private List values = new ArrayList<>();
25 |
26 | public Dependencies() {
27 | }
28 |
29 | public List getValues() {
30 | return values;
31 | }
32 |
33 | public void setValues(List values) {
34 | this.values = values;
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/handlers/json/BadLocationException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions.handlers.json;
18 |
19 | public class BadLocationException extends Exception {
20 |
21 | private static final long serialVersionUID = 4005922462747639763L;
22 |
23 | public BadLocationException(Throwable e) {
24 | super(e);
25 | }
26 |
27 | public BadLocationException(String message) {
28 | super(message);
29 | }
30 |
31 | public BadLocationException() {
32 | super();
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/commands/boot-start.adoc:
--------------------------------------------------------------------------------
1 | = boot start
2 | Create a new project from start.spring.io
3 |
4 | == NAME
5 | boot start
6 |
7 | == SYNOPSIS
8 | ====
9 | [source]
10 | ----
11 | boot start --path String --project String --language String --boot-version String --version String --group String --artifact String --name String --description String --package-name String --dependencies List --packaging String --java-version String --help
12 | ----
13 | ====
14 |
15 | == OPTIONS
16 | `--path` String Path to extract *Optional*
17 |
18 | `--project` String Project *Optional*
19 |
20 | `--language` String Language *Optional*
21 |
22 | `--boot-version` String Language *Optional*
23 |
24 | `--version` String Version *Optional*
25 |
26 | `--group` String Group *Optional*
27 |
28 | `--artifact` String Artifact *Optional*
29 |
30 | `--name` String Name *Optional*
31 |
32 | `--description` String Description *Optional*
33 |
34 | `--package-name` String Package Name *Optional*
35 |
36 | `--dependencies` List Dependencies *Optional*
37 |
38 | `--packaging` String Packaging *Optional*
39 |
40 | `--java-version` String Java *Optional*
41 |
42 | `--help or -h` help for boot start *Optional*
43 |
44 |
45 | include::footers/boot-start-footer.adoc[opts=optional]
46 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/cli/runtime/engine/spel/Greeter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.spel;
18 |
19 | public class Greeter {
20 |
21 | private int calls;
22 |
23 | private String prefix;
24 |
25 | private String suffix;
26 |
27 | public Greeter(String prefix, String suffix) {
28 | this.prefix = prefix;
29 | this.suffix = suffix;
30 | }
31 |
32 | public boolean greeting(String who) {
33 | System.out.println(prefix + who + suffix);
34 | calls++;
35 | return true;
36 | }
37 |
38 | public int getCalls() {
39 | return calls;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/cli/testutil/TableAssertions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.testutil;
18 |
19 | import org.springframework.shell.table.Table;
20 |
21 | import static org.assertj.core.api.Assertions.assertThat;
22 |
23 | public final class TableAssertions {
24 |
25 | private TableAssertions() {
26 | }
27 |
28 | public static void verifyTableValue(Table table, int row, int col, Object expected) {
29 | assertThat(table.getModel().getValue(row, col))
30 | .as(String.format("Row %d, Column %d should be: %s", row, col, expected))
31 | .isEqualTo(expected);
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/SpringCliException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli;
18 |
19 | @SuppressWarnings("serial")
20 | public class SpringCliException extends RuntimeException {
21 |
22 | /**
23 | * Instantiates a new {@code UpException}.
24 | * @param message the message
25 | */
26 | public SpringCliException(String message) {
27 | super(message);
28 | }
29 |
30 | /**
31 | * Instantiates a new {@code UpException}.
32 | * @param message the message
33 | * @param cause the cause
34 | */
35 | public SpringCliException(String message, Throwable cause) {
36 | super(message, cause);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/merger/ai/ProjectArtifactCreator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.merger.ai;
18 |
19 | import java.util.List;
20 |
21 | import org.commonmark.node.Node;
22 | import org.commonmark.parser.Parser;
23 |
24 | public class ProjectArtifactCreator {
25 |
26 | public List create(String response) {
27 | Parser parser = Parser.builder().build();
28 | Node node = parser.parse(response);
29 |
30 | MarkdownResponseVisitor markdownResponseVisitor = new MarkdownResponseVisitor();
31 | node.accept(markdownResponseVisitor);
32 |
33 | return markdownResponseVisitor.getProjectArtifacts();
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/initializr/model/Name.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.initializr.model;
18 |
19 | import com.fasterxml.jackson.annotation.JsonProperty;
20 |
21 | public class Name {
22 |
23 | @JsonProperty("default")
24 | private String defaultId;
25 |
26 | private String type;
27 |
28 | public Name() {
29 | }
30 |
31 | public String getDefault() {
32 | return defaultId;
33 | }
34 |
35 | public void setDefault(String defaultId) {
36 | this.defaultId = defaultId;
37 | }
38 |
39 | public String getType() {
40 | return type;
41 | }
42 |
43 | public void setType(String type) {
44 | this.type = type;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/nav.adoc:
--------------------------------------------------------------------------------
1 | * xref:index.adoc[Overview]
2 | * xref:installation.adoc[Installation]
3 | * xref:getting-started.adoc[Getting Started]
4 | * xref:key-concepts.adoc[Key Concepts]
5 | * xref:ref/index.adoc[]
6 | ** xref:ref/project/index.adoc[]
7 | *** xref:ref/project/comments-on-the-approach.adoc[Comments on the Approach]
8 | *** xref:ref/project/creating-new-projects.adoc[Creating New Projects]
9 | *** xref:ref/project/adding-to-existing-projects.adoc[Adding to Existing Projects]
10 | ** xref:ref/catalog/index.adoc[]
11 | *** xref:ref/catalog/registering-new-projects.adoc[]
12 | ** xref:ref/actionfile/index.adoc[]
13 | *** xref:ref/actionfile/action-guide.adoc[Guide to Action Files]
14 | *** xref:ref/actionfile/roles-guide.adoc[Guide to Roles]
15 | ** xref:ref/usercommand/index.adoc[]
16 | *** xref:ref/usercommand/user-command-guide.adoc[User defined Commands]
17 | *** xref:ref/usercommand/action-file-overview.adoc[Overview of Action Files]
18 | ** xref:ref/ai/index.adoc[]
19 | *** xref:ref/ai/readme-command-guide.adoc[Guide to README Commands]
20 | * xref:howto/index.adoc[]
21 | ** xref:howto/boot-add-guide.adoc[Using "boot add"]
22 | ** xref:howto/ai-guide.adoc[Guide to "ai Commands"]
23 | ** xref:howto/special-commands-guide.adoc[Guide to Special Commands]
24 | ** xref:howto/create-application.adoc[]
25 | * xref:glossary.adoc[Glossary]
26 |
--------------------------------------------------------------------------------
/src/jreleaser/templates/jlink/brew/formula-multi.rb.tpl:
--------------------------------------------------------------------------------
1 | # {{jreleaserCreationStamp}}
2 | class {{brewFormulaName}} < Formula
3 | desc "{{projectDescription}}"
4 | homepage "{{projectLinkHomepage}}"
5 | version "{{projectVersion}}"
6 | license "{{projectLicense}}"
7 |
8 | {{brewMultiPlatform}}
9 |
10 | {{#brewHasLivecheck}}
11 | livecheck do
12 | {{#brewLivecheck}}
13 | {{.}}
14 | {{/brewLivecheck}}
15 | end
16 | {{/brewHasLivecheck}}
17 | {{#brewDependencies}}
18 | depends_on {{.}}
19 | {{/brewDependencies}}
20 |
21 | def install
22 | libexec.install Dir["*"]
23 | bin.install_symlink "#{libexec}/bin/{{distributionExecutableUnix}}" => "{{distributionExecutableName}}"
24 | bash_completion.install Dir["#{libexec}/completion/bash/spring"]
25 | zsh_completion.install Dir["#{libexec}/completion/zsh/_spring"]
26 | end
27 |
28 | def post_install
29 | if OS.mac?
30 | Dir["#{libexec}/lib/**/*.dylib"].each do |dylib|
31 | chmod 0664, dylib
32 | MachO::Tools.change_dylib_id(dylib, "@rpath/#{File.basename(dylib)}")
33 | MachO.codesign!(dylib)
34 | chmod 0444, dylib
35 | end
36 | end
37 | end
38 |
39 | test do
40 | output = shell_output("#{bin}/{{distributionExecutableName}} --version")
41 | assert_match "{{projectVersion}}", output
42 | end
43 | end
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/initializr/model/GroupId.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.initializr.model;
18 |
19 | import com.fasterxml.jackson.annotation.JsonProperty;
20 |
21 | public class GroupId {
22 |
23 | @JsonProperty("default")
24 | private String defaultId;
25 |
26 | private String type;
27 |
28 | public GroupId() {
29 | }
30 |
31 | public String getDefault() {
32 | return defaultId;
33 | }
34 |
35 | public void setDefault(String defaultId) {
36 | this.defaultId = defaultId;
37 | }
38 |
39 | public String getType() {
40 | return type;
41 | }
42 |
43 | public void setType(String type) {
44 | this.type = type;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/initializr/model/Version.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.initializr.model;
18 |
19 | import com.fasterxml.jackson.annotation.JsonProperty;
20 |
21 | public class Version {
22 |
23 | @JsonProperty("default")
24 | private String defaultId;
25 |
26 | private String type;
27 |
28 | public Version() {
29 | }
30 |
31 | public String getDefault() {
32 | return defaultId;
33 | }
34 |
35 | public void setDefault(String defaultId) {
36 | this.defaultId = defaultId;
37 | }
38 |
39 | public String getType() {
40 | return type;
41 | }
42 |
43 | public void setType(String type) {
44 | this.type = type;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/initializr/model/Dependency.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.initializr.model;
18 |
19 | public class Dependency extends IdName {
20 |
21 | private String description;
22 |
23 | private String versionRange;
24 |
25 | public Dependency() {
26 | }
27 |
28 | public String getDescription() {
29 | return description;
30 | }
31 |
32 | public void setDescription(String description) {
33 | this.description = description;
34 | }
35 |
36 | public String getVersionRange() {
37 | return versionRange;
38 | }
39 |
40 | public void setVersionRange(String versionRange) {
41 | this.versionRange = versionRange;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/initializr/model/ArtifactId.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.initializr.model;
18 |
19 | import com.fasterxml.jackson.annotation.JsonProperty;
20 |
21 | public class ArtifactId {
22 |
23 | @JsonProperty("default")
24 | private String defaultId;
25 |
26 | private String type;
27 |
28 | public ArtifactId() {
29 | }
30 |
31 | public String getDefault() {
32 | return defaultId;
33 | }
34 |
35 | public void setDefault(String defaultId) {
36 | this.defaultId = defaultId;
37 | }
38 |
39 | public String getType() {
40 | return type;
41 | }
42 |
43 | public void setType(String type) {
44 | this.type = type;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/Var.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions;
18 |
19 | import com.fasterxml.jackson.annotation.JsonCreator;
20 | import com.fasterxml.jackson.annotation.JsonProperty;
21 |
22 | import org.springframework.lang.Nullable;
23 |
24 | public class Var {
25 |
26 | private From from;
27 |
28 | @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
29 | Var(@JsonProperty("from") @Nullable From from) {
30 | this.from = from;
31 | }
32 |
33 | public From getFrom() {
34 | return from;
35 | }
36 |
37 | @Override
38 | public String toString() {
39 | return "Var{" + "from=" + from + '}';
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/initializr/model/Description.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.initializr.model;
18 |
19 | import com.fasterxml.jackson.annotation.JsonProperty;
20 |
21 | public class Description {
22 |
23 | @JsonProperty("default")
24 | private String defaultId;
25 |
26 | private String type;
27 |
28 | public Description() {
29 | }
30 |
31 | public String getDefault() {
32 | return defaultId;
33 | }
34 |
35 | public void setDefault(String defaultId) {
36 | this.defaultId = defaultId;
37 | }
38 |
39 | public String getType() {
40 | return type;
41 | }
42 |
43 | public void setType(String type) {
44 | this.type = type;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/initializr/model/PackageName.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.initializr.model;
18 |
19 | import com.fasterxml.jackson.annotation.JsonProperty;
20 |
21 | public class PackageName {
22 |
23 | @JsonProperty("default")
24 | private String defaultId;
25 |
26 | private String type;
27 |
28 | public PackageName() {
29 | }
30 |
31 | public String getDefault() {
32 | return defaultId;
33 | }
34 |
35 | public void setDefault(String defaultId) {
36 | this.defaultId = defaultId;
37 | }
38 |
39 | public String getType() {
40 | return type;
41 | }
42 |
43 | public void setType(String type) {
44 | this.type = type;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/util/NamingUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.util;
18 |
19 | public final class NamingUtils {
20 |
21 | private NamingUtils() {
22 | }
23 |
24 | public static String toKebab(CharSequence original) {
25 | StringBuilder result = new StringBuilder(original.length());
26 | boolean wasLowercase = false;
27 | for (int i = 0; i < original.length(); i++) {
28 | char ch = original.charAt(i);
29 | if (Character.isUpperCase(ch) && wasLowercase) {
30 | result.append('-');
31 | }
32 | wasLowercase = Character.isLowerCase(ch);
33 | result.append(Character.toLowerCase(ch));
34 | }
35 | return result.toString();
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "**/.vscode": true,
4 | "bin": true,
5 | "gradle": true,
6 | "e2e": true
7 | },
8 | "java.completion.importOrder": [
9 | "java",
10 | "javax",
11 | "",
12 | "org.springframework",
13 | "#"
14 | ],
15 | "java.checkstyle.configuration": "https://raw.githubusercontent.com/spring-cloud/spring-cloud-dataflow-build/main/spring-cloud-dataflow-build-tools/src/main/resources/checkstyle.xml",
16 | "java.checkstyle.properties": {
17 | "checkstyle.suppressions.file": "https://raw.githubusercontent.com/spring-cloud/spring-cloud-dataflow-build/main/spring-cloud-dataflow-build-tools/src/checkstyle/checkstyle-suppressions.xml",
18 | "checkstyle.additional.suppressions.file": "https://raw.githubusercontent.com/spring-cloud/spring-cloud-dataflow-build/main/spring-cloud-dataflow-build-tools/src/checkstyle/checkstyle-suppressions-empty.xml",
19 | "checkstyle.header.file": "https://raw.githubusercontent.com/spring-cloud/spring-cloud-dataflow-build/main/spring-cloud-dataflow-build-tools/src/main/resources/checkstyle-header.txt"
20 | },
21 | "java.checkstyle.version": "8.29",
22 | "java.configuration.maven.notCoveredPluginExecutionSeverity": "ignore",
23 | "java.configuration.updateBuildConfiguration": "interactive"
24 | }
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/git/SourceRepositoryService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.git;
18 |
19 | import java.nio.file.Path;
20 |
21 | /**
22 | * @author Thomas Risberg
23 | */
24 | public interface SourceRepositoryService {
25 |
26 | /**
27 | * Retrieve contents from a source repository.
28 | * @param sourceRepoUrl the URL of the repository to retrieve the content for.
29 | * Supported URL schemes are file:// and https://. The latter can refer to a GitHub
30 | * (host is github.com) repository or a GitLab repository.
31 | * @return the full Path to where the contents have been retrieved
32 | */
33 | Path retrieveRepositoryContents(String sourceRepoUrl);
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/.github/workflows/jr-build.yml:
--------------------------------------------------------------------------------
1 | name: JR Build
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | ref:
7 | required: true
8 | type: string
9 | version:
10 | required: true
11 | type: string
12 |
13 | jobs:
14 | build:
15 | runs-on: ubuntu-latest
16 | name: Build
17 | steps:
18 | - uses: actions/checkout@v3
19 | with:
20 | ref: ${{ inputs.ref }}
21 | - uses: actions/setup-java@v3
22 | with:
23 | distribution: adopt
24 | java-version: 17
25 | cache: gradle
26 | - name: Gradle Build
27 | run: ./gradlew build -x test --no-daemon -PcliRelease=true
28 | - name: Completion Files
29 | run: |
30 | mkdir -p build/completion/bash
31 | mkdir -p build/completion/zsh
32 | java -jar build/libs/spring-cli-${{ inputs.version }}.jar completion bash > build/completion/bash/spring
33 | java -jar build/libs/spring-cli-${{ inputs.version }}.jar completion zsh > build/completion/zsh/_spring
34 | - uses: actions/upload-artifact@v3
35 | with:
36 | name: fatjar
37 | path: build/libs/*.jar
38 | retention-days: 1
39 | - uses: actions/upload-artifact@v3
40 | with:
41 | name: completion
42 | path: build/completion
43 | retention-days: 1
44 |
--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.234.0/containers/java
3 | {
4 | "name": "Java",
5 | "build": {
6 | "dockerfile": "Dockerfile",
7 | "args": {
8 | // Update the VARIANT arg to pick a Java version: 11, 17
9 | // Append -bullseye or -buster to pin to an OS version.
10 | // Use the -bullseye variants on local arm64/Apple Silicon.
11 | "VARIANT": "11-bullseye",
12 | // Options
13 | "INSTALL_JAVA": "true",
14 | "JAVA_VERSION": "22.1.0.r11-grl",
15 | "INSTALL_MAVEN": "false",
16 | "INSTALL_GRADLE": "true",
17 | "GRADLE_VERSION": "7.3.3",
18 | "NODE_VERSION": "none"
19 | }
20 | },
21 |
22 | // Set *default* container specific settings.json values on container create.
23 | "settings": {
24 | "java.jdt.ls.java.home": "/docker-java-home"
25 | },
26 |
27 | // Add the IDs of extensions you want installed when the container is created.
28 | "extensions": [
29 | "vscjava.vscode-java-pack"
30 | ],
31 |
32 | "updateContentCommand": "./gradlew --no-daemon --quiet build -x test || true",
33 |
34 | // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
35 | "remoteUser": "vscode",
36 | "features": {
37 | "github-cli": "latest"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/initializr/model/DependencyCategory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.initializr.model;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | public class DependencyCategory {
23 |
24 | private String name;
25 |
26 | private List values = new ArrayList<>();
27 |
28 | public DependencyCategory() {
29 | }
30 |
31 | public String getName() {
32 | return name;
33 | }
34 |
35 | public void setName(String name) {
36 | this.name = name;
37 | }
38 |
39 | public List getValues() {
40 | return values;
41 | }
42 |
43 | public void setValues(List values) {
44 | this.values = values;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/merger/ai/ProjectDependency.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.merger.ai;
18 |
19 | public class ProjectDependency {
20 |
21 | private final String groupId;
22 |
23 | private final String artifactId;
24 |
25 | public ProjectDependency(String groupId, String artifactId) {
26 | this.groupId = groupId;
27 | this.artifactId = artifactId;
28 | }
29 |
30 | public String getGroupId() {
31 | return groupId;
32 | }
33 |
34 | public String getArtifactId() {
35 | return artifactId;
36 | }
37 |
38 | @Override
39 | public String toString() {
40 | return "ProjectDependency{" + "groupId='" + groupId + '\'' + ", artifactId='" + artifactId + '\'' + '}';
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/test-data/projects/config-client/src/main/java/com/example/configurationclient/controller/MessageRestController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 |
18 | package com.example.configurationclient.controller;
19 |
20 | import org.springframework.beans.factory.annotation.Value;
21 | import org.springframework.cloud.context.config.annotation.RefreshScope;
22 | import org.springframework.web.bind.annotation.RequestMapping;
23 | import org.springframework.web.bind.annotation.RestController;
24 |
25 | @RefreshScope
26 | @RestController
27 | public class MessageRestController {
28 |
29 | @Value("${message:Hello default}")
30 | private String message;
31 |
32 | @RequestMapping("/message")
33 | public String getMessage() {
34 | return this.message;
35 | }
36 | }
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/config/SpringCliPromptProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.config;
18 |
19 | import org.jline.utils.AttributedString;
20 | import org.jline.utils.AttributedStyle;
21 |
22 | import org.springframework.shell.jline.PromptProvider;
23 | import org.springframework.stereotype.Component;
24 |
25 | /**
26 | * Defines a {@link PromptProvider} for interactive mode.
27 | *
28 | * @author Janne Valkealahti
29 | */
30 | @Component
31 | public class SpringCliPromptProvider implements PromptProvider {
32 |
33 | @Override
34 | public AttributedString getPrompt() {
35 | return new AttributedString("spring:>", AttributedStyle.DEFAULT.foreground(AttributedStyle.YELLOW));
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/merger/ai/PromptRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.merger.ai;
18 |
19 | public class PromptRequest {
20 |
21 | private String systemPrompt;
22 |
23 | private String userPrompt;
24 |
25 | public PromptRequest(String systemPrompt, String userPrompt) {
26 | this.systemPrompt = systemPrompt;
27 | this.userPrompt = userPrompt;
28 | }
29 |
30 | public String getSystemPrompt() {
31 | return systemPrompt;
32 | }
33 |
34 | public String getUserPrompt() {
35 | return userPrompt;
36 | }
37 |
38 | @Override
39 | public String toString() {
40 | return "PromptRequest{" + "systemPrompt='" + systemPrompt + '\'' + ", userPrompt='" + userPrompt + '\'' + '}';
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/Options.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions;
18 |
19 | import com.fasterxml.jackson.annotation.JsonCreator;
20 | import com.fasterxml.jackson.annotation.JsonProperty;
21 |
22 | import org.springframework.lang.Nullable;
23 |
24 | public class Options {
25 |
26 | @Nullable
27 | private Exec exec;
28 |
29 | @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
30 | Options(@JsonProperty("exec") @Nullable Exec exec) {
31 | this.exec = exec;
32 | }
33 |
34 | @Nullable
35 | public Exec getExec() {
36 | return exec;
37 | }
38 |
39 | @Override
40 | public String toString() {
41 | return "Options{" + "exec=" + exec + '}';
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/.github/workflows/jr-assemble-javaarchive.yml:
--------------------------------------------------------------------------------
1 | name: JR Assemble JavaArchive
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | ref:
7 | required: true
8 | type: string
9 | version:
10 | required: true
11 | type: string
12 |
13 | jobs:
14 | assemble:
15 | runs-on: ubuntu-latest
16 | name: Assemble
17 | steps:
18 | - uses: actions/checkout@v3
19 | with:
20 | ref: ${{ inputs.ref }}
21 | - uses: actions/setup-java@v3
22 | with:
23 | distribution: adopt
24 | java-version: 17
25 | cache: gradle
26 | - name: Download fatjar
27 | uses: actions/download-artifact@v3
28 | with:
29 | name: fatjar
30 | path: build/libs
31 | - name: Download completion
32 | uses: actions/download-artifact@v3
33 | with:
34 | name: completion
35 | path: build/completion
36 | - name: JR Assemble
37 | uses: jreleaser/release-action@v2
38 | with:
39 | version: 1.12.0
40 | arguments: assemble --assembler javaArchive
41 | env:
42 | JRELEASER_PROJECT_VERSION: ${{ inputs.version }}
43 | - uses: actions/upload-artifact@v3
44 | with:
45 | name: javaarchive
46 | path: out/jreleaser/assemble/spring-cli/java-archive/*.zip
47 | retention-days: 1
48 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/merger/ai/ProcessArtifactResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.merger.ai;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | public class ProcessArtifactResult {
23 |
24 | List notProcessedArtifacts = new ArrayList<>();
25 |
26 | private T result;
27 |
28 | public List getNotProcessedArtifacts() {
29 | return notProcessedArtifacts;
30 | }
31 |
32 | public void addToNotProcessed(ProjectArtifact projectArtifact) {
33 | notProcessedArtifacts.add(projectArtifact);
34 | }
35 |
36 | public T getResult() {
37 | return result;
38 | }
39 |
40 | void setResult(T result) {
41 | this.result = result;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/From.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions;
18 |
19 | import com.fasterxml.jackson.annotation.JsonCreator;
20 | import com.fasterxml.jackson.annotation.JsonProperty;
21 |
22 | import org.springframework.lang.Nullable;
23 |
24 | public class From {
25 |
26 | private Question question;
27 |
28 | @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
29 | From(@JsonProperty("question") @Nullable Question question) {
30 | this.question = question;
31 | }
32 |
33 | public Question getQuestion() {
34 | return question;
35 | }
36 |
37 | @Override
38 | public String toString() {
39 | return "From{" + "question=" + question + '}';
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | paths-ignore:
7 | - '.github/**'
8 | schedule:
9 | - cron: '0 0 * * *'
10 |
11 | jobs:
12 | build:
13 | runs-on: ${{ matrix.os }}
14 | strategy:
15 | fail-fast: false
16 | matrix:
17 | include:
18 | - nickname: macos
19 | os: macos-latest
20 | - nickname: linux
21 | os: ubuntu-latest
22 | - nickname: windows
23 | os: windows-latest
24 | name: CI Build
25 | steps:
26 | - uses: actions/checkout@v2
27 | - uses: actions/setup-java@v2
28 | with:
29 | distribution: adopt
30 | java-version: 17
31 | cache: gradle
32 | - run: ./gradlew build --no-daemon
33 | - uses: actions/upload-artifact@v3
34 | if: ${{ failure() }}
35 | with:
36 | name: buildreports-${{ matrix.nickname }}
37 | path: build/reports
38 | retention-days: 1
39 | ea:
40 | runs-on: ubuntu-latest
41 | if: github.repository_owner == 'spring-projects' && github.ref_name == 'main' && github.event_name == 'push'
42 | needs: build
43 | steps:
44 | - uses: actions/checkout@v2
45 | - name: Dispatch early access
46 | env:
47 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
48 | run: gh workflow run jr-ea.yml -r main
49 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/cli/runtime/engine/spel/SimpleBeanResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.spel;
18 |
19 | import org.springframework.context.ApplicationContext;
20 | import org.springframework.expression.BeanResolver;
21 | import org.springframework.expression.EvaluationContext;
22 |
23 | public class SimpleBeanResolver implements BeanResolver {
24 |
25 | private ApplicationContext applicationContext;
26 |
27 | public SimpleBeanResolver(ApplicationContext applicationContext) {
28 | this.applicationContext = applicationContext;
29 | }
30 |
31 | @Override
32 | public Object resolve(EvaluationContext context, String beanName) {
33 | return applicationContext.getBean(beanName);
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/ActionStatus.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions;
18 |
19 | public enum ActionStatus {
20 |
21 | SUCCESS("success"),
22 |
23 | FAILURE("failure"),
24 |
25 | SKIPPED("skipped");
26 |
27 | private final String value;
28 |
29 | ActionStatus(String value) {
30 | this.value = value;
31 | }
32 |
33 | public String getValue() {
34 | return value;
35 | }
36 |
37 | public static ActionStatus fromValue(String value) {
38 | for (ActionStatus status : ActionStatus.values()) {
39 | if (status.getValue().equals(value)) {
40 | return status;
41 | }
42 | }
43 | throw new IllegalArgumentException("Invalid action status: " + value);
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/ref/project/adding-to-existing-projects.adoc:
--------------------------------------------------------------------------------
1 | = Adding To Existing Projects
2 |
3 | You can use two methods to add code to existing projects:
4 |
5 | * <>
6 | * <>
7 |
8 | [[adding-using-boot-add-command]]
9 | == Using the Boot Add Command
10 |
11 | The `boot add` command allows for intelligent merging of an existing project into the current project.
12 | The code of the existing project, located in a source code repository, is checked out into a temporary directory.
13 | The package structure of the existing project is then refactored to match the current project.
14 | Finally, all code and configuration are copied from the temporary location, creating new files or updating existing ones as necessary.
15 |
16 | [[adding-using-user-defined-commands]]
17 | == Using User-Defined commands
18 |
19 | You can register commands that you define with the shell. Adding code or configuration to an existing project is accomplished through action files that contain instructions on what code or configuration needs to be generated and how it should be incorporated into the current project.
20 | The template engine uses Handlebars, which models the content of the code or configuration to be added to a new file or injected into an existing file.
21 | In addition, actions can execute shell actions, modify the Maven pom.xml file, and perform other tasks as needed.
22 |
--------------------------------------------------------------------------------
/e2e/spring-cli-e2e-tests/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spring-cli-e2e-tests",
3 | "version": "0.0.1",
4 | "description": "e2e tests for spring-cli",
5 | "main": "index.js",
6 | "scripts": {
7 | "format": "prettier --write **/*.ts",
8 | "format-check": "prettier --check **/*.ts",
9 | "test": "jest",
10 | "build-spring-shell-e2e": "npm --prefix node_modules/spring-shell-e2e run build"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/spring-projects-experimental/spring-cli.git"
15 | },
16 | "author": "",
17 | "license": "MIT",
18 | "bugs": {
19 | "url": "https://github.com/spring-projects-experimental/spring-cli/issues"
20 | },
21 | "homepage": "https://github.com/spring-projects-experimental/spring-cli",
22 | "devDependencies": {
23 | "@actions/io": "^1.1.2",
24 | "@alex_neo/jest-expect-message": "^1.0.5",
25 | "@types/jest": "^27.4.1",
26 | "@types/jest-expect-message": "^1.0.3",
27 | "@types/lodash": "^4.14.172",
28 | "@types/node": "^15.6.0",
29 | "jest": "^27.5.1",
30 | "jest-circus": "^27.5.1",
31 | "jest-extended": "^2.0.0",
32 | "jest-junit": "^13.2.0",
33 | "prettier": "^2.3.0",
34 | "ts-jest": "^27.1.3",
35 | "typescript": "^4.6.2",
36 | "wait-for-expect": "^3.0.2"
37 | },
38 | "dependencies": {
39 | "spring-shell-e2e": "https://gitpkg.vercel.app/spring-projects/spring-shell/e2e/spring-shell-e2e?main"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/test-data/projects/spring-scheduling-tasks/src/test/java/com/example/schedulingtasks/SchedulingTasksApplicationTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2015 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.example.schedulingtasks;
18 |
19 | import static org.assertj.core.api.Assertions.assertThat;
20 |
21 | import com.example.schedulingtasks.scheduling.ScheduledTasks;
22 | import org.junit.jupiter.api.Test;
23 |
24 | import org.springframework.beans.factory.annotation.Autowired;
25 | import org.springframework.boot.test.context.SpringBootTest;
26 |
27 | @SpringBootTest
28 | public class SchedulingTasksApplicationTest {
29 |
30 | @Autowired
31 | private ScheduledTasks tasks;
32 |
33 | @Test
34 | public void contextLoads() {
35 | // Basic integration test that shows the context starts up properly
36 | assertThat(tasks).isNotNull();
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/merger/AddImportRecipe.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.merger;
18 |
19 | import org.openrewrite.ExecutionContext;
20 | import org.openrewrite.Recipe;
21 | import org.openrewrite.TreeVisitor;
22 | import org.openrewrite.java.AddImport;
23 |
24 | public class AddImportRecipe extends Recipe {
25 |
26 | private AddImport addImport;
27 |
28 | public AddImportRecipe(AddImport addImport) {
29 | this.addImport = addImport;
30 | }
31 |
32 | @Override
33 | public String getDisplayName() {
34 | return "Add import recipe";
35 | }
36 |
37 | @Override
38 | public String getDescription() {
39 | return getDisplayName();
40 | }
41 |
42 | @Override
43 | public TreeVisitor, ExecutionContext> getVisitor() {
44 | return addImport;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/merger/ai/ProjectName.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.merger.ai;
18 |
19 | public class ProjectName {
20 |
21 | private final String shortPackageName;
22 |
23 | private final String springProjectName;
24 |
25 | public ProjectName(String shortName, String springProjectName) {
26 | this.shortPackageName = shortName;
27 | this.springProjectName = springProjectName;
28 | }
29 |
30 | public String getShortPackageName() {
31 | return shortPackageName;
32 | }
33 |
34 | public String getSpringProjectName() {
35 | return springProjectName;
36 | }
37 |
38 | @Override
39 | public String toString() {
40 | return "ProjectName{" + "shortPackageName='" + shortPackageName + '\'' + ", springProjectName='"
41 | + springProjectName + '\'' + '}';
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/InjectMavenDependency.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions;
18 |
19 | import java.util.Objects;
20 |
21 | import com.fasterxml.jackson.annotation.JsonCreator;
22 | import com.fasterxml.jackson.annotation.JsonProperty;
23 |
24 | /**
25 | * @author Mark Pollack
26 | */
27 | public class InjectMavenDependency {
28 |
29 | private String text;
30 |
31 | @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
32 | public InjectMavenDependency(@JsonProperty("text") String text) {
33 | this.text = Objects.requireNonNull(text);
34 | }
35 |
36 | public String getText() {
37 | return text;
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return "InjectMavenDependency{" + "text='" + text + '\'' + '}';
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/InjectMavenRepository.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions;
18 |
19 | import java.util.Objects;
20 |
21 | import com.fasterxml.jackson.annotation.JsonCreator;
22 | import com.fasterxml.jackson.annotation.JsonProperty;
23 |
24 | /**
25 | * @author Mark Pollack
26 | */
27 | public class InjectMavenRepository {
28 |
29 | private String text;
30 |
31 | @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
32 | public InjectMavenRepository(@JsonProperty("text") String text) {
33 | this.text = Objects.requireNonNull(text);
34 | }
35 |
36 | public String getText() {
37 | return text;
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return "InjectMavenRepository{" + "text='" + text + '\'' + '}';
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/InjectMavenBuildPlugin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions;
18 |
19 | import java.util.Objects;
20 |
21 | import com.fasterxml.jackson.annotation.JsonCreator;
22 | import com.fasterxml.jackson.annotation.JsonProperty;
23 |
24 | /**
25 | * @author Mark Pollack
26 | */
27 | public class InjectMavenBuildPlugin {
28 |
29 | private String text;
30 |
31 | @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
32 | public InjectMavenBuildPlugin(@JsonProperty("text") String text) {
33 | this.text = Objects.requireNonNull(text);
34 | }
35 |
36 | public String getText() {
37 | return text;
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return "InjectMavenBuildPlugin{" + "text='" + text + '\'' + '}';
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/test-data/projects/spring-scheduling-tasks/src/main/java/com/example/schedulingtasks/scheduling/ScheduledTasks.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2015 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.example.schedulingtasks.scheduling;
18 |
19 | import java.text.SimpleDateFormat;
20 | import java.util.Date;
21 |
22 | import org.slf4j.Logger;
23 | import org.slf4j.LoggerFactory;
24 | import org.springframework.scheduling.annotation.Scheduled;
25 | import org.springframework.stereotype.Component;
26 |
27 | @Component
28 | public class ScheduledTasks {
29 |
30 | private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);
31 |
32 | private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
33 |
34 | @Scheduled(fixedRate = 5000)
35 | public void reportCurrentTime() {
36 | log.info("The time is now {}", dateFormat.format(new Date()));
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/.github/workflows/jr-ga.yml:
--------------------------------------------------------------------------------
1 | name: GA
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | version:
7 | description: 'Release version like, 1.0.0, 1.0.0-RC1, etc'
8 | required: true
9 |
10 | jobs:
11 |
12 | precheck:
13 | uses: ./.github/workflows/jr-version.yml
14 | with:
15 | version: ${{ github.event.inputs.version }}
16 | build:
17 | needs: [precheck]
18 | uses: ./.github/workflows/jr-build.yml
19 | with:
20 | ref: ${{ needs.precheck.outputs.ref }}
21 | version: ${{ needs.precheck.outputs.version }}
22 | javaarchive:
23 | needs: [precheck,build]
24 | uses: ./.github/workflows/jr-assemble-javaarchive.yml
25 | with:
26 | ref: ${{ needs.precheck.outputs.ref }}
27 | version: ${{ needs.precheck.outputs.version }}
28 | jlink:
29 | needs: [precheck,build]
30 | uses: ./.github/workflows/jr-assemble-jlink.yml
31 | with:
32 | ref: ${{ needs.precheck.outputs.ref }}
33 | version: ${{ needs.precheck.outputs.version }}
34 | jpackage:
35 | needs: [precheck,jlink]
36 | uses: ./.github/workflows/jr-assemble-jpackage.yml
37 | with:
38 | ref: ${{ needs.precheck.outputs.ref }}
39 | version: ${{ needs.precheck.outputs.version }}
40 | release:
41 | needs: [precheck,javaarchive,jpackage]
42 | uses: ./.github/workflows/jr-release.yml
43 | secrets: inherit
44 | with:
45 | ref: ${{ needs.precheck.outputs.ref }}
46 | version: ${{ needs.precheck.outputs.version }}
47 |
48 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/initializr/model/BootVersion.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.initializr.model;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | import com.fasterxml.jackson.annotation.JsonProperty;
23 |
24 | public class BootVersion {
25 |
26 | @JsonProperty("default")
27 | private String defaultversion;
28 |
29 | private List values = new ArrayList<>();
30 |
31 | public BootVersion() {
32 | }
33 |
34 | public String getDefaultversion() {
35 | return defaultversion;
36 | }
37 |
38 | public void setDefaultversion(String defaultversion) {
39 | this.defaultversion = defaultversion;
40 | }
41 |
42 | public List getValues() {
43 | return values;
44 | }
45 |
46 | public void setValues(List values) {
47 | this.values = values;
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/InjectMavenDependencyManagement.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions;
18 |
19 | import java.util.Objects;
20 |
21 | import com.fasterxml.jackson.annotation.JsonCreator;
22 | import com.fasterxml.jackson.annotation.JsonProperty;
23 |
24 | /**
25 | * @author Mark Pollack
26 | */
27 | public class InjectMavenDependencyManagement {
28 |
29 | private String text;
30 |
31 | @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
32 | public InjectMavenDependencyManagement(@JsonProperty("text") String text) {
33 | this.text = Objects.requireNonNull(text);
34 | }
35 |
36 | public String getText() {
37 | return text;
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return "InjectMavenDependency{" + "text='" + text + '\'' + '}';
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/model/RootPackageModelPopulator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.model;
18 |
19 | import java.io.File;
20 | import java.nio.file.Path;
21 | import java.util.Map;
22 | import java.util.Optional;
23 |
24 | import org.springframework.cli.util.RootPackageFinder;
25 |
26 | public class RootPackageModelPopulator implements ModelPopulator {
27 |
28 | @Override
29 | public void contributeToModel(Path rootDirectory, Map model) {
30 | Optional rootPackage = RootPackageFinder.findRootPackage(rootDirectory.toFile());
31 | if (rootPackage.isPresent()) {
32 | String packageDir = rootPackage.get().replace('.', File.separatorChar);
33 | model.put("root-package", rootPackage.get());
34 | model.put("root-package-dir", packageDir);
35 | }
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/.github/workflows/jr-ea.yml:
--------------------------------------------------------------------------------
1 | name: Early Access
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | concurrency:
7 | group: jr-ea
8 | cancel-in-progress: true
9 |
10 | jobs:
11 |
12 | precheck:
13 | if: github.repository_owner == 'spring-projects' || github.event_name == 'workflow_dispatch'
14 | uses: ./.github/workflows/jr-version.yml
15 | with:
16 | version:
17 | build:
18 | needs: [precheck]
19 | uses: ./.github/workflows/jr-build.yml
20 | with:
21 | ref: ${{ needs.precheck.outputs.ref }}
22 | version: ${{ needs.precheck.outputs.version }}
23 | javaarchive:
24 | needs: [precheck,build]
25 | uses: ./.github/workflows/jr-assemble-javaarchive.yml
26 | with:
27 | ref: ${{ needs.precheck.outputs.ref }}
28 | version: ${{ needs.precheck.outputs.version }}
29 | jlink:
30 | needs: [precheck,build]
31 | uses: ./.github/workflows/jr-assemble-jlink.yml
32 | with:
33 | ref: ${{ needs.precheck.outputs.ref }}
34 | version: ${{ needs.precheck.outputs.version }}
35 | jpackage:
36 | needs: [precheck,jlink]
37 | uses: ./.github/workflows/jr-assemble-jpackage.yml
38 | with:
39 | ref: ${{ needs.precheck.outputs.ref }}
40 | version: ${{ needs.precheck.outputs.version }}
41 | release:
42 | needs: [precheck,javaarchive,jpackage]
43 | uses: ./.github/workflows/jr-release.yml
44 | secrets: inherit
45 | with:
46 | ref: ${{ needs.precheck.outputs.ref }}
47 | version: ${{ needs.precheck.outputs.version }}
48 |
49 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/ActionsFile.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions;
18 |
19 | import java.util.List;
20 | import java.util.Objects;
21 |
22 | import com.fasterxml.jackson.annotation.JsonCreator;
23 | import com.fasterxml.jackson.annotation.JsonProperty;
24 |
25 | import org.springframework.lang.Nullable;
26 |
27 | public class ActionsFile {
28 |
29 | private final List actions;
30 |
31 | @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
32 | ActionsFile(@JsonProperty("actions") @Nullable List actions) {
33 | this.actions = Objects.requireNonNull(actions);
34 | }
35 |
36 | public List getActions() {
37 | return actions;
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return "ActionsFile{" + "actions=" + actions + '}';
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/cli/runtime/command/InjectTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.command;
18 |
19 | import java.io.IOException;
20 | import java.util.HashMap;
21 | import java.util.Map;
22 |
23 | import org.junit.jupiter.api.Test;
24 |
25 | public class InjectTests extends AbstractCommandTests {
26 |
27 | @Test
28 | void injectBefore() throws IOException {
29 | Map model = new HashMap<>();
30 | runInjectAction("before", "text", model, "myfile-before",
31 | "src/test/resources/org/springframework/cli/runtime/command/inject");
32 | }
33 |
34 | @Test
35 | void injectAfter() throws IOException {
36 | Map model = new HashMap<>();
37 | runInjectAction("after", "text", model, "myfile-after",
38 | "src/test/resources/org/springframework/cli/runtime/command/inject");
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/cli/runtime/engine/spel/Person.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.spel;
18 |
19 | public class Person {
20 |
21 | private String name;
22 |
23 | private int age;
24 |
25 | private boolean isAdult;
26 |
27 | public Person(String name, int age) {
28 | this.name = name;
29 | this.age = age;
30 | }
31 |
32 | public String getName() {
33 | return name;
34 | }
35 |
36 | public void setName(String name) {
37 | this.name = name;
38 | }
39 |
40 | public int getAge() {
41 | return age;
42 | }
43 |
44 | public void setAge(int age) {
45 | this.age = age;
46 | }
47 |
48 | public boolean isAdult() {
49 | return isAdult;
50 | }
51 |
52 | public void setAdult(boolean adult) {
53 | isAdult = adult;
54 | }
55 |
56 | public static void sayHello() {
57 | System.out.println("hello");
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/test-data/projects/spring-scheduling-tasks/src/test/java/com/example/schedulingtasks/scheduling/ScheduledTasksTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2015 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.example.schedulingtasks.scheduling;
18 |
19 | import org.junit.jupiter.api.Test;
20 | import org.springframework.boot.test.context.SpringBootTest;
21 | import org.springframework.boot.test.mock.mockito.SpyBean;
22 |
23 | import java.time.Duration;
24 |
25 | import static org.awaitility.Awaitility.await;
26 | import static org.mockito.Mockito.atLeast;
27 | import static org.mockito.Mockito.verify;
28 |
29 | @SpringBootTest
30 | public class ScheduledTasksTest {
31 |
32 | @SpyBean
33 | ScheduledTasks tasks;
34 |
35 | @Test
36 | public void reportCurrentTime() {
37 | await().atMost(Duration.ofSeconds(10)).untilAsserted(() -> {
38 | verify(tasks, atLeast(2)).reportCurrentTime();
39 | });
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/.github/workflows/jr-assemble-jlink.yml:
--------------------------------------------------------------------------------
1 | name: JR Assemble JLink
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | ref:
7 | required: true
8 | type: string
9 | version:
10 | required: true
11 | type: string
12 |
13 | jobs:
14 | assemble:
15 | runs-on: ubuntu-latest
16 | name: Assemble
17 | steps:
18 | - uses: actions/checkout@v3
19 | with:
20 | ref: ${{ inputs.ref }}
21 | - uses: actions/setup-java@v3
22 | with:
23 | distribution: adopt
24 | java-version: 17
25 | cache: gradle
26 | - name: Download fatjar
27 | uses: actions/download-artifact@v3
28 | with:
29 | name: fatjar
30 | path: build/libs
31 | - name: Download completion
32 | uses: actions/download-artifact@v3
33 | with:
34 | name: completion
35 | path: build/completion
36 | - name: Jdks
37 | shell: bash
38 | run: ./gradlew copyJdksFromCache setupJdks -PcliRelease=true
39 | - name: JR Assemble
40 | uses: jreleaser/release-action@v2
41 | with:
42 | version: 1.12.0
43 | arguments: assemble --assembler jlink
44 | env:
45 | JRELEASER_PROJECT_VERSION: ${{ inputs.version }}
46 | - name: Upload jlink
47 | uses: actions/upload-artifact@v3
48 | with:
49 | retention-days: 1
50 | name: jlink
51 | path: |
52 | out/jreleaser/assemble/spring-cli-standalone/jlink/*.zip
53 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/ActionResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions;
18 |
19 | import java.util.Map;
20 |
21 | public class ActionResult {
22 |
23 | private Map outputs;
24 |
25 | private Throwable error;
26 |
27 | /**
28 | * The result of a completed step after continue-on-error is applied. Possible values
29 | * are success, failure, or skipped. When a continue-on-error action fails, the
30 | * outcome is failure, but the final conclusion is success.
31 | */
32 | private ActionStatus conclusion;
33 |
34 | /**
35 | * The result of a completed step before continue-on-error is applied. Possible values
36 | * are success, failure, or skipped. When a continue-on-error action fails, the
37 | * outcome is failure, but the final conclusion is success.
38 | */
39 | private ActionStatus outcome;
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/.github/workflows/e2e.yml:
--------------------------------------------------------------------------------
1 | name: e2e
2 |
3 | on:
4 | workflow_dispatch:
5 | # schedule:
6 | # - cron: '0 0 * * 1,3,5'
7 |
8 | jobs:
9 | e2e:
10 | runs-on: ${{ matrix.os }}
11 | strategy:
12 | fail-fast: false
13 | matrix:
14 | include:
15 | - nickname: macos
16 | os: macos-latest
17 | graal: dev
18 | - nickname: linux
19 | os: ubuntu-latest
20 | graal: dev
21 | - nickname: windows
22 | os: win22-8-32
23 | graal: dev
24 | name: E2E ${{ matrix.nickname }}
25 | steps:
26 | - uses: actions/checkout@v2
27 | - uses: graalvm/setup-graalvm@v1
28 | with:
29 | version: ${{ matrix.graal }}
30 | java-version: 21
31 | set-java-home: true
32 | github-token: ${{ secrets.GITHUB_TOKEN }}
33 | - name: Use Python 3.11
34 | uses: actions/setup-python@v4
35 | with:
36 | python-version: '3.11'
37 | - uses: actions/setup-node@v2
38 | with:
39 | node-version: '16'
40 | - run: |
41 | ./gradlew clean build nativeBuild -x test
42 | - name: run e2e tests
43 | working-directory: e2e/spring-cli-e2e-tests
44 | run: |
45 | npm install
46 | npm run build-spring-shell-e2e
47 | npm test
48 | - name: Publish Test Results
49 | uses: EnricoMi/publish-unit-test-result-action/composite@v1
50 | if: always()
51 | with:
52 | files: e2e/spring-cli-e2e-tests/junit.xml
53 |
--------------------------------------------------------------------------------
/src/test/resources/pom-existing-project.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.6.3
9 |
10 |
11 | com.example
12 | demo
13 | 0.0.1-SNAPSHOT
14 | demo
15 | Demo project for Spring Data JPA
16 |
17 | 1.8
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-data-jpa
23 |
24 |
25 |
26 | com.h2database
27 | h2
28 | runtime
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-test
33 | test
34 |
35 |
36 |
37 |
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-maven-plugin
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/command/CommandFileReader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.command;
18 |
19 | import java.io.IOException;
20 | import java.nio.file.Path;
21 |
22 | import com.fasterxml.jackson.databind.DeserializationFeature;
23 | import com.fasterxml.jackson.databind.ObjectMapper;
24 | import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
25 |
26 | /**
27 | * Deserializes the command object from a file
28 | *
29 | * @author Mark Pollack
30 | */
31 | public final class CommandFileReader {
32 |
33 | private CommandFileReader() {
34 |
35 | }
36 |
37 | public static CommandFileContents read(Path commandFile) throws IOException {
38 | ObjectMapper mapper = new ObjectMapper(new YAMLFactory())
39 | .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
40 | return mapper.readValue(commandFile.toFile(), CommandFileContents.class);
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/util/TerminalMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.util;
18 |
19 | import org.jline.utils.AttributedString;
20 |
21 | /**
22 | * Interface printing shell messages.
23 | *
24 | * @author Janne Valkealahti
25 | */
26 | public interface TerminalMessage {
27 |
28 | /**
29 | * Print a text.
30 | * @param text a text
31 | */
32 | void print(String... text);
33 |
34 | /**
35 | * Print an attributed text
36 | * @param text a text
37 | */
38 | void print(AttributedString... text);
39 |
40 | /**
41 | * Gets an implementation which does nothing.
42 | * @return a noop implementation
43 | */
44 | static TerminalMessage noop() {
45 | return new TerminalMessage() {
46 |
47 | @Override
48 | public void print(String... text) {
49 | }
50 |
51 | @Override
52 | public void print(AttributedString... text) {
53 | }
54 | };
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/test-data/projects/rest-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.2.3
9 |
10 |
11 | com.example
12 | rest-service
13 | 0.0.1-SNAPSHOT
14 | rest-service
15 | RESTful web application
16 |
17 | 17
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-web
23 |
24 |
25 |
26 | org.springframework.boot
27 | spring-boot-starter-actuator
28 |
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-test
33 | test
34 |
35 |
36 |
37 |
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-maven-plugin
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/pages/getting-started.adoc:
--------------------------------------------------------------------------------
1 | = Getting Started
2 |
3 | Creating a new project is as simple as typing `spring boot new my-app`:
4 |
5 | [source, bash]
6 | ----
7 | spring boot new my-app
8 | ----
9 |
10 | The output is
11 | [source, bash]
12 | ----
13 | Cloning project from https://github.com/rd-1-2022/rest-service
14 | Created project in directory 'my-app'
15 | ----
16 |
17 | NOTE: If the CLI seems to be stuck at the cloning step, you might be hitting GitHub rate limiting. Use the `spring github auth login` command to authenticate.
18 |
19 | You can now `cd` into the `my-app` directory and build and run the application, which is, by default, a simple web application with a single endpoint:
20 |
21 | [source, bash]
22 | ----
23 | cd my-app
24 | ./mvnw spring-boot:run
25 | ----
26 |
27 | Then, in another terminal windows, you can interact with the endpoint by using curl:
28 |
29 | [source, bash]
30 | ----
31 | curl http://localhost:8080/greeting
32 | ----
33 |
34 | The curl command returns the default 'Hello World' greeting:
35 |
36 | [source, bash]
37 | ----
38 | {"id":1,"content":"Hello, World!"}
39 | ----
40 |
41 | The README.adoc file in the new project contains more information on how the web applications works.
42 |
43 | == Next steps
44 |
45 | The xref:ref/project/creating-new-projects.adoc[Creating New Projects] section shows you how to create applications other than the default application.
46 |
47 | The xref:ref/project/adding-to-existing-projects.adoc[Adding To Existing Projects] section shows you how to add additional applications into your current working project.
48 |
--------------------------------------------------------------------------------
/test-data/projects/spring-data-jpa/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.1.0
9 |
10 |
11 | com.example
12 | demo
13 | 0.0.1-SNAPSHOT
14 | spring-data-jpa-sample
15 | Demo project for Spring Data JPA
16 |
17 | 17
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-data-jpa
23 |
24 |
25 |
26 | com.h2database
27 | h2
28 | runtime
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-test
33 | test
34 |
35 |
36 |
37 |
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-maven-plugin
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/test/resources/org/springframework/cli/merger/pom-java-8.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.6.3
9 |
10 |
11 | com.example
12 | demo
13 | 0.0.1-SNAPSHOT
14 | demo
15 | Demo project for Spring Boot
16 |
17 | 1.8
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-web
23 |
24 |
25 |
26 | org.springframework.boot
27 | spring-boot-starter-actuator
28 |
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-test
33 | test
34 |
35 |
36 |
37 |
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-maven-plugin
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/docs/modules/ROOT/nav-commands.adoc:
--------------------------------------------------------------------------------
1 | .Commands
2 | ** xref:commands/ai-add.adoc[ai add]
3 | ** xref:commands/boot-start.adoc[boot start]
4 | ** xref:commands/boot-add.adoc[boot add]
5 | ** xref:commands/boot-new.adoc[boot new]
6 | ** xref:commands/help.adoc[help]
7 | ** xref:commands/completion-zsh.adoc[completion zsh]
8 | ** xref:commands/completion-bash.adoc[completion bash]
9 | ** xref:commands/history.adoc[history]
10 | ** xref:commands/version.adoc[version]
11 | ** xref:commands/script.adoc[script]
12 | ** xref:commands/command-remove.adoc[command remove]
13 | ** xref:commands/command-add.adoc[command add]
14 | ** xref:commands/command-new.adoc[command new]
15 | ** xref:commands/github-auth-status.adoc[github auth status]
16 | ** xref:commands/github-auth-login.adoc[github auth login]
17 | ** xref:commands/github-auth-logout.adoc[github auth logout]
18 | ** xref:commands/guide-apply.adoc[guide apply]
19 | ** xref:commands/project-list.adoc[project list]
20 | ** xref:commands/project-add.adoc[project add]
21 | ** xref:commands/project-remove.adoc[project remove]
22 | ** xref:commands/project-catalog-remove.adoc[project catalog remove]
23 | ** xref:commands/project-catalog-add.adoc[project catalog add]
24 | ** xref:commands/project-catalog-available.adoc[project catalog available]
25 | ** xref:commands/project-catalog-list.adoc[project catalog list]
26 | ** xref:commands/role-list.adoc[role list]
27 | ** xref:commands/role-add.adoc[role add]
28 | ** xref:commands/role-get.adoc[role get]
29 | ** xref:commands/role-remove.adoc[role remove]
30 | ** xref:commands/role-set.adoc[role set]
31 | ** xref:commands/vars-new.adoc[vars new]
32 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/runtime/engine/actions/Vars.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.runtime.engine.actions;
18 |
19 | import java.util.List;
20 | import java.util.Map;
21 |
22 | import com.fasterxml.jackson.annotation.JsonProperty;
23 |
24 | import org.springframework.lang.Nullable;
25 |
26 | public class Vars {
27 |
28 | private List questions;
29 |
30 | public Map data;
31 |
32 | // files
33 |
34 | Vars(@JsonProperty("questions") @Nullable List questions,
35 | @JsonProperty("data") @Nullable Map data) {
36 | this.questions = questions;
37 | this.data = data;
38 | }
39 |
40 | public List getQuestions() {
41 | return questions;
42 | }
43 |
44 | public Map getData() {
45 | return data;
46 | }
47 |
48 | @Override
49 | public String toString() {
50 | return "Vars{" + "questions=" + questions + ", data=" + data + '}';
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/docs/antora-playbook.yml:
--------------------------------------------------------------------------------
1 | # PACKAGES antora@3.2.0-alpha.2 @antora/atlas-extension:1.0.0-alpha.1 @antora/collector-extension@1.0.0-alpha.3 @springio/antora-extensions@1.3.0 @asciidoctor/tabs@1.0.0-beta.3 @springio/asciidoctor-extensions @opendevise/antora-release-line-extension@1.0.0
2 | #
3 | # The purpose of this Antora playbook is to build the docs in the current branch.
4 | antora:
5 | extensions:
6 | - '@antora/collector-extension'
7 | - id: '@antora/atlas-extension'
8 | require: '@antora/atlas-extension'
9 | enabled: false
10 | - '@springio/antora-extensions/latest-version-extension'
11 | - require: '@springio/antora-extensions/root-component-extension'
12 | root_component_name: 'cli'
13 | - require: '@springio/antora-extensions/asciinema-extension'
14 | site:
15 | title: Spring CLI Reference
16 | content:
17 | sources:
18 | - url: ./..
19 | branches: HEAD
20 | start_path: docs
21 | worktrees: true
22 | asciidoc:
23 | attributes:
24 | page-stackoverflow-url: https://stackoverflow.com/questions/tagged/spring
25 | hide-uri-scheme: '@'
26 | page-pagination: ''
27 | primary-site-url: https://docs.spring.io/spring-cli/reference
28 | tabs-sync-option: '@'
29 | extensions:
30 | - '@asciidoctor/tabs'
31 | - '@springio/asciidoctor-extensions'
32 | - '@springio/asciidoctor-extensions/include-code-extension'
33 | sourcemap: true
34 | urls:
35 | latest_version_segment: ''
36 | # runtime:
37 | # log:
38 | # failure_level: warn
39 | ui:
40 | bundle:
41 | url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.7/ui-bundle.zip
42 | snapshot: true
43 |
--------------------------------------------------------------------------------
/test-data/projects/spring-scheduling-tasks/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.1.0
9 |
10 |
11 | com.example
12 | scheduling-tasks-complete
13 | 0.0.1-SNAPSHOT
14 | scheduling-tasks-complete
15 | Demo project for Spring Boot
16 |
17 |
18 | 17
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter
25 |
26 |
27 | org.awaitility
28 | awaitility
29 | test
30 |
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-test
35 | test
36 |
37 |
38 |
39 |
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-maven-plugin
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/recipe/RecipeUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.recipe;
18 |
19 | import java.io.BufferedWriter;
20 | import java.io.IOException;
21 | import java.nio.file.Files;
22 | import java.nio.file.Path;
23 | import java.util.List;
24 |
25 | import org.openrewrite.Result;
26 |
27 | import org.springframework.cli.SpringCliException;
28 |
29 | /**
30 | * Utilities for recipe execution
31 | */
32 | public final class RecipeUtils {
33 |
34 | private RecipeUtils() {
35 | }
36 |
37 | public static void writeResults(String recipeName, Path path, List resultList) {
38 | try {
39 | for (Result result : resultList) {
40 | try (BufferedWriter sourceFileWriter = Files.newBufferedWriter(path)) {
41 | sourceFileWriter.write(result.getAfter().printAllTrimmed());
42 | }
43 | }
44 | }
45 | catch (IOException ex) {
46 | throw new SpringCliException("Could not write recipe results to path = " + path, ex);
47 | }
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/cli/util/ClassNameExtractor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.util;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 | import java.util.Optional;
22 | import java.util.regex.Matcher;
23 | import java.util.regex.Pattern;
24 |
25 | public class ClassNameExtractor {
26 |
27 | private String[] patternStrings = { "(?<=\\bclass\\s)\\w+", "(?<=\\binterface\\s)\\w+", "(?<=\\b@interface\\s)\\w+",
28 | "(?<=\\benum\\s)\\w+" };
29 |
30 | private List patterns = new ArrayList<>();
31 |
32 | public ClassNameExtractor() {
33 | for (String patternString : patternStrings) {
34 | patterns.add(Pattern.compile(patternString));
35 | }
36 | }
37 |
38 | public Optional extractClassName(String code) {
39 | for (Pattern pattern : patterns) {
40 | Matcher matcher = pattern.matcher(code);
41 | if (matcher.find()) {
42 | return Optional.of(matcher.group());
43 | }
44 | }
45 | return Optional.empty();
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/resources/command-scanner-tests/k8s-simple/new/command.yaml:
--------------------------------------------------------------------------------
1 | command:
2 | description: Create the Kubernetes resource files for the application
3 | options:
4 | - name: with-gusto
5 | description: say it loud, say it proud
6 | dataType: boolean
7 | defaultValue: false
8 | inputType: toggle # TOGGLE
9 | #
10 | - name: with-greeting
11 | description: what word to use to say hello
12 | dataType: string
13 | defaultValue: Hello
14 | paramLabel: WORD
15 | inputType: text # TEXT
16 | #
17 | - name: with-additional-message
18 | description: Additional message to output
19 | dataType: string
20 | inputType: textarea # TEXT AREA
21 | #
22 | - name: flavor
23 | description: Ice Creams Flavors
24 | dataType: string
25 | defaultValue: strawberry
26 | inputType: checkbox # CHECKBOX (multiple options)
27 | choices:
28 | vanilla: Valilla
29 | chocolate: Chocolate
30 | strawberry: Strawberry
31 | #
32 | - name: platform
33 | description: platform to target
34 | dataType: string
35 | defaultValue: azure
36 | inputType: select # SELECT (single option)
37 | choices:
38 | azure: Microsoft Azure
39 | lambda: AWS Lambda
40 | google: Google Cloud Platform
41 | #
42 | - name: beverage
43 | description: What to drink
44 | dataType: string
45 | defaultValue: water
46 | inputType: radio # RADIO (single option)
47 | choices:
48 | water: Water
49 | milk: Milk
50 | coke: Coke
51 | coffee: Coffee
52 | tea: Tea
--------------------------------------------------------------------------------
/src/test/java/org/springframework/cli/command/SpecialCommandsTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cli.command;
18 |
19 | import org.junit.jupiter.api.Test;
20 |
21 | import org.springframework.boot.test.context.runner.ApplicationContextRunner;
22 | import org.springframework.cli.support.MockConfigurations.MockBaseConfig;
23 | import org.springframework.cli.support.MockConfigurations.MockUserConfig;
24 |
25 | import static org.assertj.core.api.Assertions.assertThat;
26 |
27 | public class SpecialCommandsTests {
28 |
29 | private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
30 | .withUserConfiguration(MockBaseConfig.class);
31 |
32 | @Test
33 | void simpleExec() {
34 | this.contextRunner.withUserConfiguration(MockUserConfig.class).run((context) -> {
35 | assertThat(context).hasSingleBean(SpecialCommands.class);
36 | SpecialCommands specialCommands = context.getBean(SpecialCommands.class);
37 | specialCommands.dotExec("ls -al");
38 | });
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/docs/help-command-adoc.stg:
--------------------------------------------------------------------------------
1 | // TITLE
2 | title(commandName, commandShortDesc) ::= <<
3 | =
4 |
5 | >>
6 |
7 | // NAME
8 | name(commandName, commandShortDesc) ::= <<
9 | == NAME
10 |
11 | >>
12 |
13 | // SYNOPSIS
14 | synopsisOption(option) ::= <%
15 |
16 | <("[")>
17 |
18 |
19 | <(option.type)>
20 |
21 |
22 | <("]")>
23 |
24 | %>
25 |
26 | synopsis(commandName, options) ::= <<
27 | == SYNOPSIS
28 | ====
29 | [source]
30 | ----
31 | }; separator=" ">
32 | ----
33 | ====
34 | >>
35 |
36 | // OPTIONS
37 | arguments(arguments) ::= <<
38 | }; separator=" or ">
39 | >>
40 |
41 | type(type) ::= <<
42 |
43 | >>
44 |
45 | required(option) ::= <%
46 | *
47 |
48 | <("Mandatory")>
49 |
50 | <("Optional")>
51 |
52 |
53 | <(", default = ")><(option.defaultValue)>
54 |
55 | *
56 | %>
57 |
58 | option(option) ::= <<
59 | ``
60 |
61 | >>
62 |
63 | options(options) ::= <<
64 | == OPTIONS
65 | }; separator="\n">
66 | >>
67 |
68 | footer(commandNames) ::= <<
69 | include::footers/}; separator="-">-footer.adoc[opts=optional]
70 | >>
71 |
72 | // main
73 | main(model) ::= <<
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |