github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/cmd/generates/modules/generator.go (about)

     1  /*
     2   * Copyright 2023 Wang Min Xiang
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   * 	http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   */
    17  
    18  package modules
    19  
    20  import (
    21  	"context"
    22  	"fmt"
    23  	"github.com/aacfactory/errors"
    24  	"github.com/aacfactory/fns/cmd/generates/processes"
    25  	"github.com/aacfactory/fns/cmd/generates/sources"
    26  	"github.com/aacfactory/fns/cmd/generates/spinner"
    27  	"path/filepath"
    28  	"time"
    29  )
    30  
    31  const (
    32  	DefaultDir = "modules"
    33  )
    34  
    35  func NewGenerator(dir string, annotations FnAnnotationCodeWriters, verbose bool) *Generator {
    36  	if dir == "" {
    37  		dir = DefaultDir
    38  	}
    39  	return &Generator{
    40  		dir:         dir,
    41  		annotations: annotations,
    42  		verbose:     verbose,
    43  	}
    44  }
    45  
    46  type Generator struct {
    47  	verbose     bool
    48  	dir         string
    49  	annotations FnAnnotationCodeWriters
    50  }
    51  
    52  func (generator *Generator) Generate(ctx context.Context, mod *sources.Module) (err error) {
    53  	// parse services
    54  	services, parseServicesErr := Load(mod, generator.dir)
    55  	if parseServicesErr != nil {
    56  		err = errors.Warning("modules: generate failed").WithCause(parseServicesErr)
    57  		return
    58  	}
    59  	if len(services) == 0 {
    60  		return
    61  	}
    62  	// make process controller
    63  	process := processes.New()
    64  	functionParseUnits := make([]processes.Unit, 0, 1)
    65  	serviceCodeFileUnits := make([]processes.Unit, 0, 1)
    66  	for _, service := range services {
    67  		for _, function := range service.Functions {
    68  			functionParseUnits = append(functionParseUnits, function)
    69  		}
    70  		serviceCodeFileUnits = append(serviceCodeFileUnits, Unit(NewServiceFile(service, generator.annotations)))
    71  	}
    72  	process.Add("generates: parsing", functionParseUnits...)
    73  	process.Add("generates: writing", serviceCodeFileUnits...)
    74  	process.Add("generates: deploys", Unit(NewDeploysFile(filepath.ToSlash(filepath.Join(mod.Dir, "modules")), services)))
    75  
    76  	if generator.verbose {
    77  		results := process.Start(ctx)
    78  		for {
    79  			result, ok := <-results
    80  			if !ok {
    81  				fmt.Println("generates: generate finished")
    82  				break
    83  			}
    84  			fmt.Println(result, "->", fmt.Sprintf("[%d/%d]", result.UnitNo, result.UnitNum), result.Data)
    85  			if result.Error != nil {
    86  				err = result.Error
    87  				_ = process.Abort(1 * time.Second)
    88  				return
    89  			}
    90  		}
    91  	} else {
    92  		sp := spinner.New(
    93  			spinner.CharSets[11], 100*time.Millisecond,
    94  			spinner.WithSuffix("  generating..."),
    95  			spinner.WithColor("fgGreen"),
    96  		)
    97  		sp.Start()
    98  		results := process.Start(ctx)
    99  		for {
   100  			result, ok := <-results
   101  			if !ok {
   102  				break
   103  			}
   104  			if result.Error != nil {
   105  				err = result.Error
   106  				_ = process.Abort(1 * time.Second)
   107  				break
   108  			}
   109  		}
   110  		sp.Stop()
   111  	}
   112  	return
   113  }