From 15bb8ecbd8e6bdb6f5735990ebe6ddfd55900e69 Mon Sep 17 00:00:00 2001 From: manasa Date: Tue, 10 Mar 2026 16:11:10 +0530 Subject: [PATCH 1/2] Show additional mise.toml tools in output summary Signed-off-by: manasa --- core/core.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++ core/core_test.go | 7 +++++++ 2 files changed, 56 insertions(+) diff --git a/core/core.go b/core/core.go index c2ec2d655..4b0d48d5a 100644 --- a/core/core.go +++ b/core/core.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "slices" + "strings" "github.com/charmbracelet/log" "github.com/railwayapp/railpack/core/app" @@ -115,6 +116,19 @@ func GenerateBuildPlan(app *app.App, env *app.Environment, options *GenerateBuil return &BuildResult{Success: false, Logs: logger.Logs} } + misePackages, err := ctx.GetMiseStepBuilder().GetMisePackageVersions(ctx) + if err != nil { + logger.LogError("Failed to list additional tools from mise.toml: %s", err.Error()) + } else { + extraTools := getExtraMiseTomlTools(misePackages, resolvedPackages) + if len(extraTools) > 0 { + logger.LogInfo( + "Also installing additional tools from mise.toml: %s", + formatToolPreview(extraTools, 2), + ) + } + } + if providerToUse != nil { providerToUse.CleansePlan(buildPlan) } @@ -311,3 +325,38 @@ func getProviders(ctx *generate.GenerateContext, config *c.Config) (providers.Pr return providerToUse, detectedProvider } + +func getExtraMiseTomlTools( + misePackages map[string]*generate.MisePackageInfo, + resolvedPackages map[string]*resolver.ResolvedPackage, +) []string { + extra := []string{} + + for _, name := range slices.Sorted(maps.Keys(misePackages)) { + pkg := misePackages[name] + if pkg == nil || pkg.Source != "mise.toml" { + continue + } + if _, exists := resolvedPackages[name]; exists { + continue + } + extra = append(extra, name) + } + + return extra +} + +func formatToolPreview(tools []string, maxTools int) string { + if len(tools) == 0 { + return "" + } + + count := min(len(tools), maxTools) + preview := strings.Join(tools[:count], ", ") + + if len(tools) > maxTools { + return preview + ", etc." + } + + return preview +} diff --git a/core/core_test.go b/core/core_test.go index d5c73a32e..fe992447e 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -105,3 +105,10 @@ func TestGenerateBuildPlan_DockerignoreMetadata(t *testing.T) { require.NotNil(t, buildResult.Metadata) require.Equal(t, "true", buildResult.Metadata["dockerIgnore"]) } + +func TestFormatToolPreview(t *testing.T) { + require.Equal(t, "", formatToolPreview([]string{}, 3)) + require.Equal(t, "go, python", formatToolPreview([]string{"go", "python"}, 3)) + require.Equal(t, "go, jq, python", formatToolPreview([]string{"go", "jq", "python"}, 3)) + require.Equal(t, "go, jq, python, etc.", formatToolPreview([]string{"go", "jq", "python", "uv"}, 3)) +} From 3561c563c5a1f55700edbb61065ed0292cee9870 Mon Sep 17 00:00:00 2001 From: manasa Date: Wed, 11 Mar 2026 00:41:41 +0530 Subject: [PATCH 2/2] refactor: address #419 review feedback for mise package output Signed-off-by: manasa --- core/core.go | 64 +++++++++++++++--------------- core/core_test.go | 44 +++++++++++++++++--- core/generate/mise_step_builder.go | 26 ++++++++++-- 3 files changed, 92 insertions(+), 42 deletions(-) diff --git a/core/core.go b/core/core.go index 4b0d48d5a..5556dc0b9 100644 --- a/core/core.go +++ b/core/core.go @@ -7,7 +7,6 @@ import ( "os" "path/filepath" "slices" - "strings" "github.com/charmbracelet/log" "github.com/railwayapp/railpack/core/app" @@ -116,17 +115,8 @@ func GenerateBuildPlan(app *app.App, env *app.Environment, options *GenerateBuil return &BuildResult{Success: false, Logs: logger.Logs} } - misePackages, err := ctx.GetMiseStepBuilder().GetMisePackageVersions(ctx) - if err != nil { - logger.LogError("Failed to list additional tools from mise.toml: %s", err.Error()) - } else { - extraTools := getExtraMiseTomlTools(misePackages, resolvedPackages) - if len(extraTools) > 0 { - logger.LogInfo( - "Also installing additional tools from mise.toml: %s", - formatToolPreview(extraTools, 2), - ) - } + if err := addAdditionalMiseToolsToPackages(ctx, ctx.GetMiseStepBuilder(), resolvedPackages); err != nil { + logger.LogWarn("Failed to include additional tools from mise.toml in package output: %s", err.Error()) } if providerToUse != nil { @@ -326,12 +316,26 @@ func getProviders(ctx *generate.GenerateContext, config *c.Config) (providers.Pr return providerToUse, detectedProvider } -func getExtraMiseTomlTools( - misePackages map[string]*generate.MisePackageInfo, +// Adds app-local mise.toml tools to the package output table. +func addAdditionalMiseToolsToPackages( + ctx *generate.GenerateContext, + miseStep *generate.MiseStepBuilder, resolvedPackages map[string]*resolver.ResolvedPackage, -) []string { - extra := []string{} +) error { + misePackages, err := miseStep.GetMisePackageVersionsCached(ctx) + if err != nil { + return err + } + addAdditionalMiseToolsFromPackages(misePackages, resolvedPackages) + return nil +} + +// Merges non-provider mise.toml tools into resolved package rows. +func addAdditionalMiseToolsFromPackages( + misePackages map[string]*generate.MisePackageInfo, + resolvedPackages map[string]*resolver.ResolvedPackage, +) { for _, name := range slices.Sorted(maps.Keys(misePackages)) { pkg := misePackages[name] if pkg == nil || pkg.Source != "mise.toml" { @@ -340,23 +344,17 @@ func getExtraMiseTomlTools( if _, exists := resolvedPackages[name]; exists { continue } - extra = append(extra, name) - } - - return extra -} - -func formatToolPreview(tools []string, maxTools int) string { - if len(tools) == 0 { - return "" - } - - count := min(len(tools), maxTools) - preview := strings.Join(tools[:count], ", ") - if len(tools) > maxTools { - return preview + ", etc." + version := pkg.Version + var requestedVersion *string + if pkg.RequestedVersion != "" { + requestedVersion = &pkg.RequestedVersion + } + resolvedPackages[name] = &resolver.ResolvedPackage{ + Name: name, + RequestedVersion: requestedVersion, + ResolvedVersion: &version, + Source: "mise.toml", + } } - - return preview } diff --git a/core/core_test.go b/core/core_test.go index fe992447e..cd3217b8f 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -7,7 +7,9 @@ import ( "github.com/gkampitakis/go-snaps/snaps" "github.com/railwayapp/railpack/core/app" + "github.com/railwayapp/railpack/core/generate" "github.com/railwayapp/railpack/core/logger" + "github.com/railwayapp/railpack/core/resolver" "github.com/stretchr/testify/require" ) @@ -106,9 +108,41 @@ func TestGenerateBuildPlan_DockerignoreMetadata(t *testing.T) { require.Equal(t, "true", buildResult.Metadata["dockerIgnore"]) } -func TestFormatToolPreview(t *testing.T) { - require.Equal(t, "", formatToolPreview([]string{}, 3)) - require.Equal(t, "go, python", formatToolPreview([]string{"go", "python"}, 3)) - require.Equal(t, "go, jq, python", formatToolPreview([]string{"go", "jq", "python"}, 3)) - require.Equal(t, "go, jq, python, etc.", formatToolPreview([]string{"go", "jq", "python", "uv"}, 3)) +func TestAddAdditionalMiseToolsToPackages(t *testing.T) { + nodeVersion := "24.0.0" + bunVersion := "1.3.10" + + // Simulate what provider already resolved (node + bun already in table) + resolvedPackages := map[string]*resolver.ResolvedPackage{ + "node": {Name: "node", ResolvedVersion: &nodeVersion, Source: "mise.toml"}, + "bun": {Name: "bun", ResolvedVersion: &bunVersion, Source: "mise.toml"}, + } + + // Simulate what mise returns from app mise.toml + misePackages := map[string]*generate.MisePackageInfo{ + "node": {Version: "24.0.0", RequestedVersion: "24", Source: "mise.toml"}, + "bun": {Version: "1.3.10", RequestedVersion: "latest", Source: "mise.toml"}, + "python": {Version: "3.13.0", RequestedVersion: "3.13", Source: "mise.toml"}, + "go": {Version: "1.23.0", RequestedVersion: "1.23", Source: "mise.toml"}, + } + + addAdditionalMiseToolsFromPackages(misePackages, resolvedPackages) + + // node and bun should remain unchanged + require.Equal(t, "mise.toml", resolvedPackages["node"].Source) + require.Equal(t, "mise.toml", resolvedPackages["bun"].Source) + + // python and go should be added with requested versions from app mise.toml + require.Contains(t, resolvedPackages, "python") + require.Equal(t, "mise.toml", resolvedPackages["python"].Source) + require.Equal(t, "3.13.0", *resolvedPackages["python"].ResolvedVersion) + require.Equal(t, "3.13", *resolvedPackages["python"].RequestedVersion) + + require.Contains(t, resolvedPackages, "go") + require.Equal(t, "mise.toml", resolvedPackages["go"].Source) + require.Equal(t, "1.23.0", *resolvedPackages["go"].ResolvedVersion) + require.Equal(t, "1.23", *resolvedPackages["go"].RequestedVersion) + + // total should now be 4 + require.Len(t, resolvedPackages, 4) } diff --git a/core/generate/mise_step_builder.go b/core/generate/mise_step_builder.go index 46ed57887..84cf6f65f 100644 --- a/core/generate/mise_step_builder.go +++ b/core/generate/mise_step_builder.go @@ -26,8 +26,9 @@ var ( // represents a app-local mise package type MisePackageInfo struct { - Version string - Source string + Version string + RequestedVersion string + Source string } // MiseListSource represents the source of a mise tool installation @@ -61,6 +62,7 @@ type MiseStepBuilder struct { Variables map[string]string app *a.App env *a.Environment + cachedMisePackages map[string]*MisePackageInfo } func (c *GenerateContext) NewMiseStepBuilder(displayName string) *MiseStepBuilder { @@ -161,7 +163,8 @@ func (b *MiseStepBuilder) GetMisePackageVersions(ctx *GenerateContext) (map[stri if len(appDirTools) > 0 { firstTool := appDirTools[0] packages[toolName] = &MisePackageInfo{ - Version: firstTool.Version, + Version: firstTool.Version, + RequestedVersion: firstTool.RequestedVersion, // include the source so we can surface this to the user so they understand where the package version came from Source: firstTool.Source.Type, } @@ -171,9 +174,24 @@ func (b *MiseStepBuilder) GetMisePackageVersions(ctx *GenerateContext) (map[stri return packages, nil } +// Reuses the mise package list to avoid duplicate mise invocations. +func (b *MiseStepBuilder) GetMisePackageVersionsCached(ctx *GenerateContext) (map[string]*MisePackageInfo, error) { + if b.cachedMisePackages != nil { + return b.cachedMisePackages, nil + } + + misePackages, err := b.GetMisePackageVersions(ctx) + if err != nil { + return nil, err + } + + b.cachedMisePackages = misePackages + return misePackages, nil +} + // Use mise-specified versions for all packages in the input list func (b *MiseStepBuilder) UseMiseVersions(ctx *GenerateContext, packages []string) { - miseVersions, err := b.GetMisePackageVersions(ctx) + miseVersions, err := b.GetMisePackageVersionsCached(ctx) if err != nil { ctx.Logger.LogWarn("Failed to get package versions from mise: %s", err.Error()) return