full reworked
This commit is contained in:
parent
b6a535a5ba
commit
49466a901f
161
.gitignore
vendored
Normal file
161
.gitignore
vendored
Normal file
@ -0,0 +1,161 @@
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,goland,go
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,goland,go
|
||||
|
||||
### Go ###
|
||||
# If you prefer the allow list template instead of the deny list, see community template:
|
||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||
#
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
|
||||
### GoLand ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
.idea
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### GoLand Patch ###
|
||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||
|
||||
# *.iml
|
||||
# modules.xml
|
||||
# .idea/misc.xml
|
||||
# *.ipr
|
||||
|
||||
# Sonarlint plugin
|
||||
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
||||
.idea/**/sonarlint/
|
||||
|
||||
# SonarQube Plugin
|
||||
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
||||
.idea/**/sonarIssues.xml
|
||||
|
||||
# Markdown Navigator plugin
|
||||
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
||||
.idea/**/markdown-navigator.xml
|
||||
.idea/**/markdown-navigator-enh.xml
|
||||
.idea/**/markdown-navigator/
|
||||
|
||||
# Cache file creation bug
|
||||
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
||||
.idea/$CACHE_FILE$
|
||||
|
||||
# CodeStream plugin
|
||||
# https://plugins.jetbrains.com/plugin/12206-codestream
|
||||
.idea/codestream.xml
|
||||
|
||||
# Azure Toolkit for IntelliJ plugin
|
||||
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
|
||||
.idea/**/azureSettings.xml
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
.history
|
||||
.ionide
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,goland,go
|
@ -1,4 +1,4 @@
|
||||
# bluepint
|
||||
# blueprint
|
||||
|
||||
|
||||
|
||||
@ -15,14 +15,14 @@ Already a pro? Just edit this README.md and make it your own. Want to make it ea
|
||||
|
||||
```
|
||||
cd existing_repo
|
||||
git remote add origin https://penahub.gitlab.yandexcloud.net/pena-services/bluepint.git
|
||||
git remote add origin https://penahub.gitlab.yandexcloud.net/pena-services/blueprint.git
|
||||
git branch -M main
|
||||
git push -uf origin main
|
||||
```
|
||||
|
||||
## Integrate with your tools
|
||||
|
||||
- [ ] [Set up project integrations](https://penahub.gitlab.yandexcloud.net/pena-services/bluepint/-/settings/integrations)
|
||||
- [ ] [Set up project integrations](https://penahub.gitlab.yandexcloud.net/pena-services/blueprint/-/settings/integrations)
|
||||
|
||||
## Collaborate with your team
|
||||
|
||||
|
75
app/app.go
75
app/app.go
@ -1,75 +0,0 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/bluepint/blueprint"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/bluepint/creator"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
Config *Config
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Version string
|
||||
}
|
||||
|
||||
func NewApp(cfg *Config) *App {
|
||||
cfgLogger := zap.NewDevelopmentConfig()
|
||||
cfgLogger.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
||||
cfgLogger.EncoderConfig.ConsoleSeparator = " "
|
||||
|
||||
logger, err := cfgLogger.Build()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &App{
|
||||
Config: cfg,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute - Любой вызов приложения.
|
||||
func (r *App) Execute() {
|
||||
versionFlag := flag.Bool("v", false, "Show current version")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if *versionFlag {
|
||||
if err := r.Version(); err != nil {
|
||||
r.logger.Fatal("app.Version", zap.Error(err))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
r.Run()
|
||||
}
|
||||
|
||||
// Run - Запуск приложения.
|
||||
func (r *App) Run() {
|
||||
file, err := blueprint.FileToStruct("")
|
||||
|
||||
if err != nil {
|
||||
r.logger.Fatal("blueprint.FileToStruct", zap.Error(err))
|
||||
}
|
||||
|
||||
creator := creator.NewCreator(creator.Deps{Blueprint: file})
|
||||
|
||||
if err = creator.CreateApp(); err != nil {
|
||||
r.logger.Fatal("creator.CreateApp", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
// Version - Вывод версии приложения.
|
||||
func (r *App) Version() error {
|
||||
_, err := fmt.Println("Version: ", r.Config.Version)
|
||||
|
||||
return err
|
||||
}
|
@ -2,77 +2,62 @@ package blueprint
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"slices"
|
||||
"text/template"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
const BlueprintPath = "./blueprint.yaml"
|
||||
const BlueprintDefaultPath = "./"
|
||||
|
||||
type BlueprintFile struct {
|
||||
ProjectName string `yaml:"ProjectName"`
|
||||
Description string `yaml:"Description"`
|
||||
Folders map[FolderType]string `yaml:"Folders"`
|
||||
}
|
||||
|
||||
type FolderType uint8
|
||||
|
||||
const (
|
||||
UnknownFolder FolderType = iota
|
||||
MainFolder
|
||||
ModelsFolder
|
||||
ControllersFolder
|
||||
DBFolder
|
||||
var (
|
||||
BluePrintFileNames = []string{"Blueprint.yaml", "Blueprint.yml", "blueprint.yaml", "blueprint.yml"}
|
||||
)
|
||||
|
||||
func (r FolderType) stringMap() []string {
|
||||
return []string{
|
||||
"unknown",
|
||||
"main",
|
||||
"models",
|
||||
"controllers",
|
||||
"db",
|
||||
}
|
||||
// BlueprintFile - описание модели файла.
|
||||
type BlueprintFile struct {
|
||||
ProjectName string `yaml:"ProjectName"`
|
||||
Description string `yaml:"Description,omitempty"`
|
||||
Author string `yaml:"Author,omitempty"`
|
||||
ModulesSettings map[string]any `yaml:"Modules"`
|
||||
Template TemplateSettings `yaml:"Template,omitempty"`
|
||||
Vars map[string]any `yaml:"Vars,omitempty"`
|
||||
}
|
||||
|
||||
func (r FolderType) String() string {
|
||||
return r.stringMap()[r]
|
||||
}
|
||||
func readFile(blueprintFilePath string) (blueprint *BlueprintFile, err error) {
|
||||
var fileStat os.FileInfo
|
||||
|
||||
func (r FolderType) MarshalYAML() (interface{}, error) {
|
||||
return r.String(), nil
|
||||
}
|
||||
if blueprintFilePath == "" {
|
||||
for _, fileName := range BluePrintFileNames {
|
||||
blueprintFilePath = BlueprintDefaultPath + fileName
|
||||
|
||||
func (r *FolderType) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
var s string
|
||||
if err := unmarshal(&s); err != nil {
|
||||
return err
|
||||
fileStat, err = os.Stat(blueprintFilePath)
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
continue
|
||||
}
|
||||
|
||||
if fileStat.Size() <= 0 {
|
||||
return nil, fmt.Errorf("blueprint file is empty")
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
i := slices.Index[[]string, string](r.stringMap(), s)
|
||||
|
||||
if i == -1 {
|
||||
i = 0
|
||||
}
|
||||
|
||||
*r = FolderType(i)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func FileToStruct(blueprintPath string) (blueprint *BlueprintFile, err error) {
|
||||
if blueprintPath == "" {
|
||||
blueprintPath = BlueprintPath
|
||||
}
|
||||
|
||||
file, err := os.ReadFile(blueprintPath)
|
||||
file, err := os.ReadFile(blueprintFilePath)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return nil, fmt.Errorf("blueprint file not found")
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("cannot read blueprint file: %w", err)
|
||||
}
|
||||
|
||||
log.Info().Str("file", blueprintFilePath).Msg("Reading blueprint file")
|
||||
|
||||
// Получаем базовый файл.
|
||||
if err = yaml.Unmarshal(file, &blueprint); err != nil {
|
||||
return nil, fmt.Errorf("cannot parsing blueprint file: %w", err)
|
||||
|
77
blueprint/creator.go
Normal file
77
blueprint/creator.go
Normal file
@ -0,0 +1,77 @@
|
||||
package blueprint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
}
|
||||
|
||||
type BlueprintCreator struct {
|
||||
file *BlueprintFile
|
||||
template *Template
|
||||
modules []BlueprintModule
|
||||
}
|
||||
|
||||
type BlueprintModule interface {
|
||||
Name() string
|
||||
SetSettings(settings any) error
|
||||
GetFunctions() any
|
||||
Execute() error
|
||||
}
|
||||
|
||||
func NewBlueprintCreator(blueprintPath string) (*BlueprintCreator, error) {
|
||||
file, err := readFile(blueprintPath)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blueprintModules := []BlueprintModule{}
|
||||
|
||||
for _, module := range blueprintModules {
|
||||
if file.ModulesSettings[module.Name()] != nil {
|
||||
if err = module.SetSettings(file.ModulesSettings[module.Name()]); err != nil {
|
||||
return nil, fmt.Errorf("blueprintCreator: cannot set settings for module %v. %v", module.Name(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get absolute paths
|
||||
absExecPath, err := filepath.Abs("./")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("blueprintCreator: cannot get absolute path for execPath. %v", err)
|
||||
}
|
||||
|
||||
template := NewTemplate(TemplateSettings{
|
||||
ExecPath: absExecPath,
|
||||
TemplatePath: file.Template.TemplatePath,
|
||||
Vars: file.Template.Vars,
|
||||
Functions: nil,
|
||||
})
|
||||
|
||||
template.SetVar("ProjectName", file.ProjectName)
|
||||
template.SetVar("Author", file.Author)
|
||||
template.SetVar("Description", file.Description)
|
||||
|
||||
return &BlueprintCreator{
|
||||
template: template,
|
||||
file: file,
|
||||
modules: blueprintModules,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (r *BlueprintCreator) Create() error {
|
||||
for _, module := range r.modules {
|
||||
if err := module.Execute(); err != nil {
|
||||
return fmt.Errorf("module execute (%v). %v", module.Name(), err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := r.template.Execute(); err != nil {
|
||||
return fmt.Errorf("template execute. %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
208
blueprint/template.go
Normal file
208
blueprint/template.go
Normal file
@ -0,0 +1,208 @@
|
||||
package blueprint
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultPath = "./template"
|
||||
)
|
||||
|
||||
var (
|
||||
TemplateFormats = []string{"tmpl", "gotmpl"}
|
||||
)
|
||||
|
||||
type TemplateSettings struct {
|
||||
ExecPath string `yaml:"-"`
|
||||
TemplatePath string `yaml:"path"`
|
||||
Vars map[string]any `yaml:"vars,omitempty"`
|
||||
Functions map[string]any `yaml:"-"`
|
||||
}
|
||||
|
||||
type Template struct {
|
||||
settings *TemplateSettings
|
||||
queue []string
|
||||
}
|
||||
|
||||
func NewTemplate(settings TemplateSettings) *Template {
|
||||
if settings.Vars == nil {
|
||||
settings.Vars = make(map[string]any)
|
||||
}
|
||||
|
||||
if settings.Functions == nil {
|
||||
settings.Functions = make(map[string]any)
|
||||
}
|
||||
|
||||
return &Template{
|
||||
settings: &settings,
|
||||
queue: make([]string, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Template) SetVar(name string, value any) bool {
|
||||
if _, ok := r.settings.Vars[name]; ok {
|
||||
return false
|
||||
}
|
||||
|
||||
r.settings.Vars[name] = value
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *Template) SetSettings(settings any) error {
|
||||
out, err := yaml.Marshal(settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = yaml.Unmarshal(out, &r.settings); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if r.settings.TemplatePath == "" {
|
||||
r.settings.TemplatePath = DefaultPath
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Template) Execute() error {
|
||||
log.Info().Msg("template.Execute: started")
|
||||
err := filepath.WalkDir(r.settings.TemplatePath, r.walkFunc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, path := range r.queue {
|
||||
if err = r.templateFile(path); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return r.execCommands()
|
||||
}
|
||||
|
||||
func (r *Template) templateFile(templatePath string) error {
|
||||
// Create output path - replace template path to exec path
|
||||
sp := strings.Split(templatePath, "template")
|
||||
|
||||
outputFile := r.settings.ExecPath + sp[1]
|
||||
|
||||
// Create outputh path - template path
|
||||
t, err := template.New("filepath").Parse(outputFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("templateFile: parse filepath (%v). %v", templatePath, err)
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
if err = t.Execute(buf, r.settings.Vars); err != nil {
|
||||
return fmt.Errorf("templateFile: execute filepath (%v). %v", templatePath, err)
|
||||
}
|
||||
|
||||
outputFile = buf.String()
|
||||
|
||||
// Create output path - replace file format to .go
|
||||
for _, format := range TemplateFormats {
|
||||
outputFile = strings.Replace(outputFile, "."+format, "", -1)
|
||||
}
|
||||
|
||||
// Create file
|
||||
|
||||
err = os.MkdirAll(filepath.Dir(outputFile), 0750)
|
||||
if err != nil {
|
||||
return fmt.Errorf("templateFile: make directory (%v). %v", filepath.Dir(outputFile), err)
|
||||
}
|
||||
|
||||
file, err := os.Create(outputFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Template file
|
||||
t, err = template.New(filepath.Base(templatePath)).ParseFiles(templatePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("templateFile: parse template (%v). %v", templatePath, err)
|
||||
}
|
||||
|
||||
if err = t.Execute(file, r.settings.Vars); err != nil {
|
||||
return fmt.Errorf("templateFile: execute template (%v). %v", templatePath, err)
|
||||
}
|
||||
|
||||
log.Info().Str("file", outputFile).Msg("templateFile: file generated")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Template) execCommands() error {
|
||||
cmd := exec.Command("go", "mod", "init")
|
||||
|
||||
log.Info().Msg("execCommands: go mod init")
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd = exec.Command("go", "mod", "tidy")
|
||||
|
||||
log.Info().Msg("execCommands: go mod tidy")
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("execCommands: go mod tidy. %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Template) walkFunc(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("walkFunc: %v", err)
|
||||
}
|
||||
|
||||
info, err := d.Info()
|
||||
if err != nil {
|
||||
return fmt.Errorf("walkFunc: cannot get info about path (%v). %v", path, err)
|
||||
}
|
||||
|
||||
if isTemplateFile(info) {
|
||||
absTemplatePath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("walkFunc: cannot get absolut path for path (%v). %v", path, err)
|
||||
}
|
||||
|
||||
r.queue = append(r.queue, absTemplatePath)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isTemplateFile(info fs.FileInfo) bool {
|
||||
if info.IsDir() {
|
||||
return false
|
||||
}
|
||||
|
||||
sp := strings.Split(info.Name(), ".")
|
||||
|
||||
if len(sp) < 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
format := strings.ToLower(sp[len(sp)-1])
|
||||
|
||||
for _, v := range TemplateFormats {
|
||||
if format == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
62
cmd/app.go
Normal file
62
cmd/app.go
Normal file
@ -0,0 +1,62 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/bluepint/blueprint"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
Config *Config
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Version string
|
||||
}
|
||||
|
||||
func NewApp(cfg *Config) *App {
|
||||
return &App{
|
||||
Config: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute - Любой вызов приложения.
|
||||
func (r *App) Execute() {
|
||||
versionFlag := flag.Bool("v", false, "Show current version")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if *versionFlag {
|
||||
if err := r.PrintVersion(); err != nil {
|
||||
log.Error().Err(err).Msg("PrintVersion")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
r.Run()
|
||||
}
|
||||
|
||||
// Run - Запуск приложения.
|
||||
func (r *App) Run() {
|
||||
log.Info().Str("version", r.Config.Version).Msg("Blueprint started")
|
||||
blueprintCreator, err := blueprint.NewBlueprintCreator("")
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("NewBlueprintCreator")
|
||||
return
|
||||
}
|
||||
|
||||
if err = blueprintCreator.Create(); err != nil {
|
||||
log.Error().Err(err).Msg("BlueprintCreator.Create")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// PrintVersion - Вывод версии приложения.
|
||||
func (r *App) PrintVersion() error {
|
||||
_, err := fmt.Println("Version: ", r.Config.Version)
|
||||
|
||||
return err
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package creator
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/bluepint/blueprint"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
Blueprint *blueprint.BlueprintFile
|
||||
}
|
||||
|
||||
type Creator struct {
|
||||
blueprint *blueprint.BlueprintFile
|
||||
}
|
||||
|
||||
func NewCreator(deps Deps) *Creator {
|
||||
return &Creator{
|
||||
blueprint: deps.Blueprint,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Creator) CreateApp() error {
|
||||
return r.makeFolders()
|
||||
}
|
||||
|
||||
func (r *Creator) makeFolders() error {
|
||||
for _, folderPath := range r.blueprint.Folders {
|
||||
if err := os.MkdirAll(folderPath, 0750); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
ProjectName: test
|
||||
Description: Some descr
|
||||
|
||||
Folders:
|
||||
main: ./cmd/{{.ProjectName}}
|
||||
models: ./internal/model
|
||||
controllers: ./internal/controller
|
||||
db: ./internal/repository
|
||||
adapters: ./internal/adapter
|
||||
server: ./internal/server
|
5
examples/default/Blueprint.yaml
Normal file
5
examples/default/Blueprint.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
ProjectName: blueprint-project-example
|
||||
Description: Some descr
|
||||
|
||||
Template:
|
||||
path: "./"
|
161
examples/default/template/.gitignore.tmpl
Normal file
161
examples/default/template/.gitignore.tmpl
Normal file
@ -0,0 +1,161 @@
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,goland,go
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,goland,go
|
||||
|
||||
### Go ###
|
||||
# If you prefer the allow list template instead of the deny list, see community template:
|
||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||
#
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
|
||||
### GoLand ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
.idea
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### GoLand Patch ###
|
||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||
|
||||
# *.iml
|
||||
# modules.xml
|
||||
# .idea/misc.xml
|
||||
# *.ipr
|
||||
|
||||
# Sonarlint plugin
|
||||
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
||||
.idea/**/sonarlint/
|
||||
|
||||
# SonarQube Plugin
|
||||
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
||||
.idea/**/sonarIssues.xml
|
||||
|
||||
# Markdown Navigator plugin
|
||||
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
||||
.idea/**/markdown-navigator.xml
|
||||
.idea/**/markdown-navigator-enh.xml
|
||||
.idea/**/markdown-navigator/
|
||||
|
||||
# Cache file creation bug
|
||||
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
||||
.idea/$CACHE_FILE$
|
||||
|
||||
# CodeStream plugin
|
||||
# https://plugins.jetbrains.com/plugin/12206-codestream
|
||||
.idea/codestream.xml
|
||||
|
||||
# Azure Toolkit for IntelliJ plugin
|
||||
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
|
||||
.idea/**/azureSettings.xml
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
.history
|
||||
.ionide
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,goland,go
|
11
examples/default/template/cmd/{{.ProjectName}}/main.go.tmpl
Normal file
11
examples/default/template/cmd/{{.ProjectName}}/main.go.tmpl
Normal file
@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"{{.ProjectName}}/internal/app"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := app.New()
|
||||
app.Run()
|
||||
}
|
||||
|
17
examples/default/template/internal/app/app.go.tmpl
Normal file
17
examples/default/template/internal/app/app.go.tmpl
Normal file
@ -0,0 +1,17 @@
|
||||
package app
|
||||
|
||||
type App struct {
|
||||
config *Config
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Name string `env:"NAME"`
|
||||
}
|
||||
|
||||
func New() *App {
|
||||
return &App{}
|
||||
}
|
||||
|
||||
func (r *App) Run() {
|
||||
|
||||
}
|
11
go.mod
11
go.mod
@ -2,9 +2,14 @@ module penahub.gitlab.yandexcloud.net/pena-services/bluepint
|
||||
|
||||
go 1.21.0
|
||||
|
||||
require go.uber.org/zap v1.26.0
|
||||
require (
|
||||
github.com/rs/zerolog v1.31.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
)
|
||||
|
30
go.sum
30
go.sum
@ -1,15 +1,21 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
||||
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
|
7
main.go
7
main.go
@ -1,11 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/bluepint/app"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/bluepint/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := app.NewApp(&app.Config{Version: "0.0.1"})
|
||||
|
||||
app.Execute()
|
||||
cmd := cmd.NewApp(&cmd.Config{Version: "0.0.1"})
|
||||
cmd.Execute()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user