github.com/section/sectionctl@v1.12.3/commands/parsePackageJson.go (about)

     1  package commands
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"strconv"
     9  	"strings"
    10  
    11  	"github.com/alecthomas/kong"
    12  	"github.com/rs/zerolog/log"
    13  )
    14  
    15  type PackageJSON struct {
    16  	Name         string            `json:"name"`
    17  	Version      string            `json:"version"`
    18  	Dependencies map[string]string `json:"dependencies"`
    19  	Scripts      map[string]string `json:"scripts"`
    20  	Section      struct {
    21  		AccountID   string `json:"accountId"`
    22  		AppID       string `json:"appId"`
    23  		Environment string `json:"environment"`
    24  		ModuleName  string `json:"module-name"`
    25  		StartScript string `json:"start-script"`
    26  	} `json:"section"`
    27  	X map[string]interface{} `json:"-"` // Rest of the fields should go here.
    28  }
    29  type PotentialIntValues struct {
    30  	Section struct {
    31  		AccountID int `json:"accountId"`
    32  		AppID     int `json:"appId"`
    33  	} `json:"section"`
    34  }
    35  type MinimalPackageJSON struct {
    36  	Section struct {
    37  		AccountID   string `json:"accountId"`
    38  		AppID       string `json:"appId"`
    39  		Environment string `json:"environment"`
    40  		ModuleName  string `json:"module-name"`
    41  		StartScript string `json:"start-script"`
    42  	} `json:"section"`
    43  	X map[string]interface{} `json:"-"` // Rest of the fields should go here.
    44  }
    45  type SectionConfigJSON struct {
    46  	Proxychain []struct {
    47  		Name  string `json:"name"`
    48  		Image string `json:"image"`
    49  	} `json:"proxychain"`
    50  	X map[string]interface{} `json:"-"` // Rest of the fields should go here.
    51  }
    52  
    53  // Try to fit the contents of the package.json into one of the three structs defined above, as JSON isn't strictly typed.
    54  func ParsePackageJSON(packageJSONContents string) (PackageJSON, error) {
    55  	packageJSONContent := new(bytes.Buffer)
    56  	if err := json.Compact(packageJSONContent, []byte(packageJSONContents)); err != nil {
    57  		log.Debug().Err(err).Msg("Error compacting json while parsing your package.json")
    58  		return PackageJSON{}, err
    59  	}
    60  	packageJSON := PackageJSON{}
    61  	if err := json.Unmarshal(packageJSONContent.Bytes(), &packageJSON); err != nil {
    62  		potentialIntValues := PotentialIntValues{}
    63  		if err2 := json.Unmarshal(packageJSONContent.Bytes(), &potentialIntValues); err2 != nil {
    64  				log.Debug().Err(err).Err(err2).Msg("Error unmarshaling your package.json")
    65  		}else{
    66  			if potentialIntValues.Section.AccountID != 0 {
    67  				packageJSON.Section.AccountID = strconv.Itoa(potentialIntValues.Section.AccountID)
    68  			}
    69  			if potentialIntValues.Section.AppID != 0 {
    70  				packageJSON.Section.AppID = strconv.Itoa(potentialIntValues.Section.AppID)
    71  			}
    72  		}
    73  	}
    74  	return packageJSON, nil
    75  }
    76  
    77  func ParseSectionConfig(sectionConfigContents string) (SectionConfigJSON, error) {
    78  	sectionConfigContent := new(bytes.Buffer)
    79  	if err := json.Compact(sectionConfigContent, []byte(sectionConfigContents)); err != nil {
    80  		log.Debug().Err(err).Msg("Error compacting json while parsing your section.config.json")
    81  	}
    82  	sectionConfig := SectionConfigJSON{}
    83  	dec := json.NewDecoder(strings.NewReader(sectionConfigContent.String()))
    84  	if err := dec.Decode(&sectionConfig); err != nil {
    85  		return SectionConfigJSON{}, fmt.Errorf("failed to decode JSON: %v", err)
    86  	}
    87  	return sectionConfig, nil
    88  }
    89  
    90  // JSON returns a Resolver that retrieves values from a JSON source.
    91  //
    92  // Hyphens in flag names are replaced with underscores.
    93  func PackageJSONResolver(r io.Reader) (kong.Resolver, error) {
    94  	buf := new(bytes.Buffer)
    95  	_, err := buf.ReadFrom(r)
    96  	if err != nil{
    97  		return nil,nil
    98  	}
    99  	s := buf.String()
   100  	packageJSON, err:= ParsePackageJSON(s)
   101  	if err != nil {
   102  		log.Info().Err(err).Msg("Error parsing package.json")
   103  	}
   104  	var f kong.ResolverFunc = func(context *kong.Context, parent *kong.Path, flag *kong.Flag) (interface{}, error) {
   105  		accountID,err := strconv.Atoi(packageJSON.Section.AccountID)
   106  		if err == nil{
   107  			if accountID > 0 && flag.Name=="account-id" {
   108  				return packageJSON.Section.AccountID, nil
   109  			}
   110  		}
   111  		appID,err := strconv.Atoi(packageJSON.Section.AppID)
   112  		if err == nil{
   113  			if appID > 0 && flag.Name=="app-id" {
   114  				return packageJSON.Section.AppID, nil
   115  			}
   116  		}
   117  		if len(packageJSON.Section.Environment) > 0 && flag.Name=="environment" {
   118  			return packageJSON.Section.Environment, nil
   119  		}
   120  		if len(packageJSON.Section.ModuleName) > 0 && flag.Name=="app-path" {
   121  			return packageJSON.Section.ModuleName, nil
   122  		}
   123  		return nil, nil
   124  	}
   125  
   126  	return f, nil
   127  }