-
-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New predefined template dev command (#216)
* Hide commands that are not available * Add base structure * Adjust file permissions * Fix bug with creating the template dir * Fix typo * Add dev check * Extend * Add test for happy path * Add more tests
- Loading branch information
1 parent
44f2542
commit 881f692
Showing
15 changed files
with
426 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/urfave/cli/v2" | ||
) | ||
|
||
// CliCommands is a list of all available cli commands for Compose Generator | ||
var CliCommands = []*cli.Command{ | ||
{ | ||
Name: "generate", | ||
Aliases: []string{"g", "gen"}, | ||
Usage: "Generates a docker compose configuration", | ||
Flags: GenerateCliFlags, | ||
Action: Generate, | ||
}, | ||
{ | ||
Name: "add", | ||
Aliases: []string{"a"}, | ||
Usage: "Adds a service to an existing compose file", | ||
Flags: AddCliFlags, | ||
Action: Add, | ||
}, | ||
{ | ||
Name: "remove", | ||
Aliases: []string{"r", "rm"}, | ||
Usage: "Removes a service from an existing compose file", | ||
Flags: RemoveCliFlags, | ||
Action: Remove, | ||
}, | ||
{ | ||
Name: "template", | ||
Aliases: []string{"t"}, | ||
Usage: "Manages snapshots of your compose configuration for later use", | ||
Subcommands: []*cli.Command{ | ||
{ | ||
Name: "save", | ||
Aliases: []string{"s"}, | ||
Usage: "Save a custom template.", | ||
Flags: TemplateSaveCliFlags, | ||
Action: SaveTemplate, | ||
}, | ||
{ | ||
Name: "load", | ||
Aliases: []string{"l"}, | ||
Usage: "Load a custom template.", | ||
Flags: TemplateLoadCliFlags, | ||
Action: LoadTemplate, | ||
}, | ||
{ | ||
Name: "delete", | ||
Aliases: []string{"d"}, | ||
Usage: "Delete a custom template.", | ||
Flags: TemplateDeleteCliFlags, | ||
Action: DeleteTemplate, | ||
}, | ||
}, | ||
}, | ||
{ | ||
Name: "install", | ||
Aliases: []string{"i", "in"}, | ||
Usage: "Installs Docker and Docker Compose with a single command", | ||
Hidden: isDockerizedEnvironment(), | ||
Action: Install, | ||
}, | ||
{ | ||
Name: "predefined-template", | ||
Aliases: []string{"p", "pd"}, | ||
Usage: "Manages predefined service templates (this command does only exist in dev environments)", | ||
Hidden: !isDevVersion(), | ||
Subcommands: []*cli.Command{ | ||
{ | ||
Name: "new", | ||
Aliases: []string{"n"}, | ||
Usage: "Creates a blank predefined service template", | ||
Flags: PredefinedTemplateNewCliFlags, | ||
Action: NewPredefinedTemplate, | ||
}, | ||
}, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
package cmd | ||
|
||
import ( | ||
"compose-generator/model" | ||
"encoding/json" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/urfave/cli/v2" | ||
) | ||
|
||
// PredefinedTemplateNewCliFlags are the cli flags for the remove command | ||
var PredefinedTemplateNewCliFlags = []cli.Flag{} | ||
|
||
// ---------------------------------------------------------------- Public functions --------------------------------------------------------------- | ||
|
||
// NewPredefinedTemplate generates a blank predefined service template in the respective directory | ||
func NewPredefinedTemplate(context *cli.Context) error { | ||
infoLogger.Println("NewPredefinedTemplate command executed") | ||
|
||
if !isDevVersion() { | ||
errorLogger.Println("Executed NewPredefinedTemplate command without being dev. Aborting.") | ||
logError("Cannot run this command in a production environment.", true) | ||
return nil | ||
} | ||
|
||
// Ask user questions and save to disk subsequently | ||
config, service, readme := createNewPredefinedTemplate() | ||
savePredefinedTemplate(config, service, readme) | ||
|
||
return nil | ||
} | ||
|
||
const serviceTemplate = `image: hello-world:${{%s_VERSION}} | ||
container_name: ${{PROJECT_NAME_CONTAINER}}-%s-%s | ||
%snetworks: | ||
# ToDo: Insert or remove section | ||
ports: | ||
# ToDo: Insert or remove section | ||
volumes: | ||
# ToDo: Insert or remove section | ||
env_file: | ||
# ToDo: Insert or delete section` | ||
|
||
// --------------------------------------------------------------- Private functions --------------------------------------------------------------- | ||
|
||
func createNewPredefinedTemplate() (*model.PredefinedTemplateConfig, string, string) { | ||
config := model.PredefinedTemplateConfig{} | ||
|
||
// Ask for template label | ||
config.Label = textQuestion("Template label:") | ||
config.Name = strings.ReplaceAll(strings.ToLower(config.Label), " ", "-") | ||
snakeUpperName := strings.ToUpper(strings.ReplaceAll(config.Name, "-", "_")) | ||
|
||
// Ask for template type | ||
config.Type = menuQuestion("What is the closest match of specifying the type?", []string{ | ||
model.TemplateTypeFrontend, | ||
model.TemplateTypeBackend, | ||
model.TemplateTypeDatabase, | ||
model.TemplateTypeDbAdmin, | ||
}) | ||
|
||
// Set default configuration | ||
config.Preselected = "false" | ||
config.Proxied = config.Type == model.TemplateTypeFrontend || config.Type == model.TemplateTypeDbAdmin | ||
config.Files = []model.File{ | ||
{ | ||
Path: "service.yml", | ||
Type: "service", | ||
}, | ||
{ | ||
Path: "README.md", | ||
Type: "docs", | ||
}, | ||
} | ||
config.Questions = []model.Question{ | ||
{ | ||
Text: "Which version of " + config.Label + " do you want to use?", | ||
Type: model.QuestionTypeText, | ||
DefaultValue: "latest", | ||
Variable: snakeUpperName + "_VERSION", | ||
}, | ||
} | ||
|
||
// Check if dir already exists | ||
config.Dir = getPredefinedServicesPath() + "/" + config.Type + "/" + config.Name | ||
if fileExists(config.Dir) { | ||
errorLogger.Println("Predefined template dir '" + config.Dir + "' already exists. Aborting.") | ||
logError("Template dir already exists. Aborting.", true) | ||
return nil, "", "" | ||
} | ||
|
||
// Prepare Readme contents | ||
readme := fmt.Sprintf("## %s\nToDo: Insert software description here.\n\n### Setup\nToDo: Insert setup instructions here.", config.Label) | ||
|
||
// Prepare service contents | ||
restartRule := "" | ||
if config.Type != model.TemplateTypeDbAdmin { | ||
restartRule = "restart: always\n" | ||
} | ||
service := fmt.Sprintf(serviceTemplate, snakeUpperName, config.Type, config.Name, restartRule) | ||
|
||
return &config, service, readme | ||
} | ||
|
||
func savePredefinedTemplate(config *model.PredefinedTemplateConfig, service, readme string) { | ||
pel() | ||
spinner := startProcess("Saving predefined service template ...") | ||
// Create dir | ||
if err := mkDir(config.Dir, 0777); err != nil { | ||
errorLogger.Println("Error creating the template dir '" + config.Dir + "': " + err.Error()) | ||
logError("Error creating the template dir", true) | ||
return | ||
} | ||
|
||
// Save config.json | ||
file, err := json.MarshalIndent(config, "", " ") | ||
if err != nil { | ||
errorLogger.Println("Error marshaling predefined template config to json: " + err.Error()) | ||
logError("Error marshaling config to json", true) | ||
return | ||
} | ||
if err = writeFile(config.Dir+"/config.json", file, 0600); err != nil { | ||
errorLogger.Println("Error writing predefined template config to file: " + err.Error()) | ||
logError("Error saving config.json", true) | ||
return | ||
} | ||
|
||
// Save service.yml | ||
if err = writeFile(config.Dir+"/service.yml", []byte(service), 0600); err != nil { | ||
errorLogger.Println("Error writing service to file: " + err.Error()) | ||
logError("Error saving service.yml", true) | ||
return | ||
} | ||
|
||
// Save README.md | ||
if err = writeFile(config.Dir+"/README.md", []byte(readme), 0600); err != nil { | ||
errorLogger.Println("Error writing Readme to file: " + err.Error()) | ||
logError("Error saving README.md", true) | ||
return | ||
} | ||
stopProcess(spinner) | ||
} |
Oops, something went wrong.