github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/builder/manifest.go (about)

     1  package builder
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io/fs"
     7  	"os"
     8  	"path"
     9  
    10  	yaml "gopkg.in/yaml.v3"
    11  
    12  	"github.com/nevalang/neva/internal/compiler/sourcecode"
    13  	src "github.com/nevalang/neva/internal/compiler/sourcecode"
    14  )
    15  
    16  func (p Builder) getNearestManifest(wd string) (src.ModuleManifest, string, error) {
    17  	rawNearest, path, err := lookupManifestFile(wd, 0)
    18  	if err != nil {
    19  		return sourcecode.ModuleManifest{}, "", fmt.Errorf("read manifest yaml: %w", err)
    20  	}
    21  
    22  	parsedNearest, err := p.manifestParser.ParseManifest(rawNearest)
    23  	if err != nil {
    24  		return sourcecode.ModuleManifest{}, "", fmt.Errorf("parse manifest: %w", err)
    25  	}
    26  
    27  	return parsedNearest, path, nil
    28  }
    29  
    30  
    31  func lookupManifestFile(wd string, iteration int) ([]byte, string, error) {
    32  	if iteration > 10 {
    33  		return nil, "", errors.New("manifest file not found in 10 nearest levels up to where cli executed")
    34  	}
    35  
    36  	found, err := readManifestFromDir(wd)
    37  	if err == nil {
    38  		return found,  wd, nil
    39  	}
    40  
    41  	if !errors.Is(err, fs.ErrInvalid) &&
    42  		!errors.Is(err, os.ErrNotExist) {
    43  		return nil, "", err
    44  	}
    45  
    46  	return lookupManifestFile(
    47  		path.Dir(wd),
    48  		iteration+1,
    49  	)
    50  }
    51  
    52  func readManifestFromDir(wd string) ([]byte, error) {
    53  	raw, err := os.ReadFile(path.Join(wd, "neva.yaml"))
    54  	if err == nil {
    55  		return raw, nil
    56  	}
    57  
    58  	return os.ReadFile(path.Join(wd, "neva.yml"))
    59  }
    60  
    61  func (b Builder) writeManifest(manifest src.ModuleManifest, workdir string) error {
    62  	manifestData, err := yaml.Marshal(manifest)
    63  	if err != nil {
    64  		return fmt.Errorf("marshal manifest: %w", err)
    65  	}
    66  
    67  	manifestFileName := "neva.yaml"
    68  	if _, err := os.Stat(workdir + "/neva.yml"); err == nil {
    69  		manifestFileName = "neva.yml"
    70  	}
    71  
    72  	manifestPath := workdir + "/" + manifestFileName
    73  	file, err := os.OpenFile(manifestPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
    74  	if err != nil {
    75  		return fmt.Errorf("open file: %w", err)
    76  	}
    77  	defer file.Close()
    78  
    79  	_, err = file.Write(manifestData)
    80  	if err != nil {
    81  		return fmt.Errorf("write file: %w", err)
    82  	}
    83  
    84  	return nil
    85  }