full reworked

This commit is contained in:
Danil Solovyov 2023-12-22 21:37:12 +05:00
parent b6a535a5ba
commit 49466a901f
16 changed files with 770 additions and 193 deletions

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

@ -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

@ -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

@ -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

@ -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

@ -0,0 +1,5 @@
ProjectName: blueprint-project-example
Description: Some descr
Template:
path: "./"

@ -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

@ -0,0 +1,11 @@
package main
import (
"{{.ProjectName}}/internal/app"
)
func main() {
app := app.New()
app.Run()
}

@ -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

@ -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

@ -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=

@ -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()
}