Skip to content

Commit b901715

Browse files
authored
Merge pull request #32 from zechtz/hotfix/java-home
Hotfix/java home
2 parents 61d70e8 + 73fac9d commit b901715

9 files changed

Lines changed: 244 additions & 60 deletions

File tree

internal/database/database.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,11 @@ func (db *Database) initTables() error {
349349
return fmt.Errorf("failed to migrate service name constraint: %w", err)
350350
}
351351

352+
// Add verbose_logging column for build tool verbose/debug output
353+
if err := db.migrateAddVerboseLoggingColumn(); err != nil {
354+
return fmt.Errorf("failed to add verbose_logging column: %w", err)
355+
}
356+
352357
return nil
353358
}
354359

@@ -943,3 +948,32 @@ func (db *Database) DeleteDockerConfig(profileID string) error {
943948
}
944949
return nil
945950
}
951+
952+
// migrateAddVerboseLoggingColumn adds the verbose_logging column to the services table
953+
func (db *Database) migrateAddVerboseLoggingColumn() error {
954+
// Check if column already exists
955+
var columnExists bool
956+
var sql string
957+
err := db.QueryRow("SELECT sql FROM sqlite_master WHERE type='table' AND name='services'").Scan(&sql)
958+
if err != nil {
959+
return fmt.Errorf("failed to query services table schema: %w", err)
960+
}
961+
962+
columnExists = strings.Contains(sql, "verbose_logging")
963+
964+
if columnExists {
965+
log.Println("[INFO] Column 'verbose_logging' already exists in services table")
966+
return nil
967+
}
968+
969+
log.Println("[INFO] Adding 'verbose_logging' column to services table")
970+
971+
// Add the column with default value of FALSE
972+
_, err = db.Exec(`ALTER TABLE services ADD COLUMN verbose_logging BOOLEAN DEFAULT FALSE`)
973+
if err != nil {
974+
return fmt.Errorf("failed to add verbose_logging column: %w", err)
975+
}
976+
977+
log.Println("[INFO] Successfully added 'verbose_logging' column to services table")
978+
return nil
979+
}

internal/models/service.go

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,35 @@ import (
88
)
99

