Skip to content

Commit f54d331

Browse files
committed
apps init: show template ref in header and clone spinner
Drops the standalone "Using AppKit template version X" line. The resolved ref (e.g. "version 0.24.0" or "branch feature-x") now appears on the interactive header before the name prompt and as a suffix on the clone spinner so the user can cancel before naming the project.
1 parent a2f03c5 commit f54d331

2 files changed

Lines changed: 39 additions & 14 deletions

File tree

cmd/apps/init.go

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ func cloneRepo(ctx context.Context, repoURL, branch string) (string, error) {
548548
// Used by commands that don't benefit from background cloning (e.g., manifest).
549549
func resolveTemplate(ctx context.Context, templatePath, branch, subdir string) (string, func(), error) {
550550
ch := resolveTemplateAsync(ctx, templatePath, branch, subdir)
551-
return awaitTemplate(ctx, ch)
551+
return awaitTemplate(ctx, ch, "")
552552
}
553553

554554
// templateResult holds the outcome of a background template resolution.
@@ -599,18 +599,24 @@ func resolveTemplateAsync(ctx context.Context, templatePath, branch, subdir stri
599599
// awaitTemplate waits for the background clone to finish.
600600
// If the result is already available it returns immediately with a
601601
// checkmark; otherwise it shows a spinner while waiting.
602-
func awaitTemplate(ctx context.Context, ch <-chan templateResult) (string, func(), error) {
602+
// refLabel, if non-empty (e.g. "version 0.24.0" or "branch feature-x"),
603+
// is appended to spinner and done messages.
604+
func awaitTemplate(ctx context.Context, ch <-chan templateResult, refLabel string) (string, func(), error) {
605+
suffix := ""
606+
if refLabel != "" {
607+
suffix = " (" + refLabel + ")"
608+
}
603609
select {
604610
case res := <-ch:
605611
// Clone finished while the user was typing — print completion.
606612
if res.err == nil && res.cleanup != nil {
607-
prompt.PrintDone(ctx, "Template cloned")
613+
prompt.PrintDone(ctx, "Template cloned"+suffix)
608614
}
609615
return res.path, res.cleanup, res.err
610616
default:
611617
// Still cloning — show a spinner for the remaining wait.
612618
var res templateResult
613-
err := prompt.RunWithSpinnerCtx(ctx, "Cloning template...", func() error {
619+
err := prompt.RunWithSpinnerCtx(ctx, "Cloning template"+suffix+"...", func() error {
614620
res = <-ch
615621
return res.err
616622
})
@@ -794,25 +800,36 @@ func runCreate(ctx context.Context, opts createOptions) error {
794800
templateSrc = env.Get(ctx, templatePathEnvVar)
795801
}
796802

797-
// Resolve the git reference (branch/tag) to use for default appkit template
803+
// Resolve the git reference (branch/tag) to use for default appkit template.
804+
// refLabel is a human-readable description of the ref we're cloning
805+
// (e.g. "version 0.24.0", "branch feature-x"). It's surfaced in the
806+
// interactive header and the clone spinner so the user can cancel before
807+
// naming the project. Empty when there's nothing meaningful to show
808+
// (e.g. a custom --template URL with no explicit branch).
798809
gitRef := opts.branch
810+
var refLabel string
799811
usingDefaultTemplate := templateSrc == ""
800812
if usingDefaultTemplate {
801813
// Using default appkit template - resolve version
802814
switch {
803815
case opts.branch != "":
804816
// --branch takes precedence (already set in gitRef)
817+
refLabel = "branch " + opts.branch
805818
case opts.version != "":
806819
gitRef = normalizeVersion(opts.version)
820+
refLabel = "version " + opts.version
807821
default:
808-
appkitVersion, err := clicompat.ResolveAppKitVersion(ctx)
822+
resolved, err := clicompat.ResolveAppKitVersion(ctx)
809823
if err != nil {
810824
return fmt.Errorf("could not resolve AppKit template version: %w; use --version to specify a version manually", err)
811825
}
812-
gitRef = normalizeVersion(appkitVersion)
813-
cmdio.LogString(ctx, "Using AppKit template version "+appkitVersion)
826+
gitRef = normalizeVersion(resolved)
827+
refLabel = "version " + resolved
814828
}
815829
templateSrc = appkitRepoURL
830+
} else if opts.branch != "" {
831+
// Custom template with an explicit branch — show it for traceability.
832+
refLabel = "branch " + opts.branch
816833
}
817834

818835
// Start cloning in the background so it runs while the user types the name.
@@ -843,7 +860,7 @@ func runCreate(ctx context.Context, opts createOptions) error {
843860
if !isInteractive {
844861
return errors.New("--name is required in non-interactive mode")
845862
}
846-
name, err := prompt.PromptForProjectName(ctx, opts.outputDir)
863+
name, err := prompt.PromptForProjectName(ctx, opts.outputDir, refLabel)
847864
if err != nil {
848865
return err
849866
}
@@ -862,7 +879,7 @@ func runCreate(ctx context.Context, opts createOptions) error {
862879
}
863880

864881
// Step 2: Wait for template (may already be done if the user took time typing the name)
865-
resolvedPath, cleanup, err := awaitTemplate(ctx, templateCh)
882+
resolvedPath, cleanup, err := awaitTemplate(ctx, templateCh, refLabel)
866883
// Only fall back to the embedded version when the version was auto-resolved
867884
// from the manifest, not when the user explicitly passed --version or --branch.
868885
versionAutoResolved := opts.version == "" && opts.branch == ""
@@ -872,7 +889,8 @@ func runCreate(ctx context.Context, opts createOptions) error {
872889
log.Warnf(ctx, "Template version not found, falling back to embedded version %s", fallbackVersion)
873890
fallbackRef := normalizeVersion(fallbackVersion)
874891
templateCh = resolveTemplateAsync(ctx, templateSrc, fallbackRef, appkitTemplateDir)
875-
resolvedPath, cleanup, err = awaitTemplate(ctx, templateCh)
892+
refLabel = "version " + fallbackVersion
893+
resolvedPath, cleanup, err = awaitTemplate(ctx, templateCh, refLabel)
876894
} else if fbErr != nil {
877895
log.Warnf(ctx, "Could not resolve embedded AppKit version: %v", fbErr)
878896
}

libs/apps/prompt/prompt.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,10 @@ func ValidateProjectName(s string) error {
155155
}
156156

157157
// PrintHeader prints the AppKit header banner.
158-
func PrintHeader(ctx context.Context) {
158+
// If refLabel is non-empty (e.g. "version 0.24.0" or "branch feature-x"),
159+
// an extra dimmed line shows the resolved template ref so the user can
160+
// decide whether to continue before naming the project.
161+
func PrintHeader(ctx context.Context, refLabel string) {
159162
headerStyle := lipgloss.NewStyle().
160163
Foreground(colorRed).
161164
Bold(true)
@@ -166,14 +169,18 @@ func PrintHeader(ctx context.Context) {
166169
cmdio.LogString(ctx, "")
167170
cmdio.LogString(ctx, headerStyle.Render("◆ Create a new Databricks AppKit project"))
168171
cmdio.LogString(ctx, subtitleStyle.Render(" Full-stack TypeScript • React • Tailwind CSS"))
172+
if refLabel != "" {
173+
cmdio.LogString(ctx, subtitleStyle.Render(" Template "+refLabel))
174+
}
169175
cmdio.LogString(ctx, "")
170176
}
171177

172178
// PromptForProjectName prompts only for project name.
173179
// Used as the first step before resolving templates.
174180
// outputDir is used to check if the destination directory already exists.
175-
func PromptForProjectName(ctx context.Context, outputDir string) (string, error) {
176-
PrintHeader(ctx)
181+
// refLabel, if non-empty, is shown in the header so the user can cancel before naming.
182+
func PromptForProjectName(ctx context.Context, outputDir, refLabel string) (string, error) {
183+
PrintHeader(ctx, refLabel)
177184
theme := AppkitTheme()
178185

179186
var name string

0 commit comments

Comments
 (0)