github.com/goravel/framework@v1.13.9/foundation/application.go (about)

     1  package foundation
     2  
     3  import (
     4  	"flag"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/goravel/framework/config"
    10  	consolecontract "github.com/goravel/framework/contracts/console"
    11  	"github.com/goravel/framework/contracts/foundation"
    12  	"github.com/goravel/framework/foundation/console"
    13  	"github.com/goravel/framework/support"
    14  	"github.com/goravel/framework/support/carbon"
    15  )
    16  
    17  var (
    18  	App foundation.Application
    19  )
    20  
    21  var _ = flag.String("env", ".env", "custom .env path")
    22  
    23  func init() {
    24  	setEnv()
    25  
    26  	app := &Application{
    27  		Container:     NewContainer(),
    28  		publishes:     make(map[string]map[string]string),
    29  		publishGroups: make(map[string]map[string]string),
    30  	}
    31  	app.registerBaseServiceProviders()
    32  	app.bootBaseServiceProviders()
    33  	App = app
    34  }
    35  
    36  type Application struct {
    37  	foundation.Container
    38  	publishes     map[string]map[string]string
    39  	publishGroups map[string]map[string]string
    40  }
    41  
    42  func NewApplication() foundation.Application {
    43  	return App
    44  }
    45  
    46  // Boot Register and bootstrap configured service providers.
    47  func (app *Application) Boot() {
    48  	app.registerConfiguredServiceProviders()
    49  	app.bootConfiguredServiceProviders()
    50  	app.registerCommands([]consolecontract.Command{
    51  		console.NewTestMakeCommand(),
    52  		console.NewPackageMakeCommand(),
    53  		console.NewVendorPublishCommand(app.publishes, app.publishGroups),
    54  	})
    55  	app.bootArtisan()
    56  	app.setTimezone()
    57  	setRootPath()
    58  }
    59  
    60  func (app *Application) Commands(commands []consolecontract.Command) {
    61  	app.registerCommands(commands)
    62  }
    63  
    64  func (app *Application) Path(path string) string {
    65  	return filepath.Join("app", path)
    66  }
    67  
    68  func (app *Application) BasePath(path string) string {
    69  	return filepath.Join("", path)
    70  }
    71  
    72  func (app *Application) ConfigPath(path string) string {
    73  	return filepath.Join("config", path)
    74  }
    75  
    76  func (app *Application) DatabasePath(path string) string {
    77  	return filepath.Join("database", path)
    78  }
    79  
    80  func (app *Application) StoragePath(path string) string {
    81  	return filepath.Join("storage", path)
    82  }
    83  
    84  func (app *Application) PublicPath(path string) string {
    85  	return filepath.Join("public", path)
    86  }
    87  
    88  func (app *Application) Publishes(packageName string, paths map[string]string, groups ...string) {
    89  	app.ensurePublishArrayInitialized(packageName)
    90  
    91  	for key, value := range paths {
    92  		app.publishes[packageName][key] = value
    93  	}
    94  
    95  	for _, group := range groups {
    96  		app.addPublishGroup(group, paths)
    97  	}
    98  }
    99  
   100  func (app *Application) ensurePublishArrayInitialized(packageName string) {
   101  	if _, exist := app.publishes[packageName]; !exist {
   102  		app.publishes[packageName] = make(map[string]string)
   103  	}
   104  }
   105  
   106  func (app *Application) addPublishGroup(group string, paths map[string]string) {
   107  	if _, exist := app.publishGroups[group]; !exist {
   108  		app.publishGroups[group] = make(map[string]string)
   109  	}
   110  
   111  	for key, value := range paths {
   112  		app.publishGroups[group][key] = value
   113  	}
   114  }
   115  
   116  // bootArtisan Boot artisan command.
   117  func (app *Application) bootArtisan() {
   118  	app.MakeArtisan().Run(os.Args, true)
   119  }
   120  
   121  // getBaseServiceProviders Get base service providers.
   122  func (app *Application) getBaseServiceProviders() []foundation.ServiceProvider {
   123  	return []foundation.ServiceProvider{
   124  		&config.ServiceProvider{},
   125  	}
   126  }
   127  
   128  // getConfiguredServiceProviders Get configured service providers.
   129  func (app *Application) getConfiguredServiceProviders() []foundation.ServiceProvider {
   130  	return app.MakeConfig().Get("app.providers").([]foundation.ServiceProvider)
   131  }
   132  
   133  // registerBaseServiceProviders Register base service providers.
   134  func (app *Application) registerBaseServiceProviders() {
   135  	app.registerServiceProviders(app.getBaseServiceProviders())
   136  }
   137  
   138  // bootBaseServiceProviders Bootstrap base service providers.
   139  func (app *Application) bootBaseServiceProviders() {
   140  	app.bootServiceProviders(app.getBaseServiceProviders())
   141  }
   142  
   143  // registerConfiguredServiceProviders Register configured service providers.
   144  func (app *Application) registerConfiguredServiceProviders() {
   145  	app.registerServiceProviders(app.getConfiguredServiceProviders())
   146  }
   147  
   148  // bootConfiguredServiceProviders Bootstrap configured service providers.
   149  func (app *Application) bootConfiguredServiceProviders() {
   150  	app.bootServiceProviders(app.getConfiguredServiceProviders())
   151  }
   152  
   153  // registerServiceProviders Register service providers.
   154  func (app *Application) registerServiceProviders(serviceProviders []foundation.ServiceProvider) {
   155  	for _, serviceProvider := range serviceProviders {
   156  		serviceProvider.Register(app)
   157  	}
   158  }
   159  
   160  // bootServiceProviders Bootstrap service providers.
   161  func (app *Application) bootServiceProviders(serviceProviders []foundation.ServiceProvider) {
   162  	for _, serviceProvider := range serviceProviders {
   163  		serviceProvider.Boot(app)
   164  	}
   165  }
   166  
   167  func (app *Application) registerCommands(commands []consolecontract.Command) {
   168  	app.MakeArtisan().Register(commands)
   169  }
   170  
   171  func (app *Application) setTimezone() {
   172  	carbon.SetTimezone(app.MakeConfig().GetString("app.timezone", carbon.UTC))
   173  }
   174  
   175  func setEnv() {
   176  	args := os.Args
   177  	if strings.HasSuffix(os.Args[0], ".test") || strings.HasSuffix(os.Args[0], ".test.exe") {
   178  		support.Env = support.EnvTest
   179  	}
   180  	if len(args) >= 2 {
   181  		for _, arg := range args[1:] {
   182  			if arg == "artisan" {
   183  				support.Env = support.EnvArtisan
   184  			}
   185  			if arg == "key:generate" {
   186  				support.IsKeyGenerateCommand = true
   187  			}
   188  		}
   189  	}
   190  
   191  	env := getEnvPath()
   192  	if support.Env == support.EnvTest {
   193  		var (
   194  			relativePath string
   195  			envExist     bool
   196  			testEnv      = env
   197  		)
   198  
   199  		for i := 0; i < 50; i++ {
   200  			if _, err := os.Stat(testEnv); err == nil {
   201  				envExist = true
   202  
   203  				break
   204  			} else {
   205  				testEnv = filepath.Join("../", testEnv)
   206  				relativePath = filepath.Join("../", relativePath)
   207  			}
   208  		}
   209  
   210  		if envExist {
   211  			env = testEnv
   212  			support.RelativePath = relativePath
   213  		}
   214  	}
   215  
   216  	support.EnvPath = env
   217  }
   218  
   219  func setRootPath() {
   220  	rootPath := getCurrentAbsolutePath()
   221  
   222  	// Hack air path
   223  	airPath := "/storage/temp"
   224  	if strings.HasSuffix(rootPath, airPath) {
   225  		rootPath = strings.ReplaceAll(rootPath, airPath, "")
   226  	}
   227  
   228  	support.RootPath = rootPath
   229  }
   230  
   231  func getEnvPath() string {
   232  	envPath := ".env"
   233  	args := os.Args
   234  	for index, arg := range args {
   235  		if strings.HasPrefix(arg, "--env=") {
   236  			if path := strings.TrimPrefix(arg, "--env="); path != "" {
   237  				envPath = path
   238  				break
   239  			}
   240  		}
   241  		if strings.HasPrefix(arg, "-env=") {
   242  			if path := strings.TrimPrefix(arg, "-env="); path != "" {
   243  				envPath = path
   244  				break
   245  			}
   246  		}
   247  		if strings.HasPrefix(arg, "-e=") {
   248  			if path := strings.TrimPrefix(arg, "-e="); path != "" {
   249  				envPath = path
   250  				break
   251  			}
   252  		}
   253  		if arg == "--env" || arg == "-env" || arg == "-e" {
   254  			if len(args) >= index+1 && !strings.HasPrefix(args[index+1], "-") {
   255  				envPath = args[index+1]
   256  				break
   257  			}
   258  		}
   259  	}
   260  
   261  	return envPath
   262  }