11package playground
22
33import (
4+ "encoding/json"
45 "fmt"
56 "os"
67 "path/filepath"
@@ -26,8 +27,8 @@ type Recipe interface {
2627type Manifest struct {
2728 ctx * ExContext
2829
29- // list of services
30- services []* Service
30+ // list of Services
31+ Services []* Service `json:"services"`
3132
3233 // overrides is a map of service name to the path of the executable to run
3334 // on the host machine instead of a container.
@@ -88,10 +89,6 @@ type ServiceReady interface {
8889 Ready (instance * instance ) error
8990}
9091
91- func (s * Manifest ) Services () []* Service {
92- return s .services
93- }
94-
9592// ReleaseService is a service that can also be runned as an artifact in the host machine
9693type ReleaseService interface {
9794 ReleaseArtifact () * release
@@ -102,7 +99,7 @@ func (s *Manifest) AddService(name string, srv ServiceGen) {
10299 service .ComponentName = srv .Name ()
103100 srv .Run (service , s .ctx )
104101
105- s .services = append (s .services , service )
102+ s .Services = append (s .Services , service )
106103}
107104
108105func (s * Manifest ) MustGetService (name string ) * Service {
@@ -114,7 +111,7 @@ func (s *Manifest) MustGetService(name string) *Service {
114111}
115112
116113func (s * Manifest ) GetService (name string ) (* Service , bool ) {
117- for _ , ss := range s .services {
114+ for _ , ss := range s .Services {
118115 if ss .Name == name {
119116 return ss , true
120117 }
@@ -126,7 +123,7 @@ func (s *Manifest) GetService(name string) (*Service, bool) {
126123// - checks if all the port dependencies are met from the service description
127124// - downloads any local release artifacts for the services that require host execution
128125func (s * Manifest ) Validate () error {
129- for _ , ss := range s .services {
126+ for _ , ss := range s .Services {
130127 // validate node port references
131128 for _ , nodeRef := range ss .NodeRefs {
132129 targetService , ok := s .GetService (nodeRef .Service )
@@ -156,7 +153,7 @@ func (s *Manifest) Validate() error {
156153 }
157154
158155 // validate that the mounts are correct
159- for _ , ss := range s .services {
156+ for _ , ss := range s .Services {
160157 for _ , fileNameRef := range ss .FilesMapped {
161158 fileLoc := filepath .Join (s .out .dst , fileNameRef )
162159
@@ -170,7 +167,7 @@ func (s *Manifest) Validate() error {
170167 }
171168
172169 // validate that the mounts are correct
173- for _ , ss := range s .services {
170+ for _ , ss := range s .Services {
174171 for _ , fileNameRef := range ss .FilesMapped {
175172 fileLoc := filepath .Join (s .out .dst , fileNameRef )
176173
@@ -194,10 +191,10 @@ const (
194191// Port describes a port that a service exposes
195192type Port struct {
196193 // Name is the name of the port
197- Name string
194+ Name string `json:"name"`
198195
199196 // Port is the port number
200- Port int
197+ Port int `json:"port"`
201198
202199 // Protocol (tcp or udp)
203200 Protocol string
@@ -210,10 +207,10 @@ type Port struct {
210207
211208// NodeRef describes a reference from one service to another
212209type NodeRef struct {
213- Service string
214- PortLabel string
215- Protocol string
216- User string
210+ Service string `json:"service"`
211+ PortLabel string `json:"port_label"`
212+ Protocol string `json:"protocol"`
213+ User string `json:"user"`
217214}
218215
219216// serviceLogs is a service to access the logs of the running service
@@ -501,12 +498,12 @@ func (s *Manifest) GenerateDotGraph() string {
501498
502499 // Create a map of services for easy lookup
503500 servicesMap := make (map [string ]* Service )
504- for _ , ss := range s .services {
501+ for _ , ss := range s .Services {
505502 servicesMap [ss .Name ] = ss
506503 }
507504
508505 // Add nodes (services) with their ports as labels
509- for _ , ss := range s .services {
506+ for _ , ss := range s .Services {
510507 var ports []string
511508 for _ , p := range ss .Ports {
512509 ports = append (ports , fmt .Sprintf ("%s:%d" , p .Name , p .Port ))
@@ -523,7 +520,7 @@ func (s *Manifest) GenerateDotGraph() string {
523520 b .WriteString ("\n " )
524521
525522 // Add edges (connections between services)
526- for _ , ss := range s .services {
523+ for _ , ss := range s .Services {
527524 sourceNode := strings .ReplaceAll (ss .Name , "-" , "_" )
528525 for _ , ref := range ss .NodeRefs {
529526 targetNode := strings .ReplaceAll (ref .Service , "-" , "_" )
@@ -536,7 +533,7 @@ func (s *Manifest) GenerateDotGraph() string {
536533 }
537534
538535 // Add edges for dependws_on
539- for _ , ss := range s .services {
536+ for _ , ss := range s .Services {
540537 for _ , dep := range ss .DependsOn {
541538 sourceNode := strings .ReplaceAll (ss .Name , "-" , "_" )
542539 targetNode := strings .ReplaceAll (dep .Name , "-" , "_" )
@@ -557,8 +554,29 @@ func saveDotGraph(svcManager *Manifest, out *output) error {
557554}
558555
559556func (m * Manifest ) SaveJson () error {
560- format := map [string ]interface {}{
561- "services" : m .services ,
557+ return m .out .WriteFile ("manifest.json" , m )
558+ }
559+
560+ func ReadManifest (outputFolder string ) (* Manifest , error ) {
561+ // read outputFolder/manifest.json file
562+ manifestFile := filepath .Join (outputFolder , "manifest.json" )
563+ if _ , err := os .Stat (manifestFile ); os .IsNotExist (err ) {
564+ return nil , fmt .Errorf ("manifest file %s does not exist" , manifestFile )
565+ }
566+ manifest , err := os .ReadFile (manifestFile )
567+ if err != nil {
568+ return nil , fmt .Errorf ("failed to read manifest file %s: %w" , manifestFile , err )
569+ }
570+
571+ // parse the manifest file
572+ var manifestData Manifest
573+ if err := json .Unmarshal (manifest , & manifestData ); err != nil {
574+ return nil , fmt .Errorf ("failed to parse manifest file %s: %w" , manifestFile , err )
575+ }
576+
577+ // set the output folder
578+ manifestData .out = & output {
579+ dst : outputFolder ,
562580 }
563- return m . out . WriteFile ( "manifest.json" , format )
581+ return & manifestData , nil
564582}
0 commit comments