1010
type Service struct {
11-
ID string `json:"id"` // UUID - unique identifier for the service
12-
Name string `json:"name"`
13-
Dir string `json:"dir"`
14-
ExtraEnv string `json:"extraEnv"`
15-
JavaOpts string `json:"javaOpts"`
16-
Status string `json:"status"`
17-
HealthStatus string `json:"healthStatus"`
18-
HealthURL string `json:"healthUrl"`
19-
Port int `json:"port"`
20-
PID int `json:"pid"`
21-
Order int `json:"order"`
22-
LastStarted time.Time `json:"lastStarted"`
23-
Uptime string `json:"uptime"`
24-
Description string `json:"description"`
25-
IsEnabled bool `json:"isEnabled"`
26-
BuildSystem string `json:"buildSystem"` // "maven", "gradle", or "auto"
27-
EnvVars map[string]EnvVar `json:"envVars"`
28-
Cmd *exec.Cmd `json:"-"`
29-
Logs []LogEntry `json:"logs"`
30-
Mutex sync.RWMutex `json:"-"`
31-
CPUPercent float64 `json:"cpuPercent"`
32-
MemoryUsage uint64 `json:"memoryUsage"` // in bytes
33-
MemoryPercent float32 `json:"memoryPercent"`
34-
DiskUsage uint64 `json:"diskUsage"` // in bytes
35-
NetworkRx uint64 `json:"networkRx"` // bytes received
36-
NetworkTx uint64 `json:"networkTx"` // bytes transmitted
37-
Metrics ServiceMetrics `json:"metrics"`
38-
Dependencies []ServiceDependency `json:"dependencies"`
39-
DependentOn []string `json:"dependentOn"` // Services that depend on this one
40-
StartupDelay time.Duration `json:"startupDelay"` // Delay before starting after dependencies
11+
ID string `json:"id"` // UUID - unique identifier for the service
12+
Name string `json:"name"`
13+
Dir string `json:"dir"`
14+
ExtraEnv string `json:"extraEnv"`
15+
JavaOpts string `json:"javaOpts"`
16+
Status string `json:"status"`
17+
HealthStatus string `json:"healthStatus"`
18+
HealthURL string `json:"healthUrl"`
19+
Port int `json:"port"`
20+
PID int `json:"pid"`
21+
Order int `json:"order"`
22+
LastStarted time.Time `json:"lastStarted"`
23+
Uptime string `json:"uptime"`
24+
Description string `json:"description"`
25+
IsEnabled bool `json:"isEnabled"`
26+
BuildSystem string `json:"buildSystem"` // "maven", "gradle", or "auto"
27+
VerboseLogging bool `json:"verboseLogging"` // Enable verbose/debug logging for build tools
28+
EnvVars map[string]EnvVar `json:"envVars"`
29+
Cmd *exec.Cmd `json:"-"`
30+
Logs []LogEntry `json:"logs"`
31+
Mutex sync.RWMutex `json:"-"`
32+
CPUPercent float64 `json:"cpuPercent"`
33+
MemoryUsage uint64 `json:"memoryUsage"` // in bytes
34+
MemoryPercent float32 `json:"memoryPercent"`
35+
DiskUsage uint64 `json:"diskUsage"` // in bytes
36+
NetworkRx uint64 `json:"networkRx"` // bytes received
37+
NetworkTx uint64 `json:"networkTx"` // bytes transmitted
38+
Metrics ServiceMetrics `json:"metrics"`
39+
Dependencies []ServiceDependency `json:"dependencies"`
40+
DependentOn []string `json:"dependentOn"` // Services that depend on this one
41+
StartupDelay time.Duration `json:"startupDelay"` // Delay before starting after dependencies
4142
}

internal/services/buildsystem.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func HasGradleWrapper(serviceDir string) bool {
107107
}
108108

