Skip to content

Commit

Permalink
add support for old compose file
Browse files Browse the repository at this point in the history
  • Loading branch information
mkhuda committed Aug 4, 2024
1 parent 793775e commit f4174f7
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 55 deletions.
112 changes: 81 additions & 31 deletions internal/dockercompose/dockercompose.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import (

"github.com/fatih/color"
DockermiTypes "github.com/mkhuda/dockermi/types"

"gopkg.in/yaml.v2"
// "github.com/goccy/go-yaml"
)

// FindServices searches for docker-compose.yml files in the specified directory.
Expand Down Expand Up @@ -41,14 +43,26 @@ func FindServices(root string, force bool) (DockermiTypes.ServiceScriptReturn, e
}

for serviceName, service := range composedFiles {
order, orderExists := service.Labels["dockermi.order"]
active, activeExists := service.Labels["dockermi.active"]
order, active := "", ""
orderExists, activeExists := false, false

// Access the labels directly
if val, exists := service.Labels["dockermi.order"]; exists {
order, orderExists = val, true
}
if val, exists := service.Labels["dockermi.active"]; exists {
active, activeExists = val, true
}

includeService := true
if orderExists && activeExists && active == "true" {
// Determine if the service should be included
var includeService bool

if force {
// If force is true, always include the service
includeService = true
} else if !orderExists && !activeExists {
includeService = force || false
} else {
// Otherwise, check the order and active labels
includeService = (orderExists && activeExists && active == "true")
}

if includeService {
Expand All @@ -57,6 +71,7 @@ func FindServices(root string, force bool) (DockermiTypes.ServiceScriptReturn, e
ServiceName: serviceName,
ComposeFile: path,
})

} else if activeExists {
color.Yellow("Service '%s' is inactive (dockermi.active=false). Skipping...", serviceName)
} else {
Expand Down Expand Up @@ -112,7 +127,10 @@ func FindServicesWithKey(root string) (map[string][]DockermiTypes.ServiceScript,
active, activeExists := service.Labels["dockermi.active"]
key := service.Labels["dockermi.key"] // Check for dockermi.key

if orderExists && activeExists && active == "true" {
if key != "" && orderExists && activeExists && active == "true" {
if _, exists := groups[key]; !exists {
groups[key] = []DockermiTypes.ServiceScript{}
}
groups[key] = append(groups[key], DockermiTypes.ServiceScript{
Order: order,
ServiceName: serviceName,
Expand Down Expand Up @@ -155,42 +173,74 @@ func ParseComposeFile(path string, withKey bool, force bool) (map[string]Dockerm
return nil, err
}

var composeFile DockermiTypes.DockerCompose
var composeFile map[string]interface{}
err = yaml.Unmarshal(file, &composeFile)
if err != nil {
// invalid docker-compose.yml file or yaml that can't be unmarshalled
// will not throw an error, just return an empty map
return nil, nil
}

// Convert the services to include their names and labels
services := make(map[string]DockermiTypes.Service)
for name, service := range composeFile.Services {
labels := service.Labels
hasLabel := len(labels) != 0
if force {
services[name] = DockermiTypes.Service{
Name: name,
Labels: service.Labels,

servicesData, exists := composeFile["services"]
if !exists {
return nil, nil
}

if servicesData, ok := servicesData.(map[interface{}]interface{}); ok {
for name, data := range servicesData {
if serviceData, ok := data.(map[interface{}]interface{}); ok {
service, err := unmarshalService(serviceData)
if err != nil {
return nil, err
}
service.Name = name.(string) // Set the service name
services[name.(string)] = service
}
}
if hasLabel {
active, activeExists := service.Labels["dockermi.active"]
if activeExists && active == "true" {
// Default value for dockermi.key if not present
if _, exists := service.Labels["dockermi.key"]; !exists && withKey {
// Assign a default value or generate a unique key
service.Labels["dockermi.key"] = "default" // Example default value
}
}

services[name] = DockermiTypes.Service{
Name: name,
Labels: service.Labels,
}
return services, nil
}

// Custom unmarshal function to handle labels
func unmarshalService(data map[interface{}]interface{}) (DockermiTypes.Service, error) {
service := DockermiTypes.Service{
Labels: make(map[string]string),
}

if val, ok := data["image"].(string); ok {
service.Image = val
}
if ports, ok := data["ports"].([]interface{}); ok {
for _, port := range ports {
if p, ok := port.(string); ok {
service.Ports = append(service.Ports, p)
}
}
}

// Handle labels
if labels, ok := data["labels"]; ok {
switch labels := labels.(type) {
case []interface{}:
for _, label := range labels {
if strLabel, ok := label.(string); ok {
parts := strings.SplitN(strLabel, "=", 2)
if len(parts) == 2 {
service.Labels[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
}
}
}
case map[interface{}]interface{}:
for k, v := range labels {
if key, ok := k.(string); ok {
if value, ok := v.(string); ok {
service.Labels[key] = value
}
}
}
}
}

return services, nil
return service, nil
}
12 changes: 4 additions & 8 deletions pkg/dockermi.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

func GetVersion() string {
return "v0.1.4"
return "v0.1.5"
}

// RunDockermi executes the main logic of the dockermi command. It takes a
Expand All @@ -34,8 +34,8 @@ func RunDockermi(projectDir string) (string, error) {
// Define flags for help and version
help := flag.Bool("help", false, "Display help information")
versionFlag := flag.Bool("version", false, "Display version information")
// Short version flag
shortVersionFlag := flag.Bool("v", false, "Display version information")
force := flag.Bool("force", false, "Force script generation")
flag.Parse()

// Check for version flags
Expand All @@ -61,14 +61,12 @@ func RunDockermi(projectDir string) (string, error) {
return "", fmt.Errorf("missing key for create command")
}
return createDockermiScript(projectDir, os.Args[2])
case "--force":
return generateScripts(projectDir, true)
default:
return generateScripts(projectDir, false)
return generateScripts(projectDir, *force)
}
}
// If no specific command is provided, generate the scripts
return generateScripts(projectDir, false)
return generateScripts(projectDir, *force)
}

// handleUpDownCommand handles the 'up' command logic.
Expand Down Expand Up @@ -149,8 +147,6 @@ func createDockermiScript(projectDir string, key string) (string, error) {
return "", err
}

color.Red("find %v", services)

// Check if the key exists in the services map
groupedServices, exists := services[key]
if !exists {
Expand Down
19 changes: 10 additions & 9 deletions pkg/dockermi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestCreatedDockermi(t *testing.T) {
// Check if the dockermi.sh file is created
scriptPath := filepath.Join(currentDir, "dockermi.sh")
if _, err := os.Stat(scriptPath); os.IsNotExist(err) {
t.Errorf("Expected dockermi.sh to be created, but it was not.")
t.Errorf("TestCreatedDockermi Expected dockermi.sh to be created, but it was not.")
}

// Clean up after test
Expand All @@ -78,9 +78,9 @@ func TestFindService(t *testing.T) {

servicesLength := len(services)

expectedLength := 6
expectedLength := 10
if servicesLength != expectedLength {
t.Fatalf("Expected %v keys to be created. Created keys are: %v", expectedLength, servicesLength)
t.Fatalf("[TestFindService] Expected %v keys to be created. Created keys are: %v", expectedLength, servicesLength)
}
}

Expand All @@ -101,9 +101,9 @@ func TestFindServiceForce(t *testing.T) {
}
servicesLength := len(services)

expectedLength := 9
expectedLength := 14
if servicesLength != expectedLength {
t.Fatalf("Expected %v keys to be created. Created keys are: %v", expectedLength, servicesLength)
t.Fatalf("[TestFindServiceForce] Expected %v keys to be created. Created keys are: %v", expectedLength, servicesLength)
}
}

Expand All @@ -118,13 +118,14 @@ func TestFindServiceByKey(t *testing.T) {
t.Fatalf("Error getting current working directory: %v", err)
}

services, err := dockercompose.FindServicesWithKey(projectDir)
groupedServices, err := dockercompose.FindServicesWithKey(projectDir)
if err != nil {
t.Fatalf("Error finding services: %v", err)
}
servicesLength := len(services)
if servicesLength != 3 {
t.Fatalf("Expected 3 keys to be created. Create keys are: %v", servicesLength)
servicesLength := len(groupedServices)
expectedGroups := 2
if servicesLength != expectedGroups {
t.Fatalf("Expected %v groupedServices to be created. Grouped keys are: %v ", expectedGroups, servicesLength)
}
}

Expand Down
3 changes: 1 addition & 2 deletions test/nginx/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ services:
- "80:80"
labels:
dockermi.order: "1"
dockermi.active: "true"
dockermi.key: 'yourweb'
dockermi.active: "true"
6 changes: 6 additions & 0 deletions test/oldcompose/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
services:
oldcompose:
image: hello-world
labels:
- "dockermi.order=2"
- "dockermi.active=true"
3 changes: 1 addition & 2 deletions test/postgres/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ services:
- "5432:5432"
labels:
dockermi.order: "1"
dockermi.active: "true"
dockermi.key: "myweb"
dockermi.active: "true"
14 changes: 14 additions & 0 deletions test/withkeys1/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
services:
servicewithkey1x:
image: hello-world
labels:
dockermi.order: "1"
dockermi.active: "true"
dockermi.key: "key1"

servicewithkey1xx:
image: hello-world
labels:
dockermi.order: "2"
dockermi.active: "true"
dockermi.key: "key1"
14 changes: 14 additions & 0 deletions test/withkeys2/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
services:
servicewithkey2x:
image: hello-world
labels:
dockermi.order: "1"
dockermi.active: "false" # This service is not active
dockermi.key: "key2"

servicewithkey2xx:
image: hello-world
labels:
dockermi.order: "2"
dockermi.active: "true"
dockermi.key: "key2"
6 changes: 3 additions & 3 deletions types/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ type ServiceScriptReturn []ServiceScript

// Service represents a service in the docker-compose.yml file.
type Service struct {
Name string
// Image string `yaml:"image"`
// Ports []string `yaml:"ports"`
Name string
Image string `yaml:"image"`
Ports []string `yaml:"ports"`
Labels map[string]string `yaml:"labels"`
}

Expand Down

0 comments on commit f4174f7

Please sign in to comment.