get.porter.sh/porter@v1.3.0/pkg/porter/create.go (about)

     1  package porter
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"get.porter.sh/porter/pkg"
    11  	"get.porter.sh/porter/pkg/config"
    12  )
    13  
    14  // Create creates a new bundle configuration in the current directory
    15  func (p *Porter) Create() error {
    16  	fmt.Fprintln(p.Out, "creating porter configuration in the current directory")
    17  	destinationDir := "." // current directory
    18  
    19  	if err := p.CopyTemplate(p.Templates.GetManifest, filepath.Join(destinationDir, config.Name)); err != nil {
    20  		return err
    21  	}
    22  	return p.copyAllTemplatesExceptPorterYaml(destinationDir)
    23  }
    24  
    25  // CreateInDir creates a new bundle configuration in the specified directory. The directory will be created if it
    26  // doesn't already exist. For example, if dir is "foo/bar/baz", the directory structure "foo/bar/baz" will be created.
    27  // The bundle name will be set to the "base" of the given directory, which is "baz" in the example above.
    28  func (p *Porter) CreateInDir(dir string) error {
    29  	bundleName := filepath.Base(dir)
    30  
    31  	// Create dirs if they don't exist
    32  	_, err := p.FileSystem.Stat(dir)
    33  	if errors.Is(err, os.ErrNotExist) {
    34  		err = p.FileSystem.MkdirAll(dir, 0755)
    35  	}
    36  	if err != nil {
    37  		// the Stat failed with an error different from os.ErrNotExist OR the MkdirAll failed to create the dir(s)
    38  		return fmt.Errorf("failed to create directory for bundle: %w", err)
    39  	}
    40  
    41  	// create porter.yaml, using base of given dir as the bundle name
    42  	err = p.CopyTemplate(func() ([]byte, error) {
    43  		content, err := p.Templates.GetManifest()
    44  		if err != nil {
    45  			return nil, err
    46  		}
    47  		content = []byte(strings.ReplaceAll(string(content), "porter-hello", bundleName))
    48  		return content, nil
    49  	}, filepath.Join(dir, config.Name))
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	return p.copyAllTemplatesExceptPorterYaml(dir)
    55  }
    56  
    57  func (p *Porter) copyAllTemplatesExceptPorterYaml(destinationDir string) error {
    58  	err := p.CopyTemplate(p.Templates.GetManifestHelpers, filepath.Join(destinationDir, "helpers.sh"))
    59  	if err != nil {
    60  		return err
    61  	}
    62  
    63  	err = p.CopyTemplate(p.Templates.GetReadme, filepath.Join(destinationDir, "README.md"))
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	err = p.CopyTemplate(p.Templates.GetDockerfileTemplate, filepath.Join(destinationDir, "template.Dockerfile"))
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	err = p.CopyTemplate(p.Templates.GetDockerignore, filepath.Join(destinationDir, ".dockerignore"))
    74  	if err != nil {
    75  		return err
    76  	}
    77  
    78  	return p.CopyTemplate(p.Templates.GetGitignore, filepath.Join(destinationDir, ".gitignore"))
    79  }
    80  
    81  func (p *Porter) CopyTemplate(getTemplate func() ([]byte, error), dest string) error {
    82  	tmpl, err := getTemplate()
    83  	if err != nil {
    84  		return err
    85  	}
    86  
    87  	var mode os.FileMode = pkg.FileModeWritable
    88  	if filepath.Ext(dest) == ".sh" {
    89  		mode = pkg.FileModeExecutable
    90  	}
    91  
    92  	if _, err := p.FileSystem.Stat(dest); err == nil {
    93  		fmt.Fprintf(p.Err, "WARNING: File %q already exists. Overwriting.\n", dest)
    94  	}
    95  	err = p.FileSystem.WriteFile(dest, tmpl, mode)
    96  	if err != nil {
    97  		return fmt.Errorf("failed to write template to %s: %w", dest, err)
    98  	}
    99  	return nil
   100  }