github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/maven/archetype.go (about)

     1  package maven
     2  
     3  import (
     4  	"strings"
     5  
     6  	"fmt"
     7  	"sort"
     8  
     9  	"github.com/olli-ai/jx/v2/pkg/util"
    10  	"gopkg.in/AlecAivazis/survey.v1"
    11  )
    12  
    13  const (
    14  	MavenArchetypePluginVersion = "3.0.1"
    15  )
    16  
    17  type ArtifactVersions struct {
    18  	GroupId     string
    19  	ArtifactId  string
    20  	Description string
    21  	Versions    []string
    22  }
    23  
    24  type GroupArchectypes struct {
    25  	GroupId   string
    26  	Artifacts map[string]*ArtifactVersions
    27  }
    28  
    29  type ArchetypeModel struct {
    30  	Groups map[string]*GroupArchectypes
    31  }
    32  
    33  type ArtifactData struct {
    34  	GroupId     string
    35  	ArtifactId  string
    36  	Version     string
    37  	Description string
    38  }
    39  
    40  type ArchetypeFilter struct {
    41  	GroupIds         []string
    42  	GroupIdFilter    string
    43  	ArtifactIdFilter string
    44  	Version          string
    45  }
    46  
    47  type ArchetypeForm struct {
    48  	ArchetypeGroupId    string
    49  	ArchetypeArtifactId string
    50  	ArchetypeVersion    string
    51  
    52  	GroupId    string
    53  	ArtifactId string
    54  	Package    string
    55  	Version    string
    56  }
    57  
    58  func NewArchetypeModel() ArchetypeModel {
    59  	return ArchetypeModel{
    60  		Groups: map[string]*GroupArchectypes{},
    61  	}
    62  }
    63  
    64  func (m *ArchetypeModel) GroupIDs(filter string) []string {
    65  	answer := []string{}
    66  	for group := range m.Groups {
    67  		if filter == "" || strings.Index(group, filter) >= 0 {
    68  			answer = append(answer, group)
    69  		}
    70  	}
    71  	sort.Strings(answer)
    72  	return answer
    73  }
    74  
    75  func (m *ArchetypeModel) ArtifactIDs(groupId string, filter string) []string {
    76  	answer := []string{}
    77  	artifact := m.Groups[groupId]
    78  	if artifact != nil {
    79  		for a := range artifact.Artifacts {
    80  			if filter == "" || strings.Index(a, filter) >= 0 {
    81  				answer = append(answer, a)
    82  			}
    83  		}
    84  		sort.Strings(answer)
    85  	}
    86  	return answer
    87  }
    88  
    89  func (m *ArchetypeModel) Versions(groupId string, artifactId, filter string) []string {
    90  	answer := []string{}
    91  	artifact := m.Groups[groupId]
    92  	if artifact != nil {
    93  		av := artifact.Artifacts[artifactId]
    94  		if av != nil {
    95  			for _, v := range av.Versions {
    96  				if filter == "" || strings.Index(v, filter) >= 0 {
    97  					answer = append(answer, v)
    98  				}
    99  			}
   100  			// TODO use a version sorter?
   101  			sort.Sort(sort.Reverse(sort.StringSlice(answer)))
   102  		}
   103  	}
   104  	return answer
   105  }
   106  
   107  func (m *ArchetypeModel) AddArtifact(a *ArtifactData) *ArtifactVersions {
   108  	groupId := a.GroupId
   109  	artifactId := a.ArtifactId
   110  	version := a.Version
   111  	description := a.Description
   112  	if groupId == "" || artifactId == "" || version == "" {
   113  		return nil
   114  	}
   115  
   116  	if m.Groups == nil {
   117  		m.Groups = map[string]*GroupArchectypes{}
   118  	}
   119  	group := m.Groups[groupId]
   120  	if group == nil {
   121  		group = &GroupArchectypes{
   122  			GroupId:   groupId,
   123  			Artifacts: map[string]*ArtifactVersions{},
   124  		}
   125  		m.Groups[groupId] = group
   126  	}
   127  	artifact := group.Artifacts[artifactId]
   128  	if artifact == nil {
   129  		artifact = &ArtifactVersions{
   130  			GroupId:    groupId,
   131  			ArtifactId: artifactId,
   132  			Versions:   []string{},
   133  		}
   134  		group.Artifacts[artifactId] = artifact
   135  	}
   136  	if artifact.Description == "" && description != "" {
   137  		artifact.Description = description
   138  	}
   139  	if util.StringArrayIndex(artifact.Versions, version) < 0 {
   140  		artifact.Versions = append(artifact.Versions, version)
   141  	}
   142  	return artifact
   143  }
   144  
   145  func (model *ArchetypeModel) CreateSurvey(data *ArchetypeFilter, pickVersion bool, form *ArchetypeForm, handles util.IOFileHandles) error {
   146  	surveyOpts := survey.WithStdio(handles.In, handles.Out, handles.Err)
   147  	groupIds := data.GroupIds
   148  	if len(data.GroupIds) == 0 {
   149  		filteredGroups := model.GroupIDs(data.GroupIdFilter)
   150  		if len(filteredGroups) == 0 {
   151  			return util.InvalidOption("group-filter", data.GroupIdFilter, model.GroupIDs(""))
   152  		}
   153  
   154  		// lets pick from all groups
   155  		prompt := &survey.Select{
   156  			Message: "Group ID:",
   157  			Options: filteredGroups,
   158  		}
   159  		err := survey.AskOne(prompt, &form.ArchetypeGroupId, survey.Required, surveyOpts)
   160  		if err != nil {
   161  			return err
   162  		}
   163  		artifactsWithoutFilter := model.ArtifactIDs(form.ArchetypeGroupId, "")
   164  		if len(artifactsWithoutFilter) == 0 {
   165  			return fmt.Errorf("Could not find any artifacts for group %s", form.ArchetypeGroupId)
   166  		}
   167  	} else {
   168  		// TODO for now lets just support a single group ID being passed in
   169  		form.ArchetypeGroupId = groupIds[0]
   170  
   171  		artifactsWithoutFilter := model.ArtifactIDs(form.ArchetypeGroupId, "")
   172  		if len(artifactsWithoutFilter) == 0 {
   173  			return util.InvalidOption("group", form.ArchetypeGroupId, model.GroupIDs(""))
   174  		}
   175  	}
   176  	if form.ArchetypeGroupId == "" {
   177  		return fmt.Errorf("No archetype groupId selected")
   178  	}
   179  
   180  	artifactIds := model.ArtifactIDs(form.ArchetypeGroupId, data.ArtifactIdFilter)
   181  	if len(artifactIds) == 0 {
   182  		artifactsWithoutFilter := model.ArtifactIDs(form.ArchetypeGroupId, "")
   183  		return util.InvalidOption("artifact", data.ArtifactIdFilter, artifactsWithoutFilter)
   184  	}
   185  
   186  	if len(artifactIds) == 1 {
   187  		form.ArchetypeArtifactId = artifactIds[0]
   188  	} else {
   189  		prompt := &survey.Select{
   190  			Message: "Artifact ID:",
   191  			Options: artifactIds,
   192  		}
   193  		err := survey.AskOne(prompt, &form.ArchetypeArtifactId, survey.Required, surveyOpts)
   194  		if err != nil {
   195  			return err
   196  		}
   197  	}
   198  	if form.ArchetypeArtifactId == "" {
   199  		return fmt.Errorf("No archetype artifactId selected")
   200  	}
   201  
   202  	version := data.Version
   203  	versions := model.Versions(form.ArchetypeGroupId, form.ArchetypeArtifactId, version)
   204  	if len(versions) == 0 {
   205  		return util.InvalidOption("version", version, model.Versions(form.ArchetypeGroupId, form.ArchetypeArtifactId, ""))
   206  	}
   207  
   208  	if len(versions) == 1 || !pickVersion {
   209  		form.ArchetypeVersion = versions[0]
   210  	} else {
   211  		prompt := &survey.Select{
   212  			Message: "Version:",
   213  			Options: versions,
   214  		}
   215  		err := survey.AskOne(prompt, &form.ArchetypeVersion, survey.Required, surveyOpts)
   216  		if err != nil {
   217  			return err
   218  		}
   219  	}
   220  	if form.ArchetypeVersion == "" {
   221  		return fmt.Errorf("No archetype version selected")
   222  	}
   223  
   224  	if form.GroupId == "" {
   225  		q := &survey.Input{
   226  			Message: "Project Group ID:",
   227  			Default: "com.acme",
   228  		}
   229  		err := survey.AskOne(q, &form.GroupId, survey.Required, surveyOpts)
   230  		if err != nil {
   231  			return err
   232  		}
   233  	}
   234  	if form.ArtifactId == "" {
   235  		q := &survey.Input{
   236  			Message: "Project Artifact ID:",
   237  			Default: "",
   238  		}
   239  		err := survey.AskOne(q, &form.ArtifactId, survey.Required, surveyOpts)
   240  		if err != nil {
   241  			return err
   242  		}
   243  	}
   244  	if form.Version == "" {
   245  		q := &survey.Input{
   246  			Message: "Project Version:",
   247  			Default: "1.0.0-SNAPSHOT",
   248  		}
   249  		err := survey.AskOne(q, &form.Version, survey.Required, surveyOpts)
   250  		if err != nil {
   251  			return err
   252  		}
   253  	}
   254  	return nil
   255  }