github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow@v0.28.1-0.20240311201729-34c6856b157f/pkg/command/quarkus/convert.go (about)

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one
     3   * or more contributor license agreements.  See the NOTICE file
     4   * distributed with this work for additional information
     5   * regarding copyright ownership.  The ASF licenses this file
     6   * to you under the Apache License, Version 2.0 (the
     7   * "License"); you may not use this file except in compliance
     8   * with the License.  You may obtain a copy of the License at
     9   *
    10   *  http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing,
    13   * software distributed under the License is distributed on an
    14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   * KIND, either express or implied.  See the License for the
    16   * specific language governing permissions and limitations
    17   * under the License.
    18   */
    19  
    20  package quarkus
    21  
    22  import (
    23  	"fmt"
    24  	"io"
    25  	"os"
    26  	"path/filepath"
    27  
    28  	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/common"
    29  	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/metadata"
    30  	"github.com/ory/viper"
    31  	"github.com/spf13/cobra"
    32  )
    33  
    34  func NewConvertCommand() *cobra.Command {
    35  	var cmd = &cobra.Command{
    36  		Use:   "convert",
    37  		Short: "Convert a SonataFlow project to a Quarkus SonataFlow project",
    38  		Long: `
    39  	Convert a SonataFlow project to a Quarkus SonataFlow Project.
    40  		`,
    41  		Example: `
    42  	# Run the local directory
    43  	{{.Name}} quarkus convert
    44  		`,
    45  		SuggestFor: []string{"convert-to-quarkus"},
    46  		PreRunE:    common.BindEnv("extension", "quarkus-platform-group-id", "quarkus-version"),
    47  	}
    48  
    49  	cmd.RunE = func(cmd *cobra.Command, args []string) error {
    50  		return runConvert()
    51  	}
    52  
    53  	quarkusDependencies := metadata.ResolveQuarkusDependencies()
    54  
    55  	cmd.Flags().StringP("extension", "e", "", "On Quarkus projects, setup project custom Maven extensions, separated with a comma.")
    56  	cmd.Flags().StringP("quarkus-platform-group-id", "G", quarkusDependencies.QuarkusPlatformGroupId, "On Quarkus projects, setup project group id.")
    57  	cmd.Flags().StringP("quarkus-version", "V", quarkusDependencies.QuarkusVersion, "On Quarkus projects, setup the project version.")
    58  
    59  	cmd.SetHelpFunc(common.DefaultTemplatedHelp)
    60  
    61  	return cmd
    62  }
    63  
    64  func runConvert() error {
    65  	if common.IsSonataFlowProject() {
    66  		return convert()
    67  	} else if common.IsQuarkusSonataFlowProject() {
    68  		return fmt.Errorf("looks like you are already inside a Quarkus project, so no need to convert it")
    69  	} else {
    70  		return fmt.Errorf("cannot find SonataFlow project")
    71  	}
    72  }
    73  
    74  func loadConvertCmdConfig() (cfg CreateQuarkusProjectConfig, err error) {
    75  	quarkusPlatformGroupId := viper.GetString("quarkus-platform-group-id")
    76  	quarkusVersion := viper.GetString("quarkus-version")
    77  
    78  	cfg = CreateQuarkusProjectConfig{
    79  		Extensions: fmt.Sprintf("%s,%s,%s,%s",
    80  			metadata.QuarkusKubernetesExtension,
    81  			metadata.QuarkusResteasyJacksonExtension,
    82  			metadata.SmallryeHealth,
    83  			viper.GetString("extension"),
    84  		),
    85  		DependenciesVersion: metadata.DependenciesVersion{
    86  			QuarkusPlatformGroupId: quarkusPlatformGroupId,
    87  			QuarkusVersion:         quarkusVersion,
    88  		},
    89  	}
    90  	if cfg.ProjectName == "" {
    91  		dir, err := os.Getwd()
    92  		if err != nil {
    93  			dir = "project-name"
    94  		}
    95  		cfg.ProjectName = filepath.Base(dir)
    96  	}
    97  	return
    98  }
    99  func convert() error {
   100  
   101  	cfg, err := loadConvertCmdConfig()
   102  
   103  	if err != nil {
   104  		return fmt.Errorf("initializing create config: %w", err)
   105  	}
   106  
   107  	if err := common.CheckJavaDependencies(); err != nil {
   108  		return err
   109  	}
   110  
   111  	if err = runConvertProject(cfg); err != nil {
   112  		return err
   113  	}
   114  
   115  	return nil
   116  }
   117  
   118  func runConvertProject(cfg CreateQuarkusProjectConfig) (err error) {
   119  
   120  	fmt.Println("🔨 Creating a Quarkus SonataFlow project...")
   121  	if err = CreateQuarkusProject(cfg); err != nil {
   122  		fmt.Println("❌ Error creating Quarkus project", err)
   123  		return err
   124  	}
   125  
   126  	fmt.Println("🔨 Moving SonataFlow files to Quarkus SonataFlow project...")
   127  	rootFolder, err := os.Getwd()
   128  	if err != nil {
   129  		return err
   130  	}
   131  
   132  	if err := moveSWFFilesToQuarkusProject(cfg, rootFolder); err != nil {
   133  		return err
   134  	}
   135  
   136  	generatedQuarkusProjectPath := rootFolder + "/" + cfg.ProjectName
   137  
   138  	if err := copyDir(generatedQuarkusProjectPath, rootFolder); err != nil {
   139  		fmt.Println("❌ Error migrating Quarkus SonataFlow project files", err)
   140  		return err
   141  	}
   142  	if err := os.RemoveAll(generatedQuarkusProjectPath); err != nil {
   143  		fmt.Println("❌ Error migrating Quarkus SonataFlow project", err)
   144  		return err
   145  	}
   146  
   147  	fmt.Println("✅ Quarkus SonataFlow project successfully created")
   148  
   149  	return nil
   150  }
   151  
   152  func moveSWFFilesToQuarkusProject(cfg CreateQuarkusProjectConfig, rootFolder string) error {
   153  	targetFolder := filepath.Join(rootFolder, cfg.ProjectName+"/src/main/resources")
   154  
   155  	err := os.MkdirAll(targetFolder, os.ModePerm)
   156  	if err != nil {
   157  		return err
   158  	}
   159  
   160  	items, err := os.ReadDir(rootFolder)
   161  	if err != nil {
   162  		return err
   163  	}
   164  
   165  	for _, item := range items {
   166  		if item.IsDir() && item.Name() == cfg.ProjectName {
   167  			continue
   168  		}
   169  
   170  		srcPath := filepath.Join(rootFolder, item.Name())
   171  		dstPath := filepath.Join(targetFolder, item.Name())
   172  
   173  		if err := os.Rename(srcPath, dstPath); err != nil {
   174  			return fmt.Errorf("error moving %s: %w", srcPath, err)
   175  		}
   176  	}
   177  
   178  	return nil
   179  }
   180  
   181  func copyFile(src, dst string) error {
   182  	srcFile, err := os.Open(src)
   183  	if err != nil {
   184  		return err
   185  	}
   186  	defer srcFile.Close()
   187  
   188  	dstFile, err := os.Create(dst)
   189  	if err != nil {
   190  		return err
   191  	}
   192  	defer dstFile.Close()
   193  
   194  	_, err = io.Copy(dstFile, srcFile)
   195  	if err != nil {
   196  		return err
   197  	}
   198  
   199  	return nil
   200  }
   201  
   202  func copyDir(src, dst string) error {
   203  	err := filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
   204  		if err != nil {
   205  			return err
   206  		}
   207  
   208  		dstPath := filepath.Join(dst, path[len(src):])
   209  		if info.IsDir() {
   210  			err = os.MkdirAll(dstPath, info.Mode())
   211  			if err != nil {
   212  				return err
   213  			}
   214  		} else {
   215  			err = copyFile(path, dstPath)
   216  			if err != nil {
   217  				return err
   218  			}
   219  		}
   220  
   221  		return nil
   222  	})
   223  
   224  	return err
   225  }