Skip to content

Commit

Permalink
addition work on templates
Browse files Browse the repository at this point in the history
  • Loading branch information
tmiddlet2666 committed Jan 27, 2025
1 parent e3451ba commit a73bf3c
Show file tree
Hide file tree
Showing 22 changed files with 1,289 additions and 3 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2021, 2024 Oracle and/or its affiliates.
// Copyright (c) 2021, 2025 Oracle and/or its affiliates.
// Licensed under the Universal Permissive License v 1.0 as shown at
// https://oss.oracle.com/licenses/upl.
//
Expand All @@ -17,6 +17,7 @@ require (
go.uber.org/zap v1.27.0
golang.org/x/term v0.27.0
golang.org/x/text v0.21.0
gopkg.in/yaml.v3 v3.0.1
)

require (
Expand Down Expand Up @@ -45,5 +46,4 @@ require (
golang.org/x/net v0.33.0 // indirect
golang.org/x/sys v0.28.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
3 changes: 2 additions & 1 deletion pkg/cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2024 Oracle and/or its affiliates.
* Copyright (c) 2021, 2025 Oracle and/or its affiliates.
* Licensed under the Universal Permissive License v 1.0 as shown at
* https://oss.oracle.com/licenses/upl.
*/
Expand Down Expand Up @@ -672,6 +672,7 @@ func Initialize(command *cobra.Command) *cobra.Command {
command.AddCommand(createCmd)
createCmd.AddCommand(createSnapshotCmd)
createCmd.AddCommand(createClusterCmd)
createCmd.AddCommand(createStarterCmd)

// recover
command.AddCommand(recoverCmd)
Expand Down
215 changes: 215 additions & 0 deletions pkg/cmd/starter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
/*
* Copyright (c) 2025 Oracle and/or its affiliates.
* Licensed under the Universal Permissive License v 1.0 as shown at
* https://oss.oracle.com/licenses/upl.
*/

package cmd

import (
"fmt"
"github.com/oracle/coherence-cli/pkg/utils"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"os"
"path/filepath"
)

const (
framework = "framework"
frameworkURL = "https://raw.githubusercontent.com/oracle/coherence-cli/refs/heads/template/templates"
frameworkTypesURL = "https://raw.githubusercontent.com/oracle/coherence-cli/refs/heads/template/templates/template.yaml"
)

// FrameworkTemplate contains the contents read from the coherence-cli repository.
type FrameworkTemplate struct {
Name string `yaml:"name"`
FrameworkVersion string `yaml:"frameworkVersion"`
Instructions string `yaml:"instructions"`
Files []string `yaml:"files"`
}

type Templates struct {
Templates []FrameworkTemplate `yaml:"templates"`
}

var (
frameworkTypeParam string
validFrameworks = []string{"helidon", "springboot", "micronaut"}

commonInstructions = `
Add a customer:
curl -X POST -H "Content-Type: application/json" -d '{"id": 1, "name": "Tim", "balance": 1000}' http://localhost:8080/api/customers
Get a customer:
curl -s http://localhost:8080/api/customers/1
Get all customers:
curl -s http://localhost:8080/api/customers
Delete a customer:
curl -X DELETE http://localhost:8080/api/customers/1
`
)

// createStarterCmd represents the create starter command.
var createStarterCmd = &cobra.Command{
Use: "starter project-name",
Short: "creates a starter project for Coherence",
Long: `The 'create starter' command creates a starter Maven project to use Coherence
with various frameworks including Helidon, Spring Boot and Micronaut. A directory
will be created off the current directory with the same name as the project name.`,
Args: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
displayErrorAndExit(cmd, "you must provide a project name")
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
var (
projectName = args[0]
err error
)

// the project name will be used as the directory off the current directory, validate it
if utils.SanitizeSnapshotName(projectName) != projectName {
return fmt.Errorf("invalid project name: %s", projectName)
}

// validate the framework
if !utils.SliceContains(validFrameworks, frameworkTypeParam) {
return fmt.Errorf("framework must be one of %v", validFrameworks)
}

// check the directory does not exist
if utils.DirectoryExists(projectName) {
return fmt.Errorf("the directory %s already exists", projectName)
}

cmd.Printf("checking for availability of template %v...\n", frameworkTypeParam)

// load the template files
templates, err := loadTemplateFiles()
if err != nil {
return err
}

// get the template for the framework
template := getTemplate(templates, frameworkTypeParam)

if template == nil {
return fmt.Errorf("unable to find files for framework %s", frameworkTypeParam)
}

absolutePath, err := filepath.Abs(projectName)
if err != nil {
return fmt.Errorf("unable to get absolute path for directory %s: %w", projectName, err)
}

cmd.Println("\nCreate Starter Project")
cmd.Printf("Project Name: %s\n", projectName)
cmd.Printf("Framework Type: %s\n", frameworkTypeParam)
cmd.Printf("Framework Versions: %s\n", template.FrameworkVersion)
cmd.Printf("Project Path %s\n\n", absolutePath)

// confirm the operation
if !confirmOperation(cmd, "Are you sure you want to create the starter project above? (y/n) ") {
return nil
}

return initProject(cmd, template, projectName, absolutePath)
},
}

func initProject(cmd *cobra.Command, template *FrameworkTemplate, projectName string, absolutePath string) error {
var err error

// create the directory
if err = utils.EnsureDirectory(projectName); err != nil {
return err
}

err = saveFiles(template.Files, projectName, template.Name)
if err != nil {
return err
}

// output instructions for the framework
cmd.Printf("\nYour %s template project has been saved to %s\n", template.Name, absolutePath)

// get framework instructions
instructions := template.Instructions

cmd.Printf("\nPlease see the file %s/readme.txt for instructions\n\n", projectName)
return writeContentToFile(projectName, "readme.txt", instructions+commonInstructions)
}

func loadTemplateFiles() (*Templates, error) {
var templates Templates

response, err := GetURLContents(frameworkTypesURL)
if err != nil {
return nil, err
}

err = yaml.Unmarshal(response, &templates)
if err != nil {
return nil, fmt.Errorf("unable to unmarshal %v, %v", frameworkTypesURL, err)
}

return &templates, nil
}

func getTemplate(templates *Templates, framework string) *FrameworkTemplate {
for _, template := range templates.Templates {
if template.Name == framework {
return &template
}
}
return nil
}

func saveFiles(fileList []string, baseDir string, frameworkType string) error {
for _, file := range fileList {
url := fmt.Sprintf("%s/%s/%s", frameworkURL, frameworkType, file)

// Get the file contents
response, err := GetURLContents(url)
if err != nil {
return fmt.Errorf("error downloading file %s: %w", file, err)
}

// Construct the full destination path
destPath := filepath.Join(baseDir, file)

destDir := filepath.Dir(destPath)
if err = os.MkdirAll(destDir, os.ModePerm); err != nil {
return fmt.Errorf("error creating directory %s: %w", destDir, err)
}

// Write the file contents to the destination
if err = os.WriteFile(destPath, response, 0600); err != nil {
return fmt.Errorf("error writing file %s: %w", destPath, err)
}
}

return nil
}

func writeContentToFile(baseDir, fileName, content string) error {
filePath := filepath.Join(baseDir, fileName)

// Write the content to the file
err := os.WriteFile(filePath, []byte(content), 0600)
if err != nil {
return fmt.Errorf("failed to write to file %s: %w", filePath, err)
}

return nil
}

func init() {
createStarterCmd.Flags().StringVarP(&frameworkTypeParam, framework, "f", "", "the framework to create for: helidon, springboot or micronaut")
_ = createStarterCmd.MarkFlagRequired(framework)
createStarterCmd.Flags().BoolVarP(&automaticallyConfirm, "yes", "y", false, confirmOptionMessage)
}
123 changes: 123 additions & 0 deletions templates/helidon/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2025 Oracle and/or its affiliates.
Licensed under the Universal Permissive License v 1.0 as shown at
https://oss.oracle.com/licenses/upl.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.helidon.applications</groupId>
<artifactId>helidon-mp</artifactId>
<version>4.1.6</version>
<relativePath/>
</parent>

<groupId>com.oracle.coherence.demo.frameworks</groupId>
<artifactId>helidon</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Demo project for Helidon and Coherence</name>

<properties>
<coherence.group.id>com.oracle.coherence.ce</coherence.group.id>
<coherence.version>24.09</coherence.version>
<jackson.version>2.18.2</jackson.version>
<java.version>21</java.version>
</properties>

<dependencies>
<!-- helidon dependencies -->
<dependency>
<groupId>io.helidon.microprofile.bundles</groupId>
<artifactId>helidon-microprofile-core</artifactId>
</dependency>

<dependency>
<groupId>jakarta.json.bind</groupId>
<artifactId>jakarta.json.bind-api</artifactId>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>io.helidon.logging</groupId>
<artifactId>helidon-logging-jul</artifactId>
<scope>runtime</scope>
</dependency>

<!-- Coherence dependencies -->
<dependency>
<groupId>${coherence.group.id}</groupId>
<version>${coherence.version}</version>
<artifactId>coherence</artifactId>
</dependency>
<dependency>
<groupId>${coherence.group.id}</groupId>
<version>${coherence.version}</version>
<artifactId>coherence-cdi-server</artifactId>
</dependency>
<dependency>
<groupId>${coherence.group.id}</groupId>
<version>${coherence.version}</version>
<artifactId>coherence-mp-config</artifactId>
</dependency>
<dependency>
<groupId>${coherence.group.id}</groupId>
<version>${coherence.version}</version>
<artifactId>coherence-json</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-libs</id>
</execution>
</executions>
</plugin>

<plugin>
<groupId>${coherence.group.id}</groupId>
<version>${coherence.version}</version>
<artifactId>pof-maven-plugin</artifactId>
<executions>
<execution>
<id>instrument</id>
<goals>
<goal>instrument</goal>
</goals>
</execution>
<execution>
<id>instrument-tests</id>
<goals>
<goal>instrument-tests</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Loading

0 comments on commit a73bf3c

Please # to comment.