109109
// GetStartCommand returns the appropriate start command for the service
110-
func GetStartCommand(serviceDir, buildSystem string, javaOpts string, extraEnv string) (string, error) {
110+
func GetStartCommand(serviceDir, buildSystem string, javaOpts string, extraEnv string, verboseLogging bool) (string, error) {
111111
effectiveBuildSystem := GetEffectiveBuildSystem(serviceDir, buildSystem)
112112
commands := GetBuildSystemCommands(effectiveBuildSystem)
113113

@@ -124,6 +124,17 @@ func GetStartCommand(serviceDir, buildSystem string, javaOpts string, extraEnv s
124124
baseCommand = commands.Start
125125
}
126126

127+
// Add verbose/debug logging flags if enabled
128+
if verboseLogging {
129+
if effectiveBuildSystem == BuildSystemMaven {
130+
// Maven: use -X for debug output
131+
baseCommand = strings.Replace(baseCommand, "spring-boot:run", "spring-boot:run -X", 1)
132+
} else if effectiveBuildSystem == BuildSystemGradle {
133+
// Gradle: use -i for info level logging
134+
baseCommand = strings.Replace(baseCommand, "bootRun", "bootRun -i", 1)
135+
}
136+
}
137+
127138
// Construct the full command with directory change and environment
128139
var fullCommand string
129140
if extraEnv != "" {

internal/services/database.go

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,29 +46,31 @@ func (sm *Manager) loadServices(config models.Config) error {
4646
// Try to load existing service from database
4747
var dbService models.Service
4848
row := sm.db.QueryRow(`
49-
SELECT id, name, dir, extra_env, java_opts, status, health_status, health_url, port, pid, service_order, last_started, description, is_enabled, build_system
49+
SELECT id, name, dir, extra_env, java_opts, status, health_status, health_url, port, pid, service_order, last_started, description, is_enabled, build_system, verbose_logging
5050
FROM services WHERE id = ?`, service.ID)
5151

5252
var description sql.NullString
5353
var isEnabled sql.NullBool
5454
var buildSystem sql.NullString
55+
var verboseLogging sql.NullBool
5556
err := row.Scan(&dbService.ID, &dbService.Name, &dbService.Dir, &dbService.ExtraEnv, &dbService.JavaOpts,
5657
&dbService.Status, &dbService.HealthStatus, &dbService.HealthURL, &dbService.Port,
57-
&dbService.PID, &dbService.Order, &dbService.LastStarted, &description, &isEnabled, &buildSystem)
58+
&dbService.PID, &dbService.Order, &dbService.LastStarted, &description, &isEnabled, &buildSystem, &verboseLogging)
5859

5960
if err == sql.ErrNoRows {
6061
// Service doesn't exist in DB, insert it
6162
_, err = sm.db.Exec(`
62-
INSERT INTO services (id, name, dir, extra_env, java_opts, status, health_status, health_url, port, service_order, description, is_enabled, build_system, created_at, updated_at)
63-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`,
63+
INSERT INTO services (id, name, dir, extra_env, java_opts, status, health_status, health_url, port, service_order, description, is_enabled, build_system, verbose_logging, created_at, updated_at)
64+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`,
6465
service.ID, service.Name, service.Dir, service.ExtraEnv, service.JavaOpts, service.Status,
65-
service.HealthStatus, service.HealthURL, service.Port, service.Order, "", true, "auto")
66+
service.HealthStatus, service.HealthURL, service.Port, service.Order, "", true, "auto", false)
6667
if err != nil {
6768
return fmt.Errorf("failed to insert service UUID %s: %w", service.ID, err)
6869
}
6970
service.EnvVars = make(map[string]models.EnvVar)
7071
service.Logs = []models.LogEntry{}
7172
service.BuildSystem = "auto"
73+
service.VerboseLogging = false
7274
sm.services[service.ID] = service
7375
} else if err != nil {
7476
return fmt.Errorf("failed to query service UUID %s: %w", service.ID, err)
@@ -106,6 +108,11 @@ func (sm *Manager) loadServices(config models.Config) error {
106108
} else {
107109
dbService.BuildSystem = "auto"
108110
}
111+
if verboseLogging.Valid {
112+
dbService.VerboseLogging = verboseLogging.Bool
113+
} else {
114+
dbService.VerboseLogging = false
115+
}
109116

110117
// Load environment variables for this service
111118
dbService.EnvVars = make(map[string]models.EnvVar)
@@ -368,11 +375,11 @@ func (sm *Manager) loadDynamicServices() error {
368375

369376
func (sm *Manager) insertServiceInDB(service *models.Service) error {
370377
_, err := sm.db.Exec(`
371-
INSERT INTO services (id, name, dir, extra_env, java_opts, status, health_status, health_url, port, service_order, description, is_enabled, build_system, created_at, updated_at)
372-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`,
378+
INSERT INTO services (id, name, dir, extra_env, java_opts, status, health_status, health_url, port, service_order, description, is_enabled, build_system, verbose_logging, created_at, updated_at)
379+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`,
373380
service.ID, service.Name, service.Dir, service.ExtraEnv, service.JavaOpts, service.Status,
374381
service.HealthStatus, service.HealthURL, service.Port, service.Order,
375-
service.Description, service.IsEnabled, service.BuildSystem)
382+
service.Description, service.IsEnabled, service.BuildSystem, service.VerboseLogging)
376383

377384
return err
378385
}
@@ -418,12 +425,12 @@ func (sm *Manager) UpdateServiceInDB(service *models.Service) error {
418425

419426
func (sm *Manager) UpdateServiceConfigInDB(service *models.Service) error {
420427
_, err := sm.db.Exec(`
421-
UPDATE services
422-
SET name = ?, java_opts = ?, health_url = ?, port = ?, service_order = ?, description = ?,
423-
is_enabled = ?, build_system = ?, updated_at = CURRENT_TIMESTAMP
428+
UPDATE services
429+
SET name = ?, java_opts = ?, health_url = ?, port = ?, service_order = ?, description = ?,
430+
is_enabled = ?, build_system = ?, verbose_logging = ?, updated_at = CURRENT_TIMESTAMP
424431
WHERE id = ?`,
425432
service.Name, service.JavaOpts, service.HealthURL, service.Port, service.Order,
426-
service.Description, service.IsEnabled, service.BuildSystem, service.ID)
433+
service.Description, service.IsEnabled, service.BuildSystem, service.VerboseLogging, service.ID)
427434

428435
return err
429436
}

internal/services/java_env.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@ func DetectJavaEnvironment() *JavaEnvironment {
2727

2828
// Method 1: Check JAVA_HOME environment variable
2929
if javaHome := os.Getenv("JAVA_HOME"); javaHome != "" {
30+
// Check if JAVA_HOME points to asdf shims directory and resolve it
31+
if strings.Contains(javaHome, "/.asdf/shims") {
32+
log.Printf("[DEBUG] JAVA_HOME points to asdf shims, attempting to resolve: %s", javaHome)
33+
// Try to resolve using asdf
34+
cmd := exec.Command("asdf", "which", "java")
35+
if output, err := cmd.Output(); err == nil && len(output) > 0 {
36+
realJavaPath := strings.TrimSpace(string(output))
37+
javaHome = inferJavaHome(realJavaPath)
38+
log.Printf("[DEBUG] Resolved JAVA_HOME from asdf to: %s", javaHome)
39+
}
40+
}
41+
3042
javaPath := filepath.Join(javaHome, "bin", getJavaExecutable())
3143
if isExecutable(javaPath) && isWorkingJava(javaPath) {
3244
env.JavaHome = javaHome
@@ -198,7 +210,40 @@ func isWorkingJava(javaPath string) bool {
198210
}
199211

200212
func inferJavaHome(javaPath string) string {
201-
// Remove /bin/java to get JAVA_HOME
213+
// Check if this is an asdf shim and resolve it to the real Java path
214+
if strings.Contains(javaPath, "/.asdf/shims/") {
215+
log.Printf("[DEBUG] Detected asdf shim, attempting to resolve actual Java path: %s", javaPath)
216+
217+
// Try to use 'asdf which java' to get the real path
218+
cmd := exec.Command("asdf", "which", "java")
219+
if output, err := cmd.Output(); err == nil && len(output) > 0 {
220+
realJavaPath := strings.TrimSpace(string(output))
221+
log.Printf("[DEBUG] Resolved asdf shim to: %s", realJavaPath)
222+
// Use the real Java path for inference
223+
binDir := filepath.Dir(realJavaPath)
224+
if filepath.Base(binDir) == "bin" {
225+
resolvedHome := filepath.Dir(binDir)
226+
log.Printf("[DEBUG] Inferred JAVA_HOME from resolved path: %s", resolvedHome)
227+
return resolvedHome
228+
}
229+
} else {
230+
log.Printf("[WARN] Failed to resolve asdf shim: %v", err)
231+
}
232+
}
233+
234+
// Check if this is an SDKMAN installation and use the current symlink
235+
if strings.Contains(javaPath, "/.sdkman/candidates/java/") && strings.Contains(javaPath, "/current/") {
236+
log.Printf("[DEBUG] Detected SDKMAN Java installation: %s", javaPath)
237+
// For SDKMAN, we can use the path as-is since 'current' is already resolved
238+
binDir := filepath.Dir(javaPath)
239+
if filepath.Base(binDir) == "bin" {
240+
resolvedHome := filepath.Dir(binDir)
241+
log.Printf("[DEBUG] Using SDKMAN Java home: %s", resolvedHome)
242+
return resolvedHome
243+
}
244+
}
245+
246+
// Standard inference: Remove /bin/java to get JAVA_HOME
202247
binDir := filepath.Dir(javaPath)
203248
if filepath.Base(binDir) == "bin" {
204249
return filepath.Dir(binDir)

0 commit comments

Comments
 (0)