github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/cmd/vpm/baseline.go (about)

     1  /*
     2   * Copyright (c) 2023-present unTill Pro, Ltd.
     3   * @author Alisher Nurmanov
     4   */
     5  
     6  package main
     7  
     8  import (
     9  	"encoding/json"
    10  	"fmt"
    11  	"os"
    12  	"path/filepath"
    13  	"strings"
    14  	"time"
    15  
    16  	"github.com/spf13/cobra"
    17  	"github.com/voedger/voedger/pkg/goutils/exec"
    18  	"github.com/voedger/voedger/pkg/goutils/logger"
    19  	"github.com/voedger/voedger/pkg/parser"
    20  
    21  	"github.com/voedger/voedger/pkg/compile"
    22  	coreutils "github.com/voedger/voedger/pkg/utils"
    23  )
    24  
    25  func newBaselineCmd(params *vpmParams) *cobra.Command {
    26  	cmd := &cobra.Command{
    27  		Use:   "baseline baseline-folder",
    28  		Short: "create baseline schemas",
    29  		Args:  exactArgs(1),
    30  		RunE: func(cmd *cobra.Command, args []string) (err error) {
    31  			compileRes, err := compile.Compile(params.Dir)
    32  			if err != nil {
    33  				return err
    34  			}
    35  			return baseline(compileRes, params.Dir, params.TargetDir)
    36  		},
    37  	}
    38  	return cmd
    39  }
    40  
    41  // baseline creates baseline schemas in target dir
    42  func baseline(compileRes *compile.Result, dir, targetDir string) error {
    43  	if err := createBaselineDir(targetDir); err != nil {
    44  		return err
    45  	}
    46  
    47  	pkgDir := filepath.Join(targetDir, pkgDirName)
    48  	if err := saveBaselineSchemas(compileRes.PkgFiles, pkgDir); err != nil {
    49  		return err
    50  	}
    51  
    52  	if err := saveBaselineInfo(compileRes, dir, targetDir); err != nil {
    53  		return err
    54  	}
    55  	return nil
    56  }
    57  
    58  // saveBaselineInfo saves baseline info into target dir
    59  // baseline info includes baseline package url, timestamp and git commit hash
    60  func saveBaselineInfo(compileRes *compile.Result, dir, targetDir string) error {
    61  	var gitCommitHash string
    62  	sb := new(strings.Builder)
    63  	if err := new(exec.PipedExec).Command("git", "rev-parse", "HEAD").WorkingDir(dir).Run(sb, os.Stderr); err == nil {
    64  		gitCommitHash = strings.TrimSpace(sb.String())
    65  	}
    66  
    67  	baselineInfoObj := baselineInfo{
    68  		BaselinePackageUrl: compileRes.ModulePath,
    69  		Timestamp:          time.Now().In(time.FixedZone("GMT", 0)).Format(timestampFormat),
    70  		GitCommitHash:      gitCommitHash,
    71  	}
    72  
    73  	content, err := json.MarshalIndent(baselineInfoObj, "", "  ")
    74  	if err != nil {
    75  		return err
    76  	}
    77  
    78  	baselineInfoFilePath := filepath.Join(targetDir, baselineInfoFileName)
    79  	if err := os.WriteFile(baselineInfoFilePath, content, coreutils.FileMode_rw_rw_rw_); err != nil {
    80  		return err
    81  	}
    82  	if logger.IsVerbose() {
    83  		logger.Verbose("create baseline info file: %s", baselineInfoFilePath)
    84  	}
    85  	return nil
    86  }
    87  
    88  func saveBaselineSchemas(pkgFiles packageFiles, baselineDir string) error {
    89  	for qpn, files := range pkgFiles {
    90  		packageDir := filepath.Join(baselineDir, qpn)
    91  		if err := os.MkdirAll(packageDir, coreutils.FileMode_rwxrwxrwx); err != nil {
    92  			return err
    93  		}
    94  		for _, file := range files {
    95  			base := filepath.Base(file)
    96  			fileNameExtensionless := base[:len(base)-len(filepath.Ext(base))]
    97  			if err := coreutils.CopyFile(file, packageDir, coreutils.WithNewName(fileNameExtensionless+parser.VSqlExt)); err != nil {
    98  				return fmt.Errorf(errFmtCopyFile, file, err)
    99  			}
   100  			if logger.IsVerbose() {
   101  				filePath := filepath.Join(packageDir, fileNameExtensionless+parser.VSqlExt)
   102  				logger.Verbose("baseline file created: %s", filePath)
   103  			}
   104  		}
   105  	}
   106  	return nil
   107  }
   108  
   109  func createBaselineDir(dir string) error {
   110  	exists, err := coreutils.Exists(dir)
   111  	if err != nil {
   112  		// notest
   113  		return err
   114  	}
   115  	if exists {
   116  		return fmt.Errorf("baseline directory already exists: %s", dir)
   117  	}
   118  	pkgDir := filepath.Join(dir, pkgDirName)
   119  	return os.MkdirAll(pkgDir, coreutils.FileMode_rwxrwxrwx)
   120  }