Skip to content

Add CLI flags to configure.sh for non-interactive usage#25

Merged
Joannis merged 1 commit intohummingbird-project:mainfrom
argylebits:feature/non-interactive-flags
Mar 14, 2026
Merged

Add CLI flags to configure.sh for non-interactive usage#25
Joannis merged 1 commit intohummingbird-project:mainfrom
argylebits:feature/non-interactive-flags

Conversation

@schultzjim
Copy link
Copy Markdown
Contributor

@schultzjim schultzjim commented Mar 9, 2026

Summary

Adds CLI flags to configure.sh so it can be driven non-interactively:

  • --package-name <name> — set the package name
  • --executable-name <name> — set the executable name
  • --lambda — enable Lambda support
  • --openapi — enable OpenAPI generator
  • --vscode-snippets — enable VS Code snippets
  • --defaults — use default values for any option not explicitly set by a flag
  • --help — display usage information and exit

Behavior

  • No flags: fully interactive, backwards-compatible (unchanged)
  • Flags without --defaults: flagged options are pre-filled, unflagged options still prompt interactively
  • Flags with --defaults: flagged options are used, everything else defaults with no prompting
  • Unknown flags: produce an error

Examples

Fully non-interactive with all defaults:

./configure.sh ./my-project --defaults

Mix of flags and defaults:

./configure.sh ./my-project --defaults --openapi --package-name "MyAPI"

Pre-fill one option, prompt for the rest:

./configure.sh ./my-project --openapi

Motivation

Running configure.sh from automated tooling (e.g. Swift's Process) fails because there's no controlling terminal for interactive prompts. These flags allow non-interactive usage while preserving the existing interactive experience.

Test plan

  • 71 assertions across 20 test cases (bash + expect-based interactive tests)
  • CI workflow runs on push/PR changes to relevant files

Copy link
Copy Markdown
Member

@adam-fowler adam-fowler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this a test script is a great idea.

I'm not certain about going immediately to defaults for everything else when only one option is added, but am willing to be convinced because alternatives aren't great either. There is the alternative of adding a --defaults which would default everything that hasn't been given a value via options. That would allow writing of scripts that decide on some parameters ahead of time, but still allow user input for others.

Out of interest how much of this was written with Claude. We don't have an AI policy as of yet. There are issues with open source including AI generated code, as we can't copyright it. Not sure how much of an issue this is yet.

@schultzjim
Copy link
Copy Markdown
Contributor Author

I'm not certain about going immediately to defaults for everything else when only one option is added, but am willing to be convinced because alternatives aren't great either. There is the alternative of adding a --defaults which would default everything that hasn't been given a value via options. That would allow writing of scripts that decide on some parameters ahead of time, but still allow user input for others.

@adam-fowler yes this was tough and I wasn't sure the best balance for this. I kinda just took a stab at a sensible option here, but I'm definitely open to making changes if yall prefer something else. The basic behavior is that any flag that you include gets picked up and used, everything else without a flag, used the script default (same as hitting Enter on the keyboard) hopefully that makes sense. if no flags, its fully interactive.

Here are a few examples:

1. All flags specified

./configure.sh ./my-project \
    --package-name "MyApp" \
    --executable-name "Server" \
    --lambda \
    --openapi \
    --vscode-snippets
Option Value
Package name MyApp (from --package-name)
Executable name Server (from --executable-name)
Lambda yes (from --lambda)
OpenAPI yes (from --openapi)
VS Code snippets yes (from --vscode-snippets)
.
├── .dockerignore
├── .github
│   └── workflows
│       └── ci.yml
├── .gitignore
├── .vscode
│   └── hummingbird.code-snippets
├── Dockerfile
├── Package.swift              ← name: "MyApp"
├── README.md
├── Sources
│   ├── App
│   │   ├── APIImplementation.swift
│   │   ├── App.swift
│   │   ├── App+build.swift
│   │   └── OpenAPIRequestContextMiddleware.swift
│   └── AppAPI
│       ├── AppAPI.swift
│       ├── openapi-generator-config.yaml
│       └── openapi.yaml
└── Tests
    └── AppTests
        └── AppTests.swift

2. Only --package-name (everything else defaults to off)

./configure.sh ./my-project --package-name "MyApp"
Option Value
Package name MyApp (from --package-name)
Executable name App (default)
Lambda no (default)
OpenAPI no (default)
VS Code snippets no (default)
.
├── .dockerignore
├── .github
│   └── workflows
│       └── ci.yml
├── .gitignore
├── .vscode
├── Dockerfile
├── Package.swift              ← name: "MyApp"
├── README.md
├── Sources
│   └── App
│       ├── App.swift
│       └── App+build.swift
└── Tests
    └── AppTests
        └── AppTests.swift

3. Only --lambda (package name defaults to folder name)

./configure.sh ./lambda-only --lambda
Option Value
Package name lambda-only (default from folder name)
Executable name App (forced by lambda)
Lambda yes (from --lambda)
OpenAPI no (default)
VS Code snippets no (default)
.
├── .dockerignore
├── .github
│   └── workflows
│       └── ci.yml
├── .gitignore
├── .vscode
├── Dockerfile
├── Package.swift              ← name: "lambda-only", includes AWSLambda deps
├── README.md
├── Sources
│   └── App
│       ├── App.swift
│       └── App+build.swift
└── Tests
    └── AppTests
        └── AppTests.swift

4. --package-name + --openapi

./configure.sh ./my-project --package-name "CoolAPI" --openapi
Option Value
Package name CoolAPI (from --package-name)
Executable name App (default)
Lambda no (default)
OpenAPI yes (from --openapi)
VS Code snippets no (default)
.
├── .dockerignore
├── .github
│   └── workflows
│       └── ci.yml
├── .gitignore
├── .vscode
├── Dockerfile
├── Package.swift              ← name: "CoolAPI"
├── README.md
├── Sources
│   ├── App
│   │   ├── APIImplementation.swift
│   │   ├── App.swift
│   │   ├── App+build.swift
│   │   └── OpenAPIRequestContextMiddleware.swift
│   └── AppAPI
│       ├── AppAPI.swift
│       ├── openapi-generator-config.yaml
│       └── openapi.yaml
└── Tests
    └── AppTests
        └── AppTests.swift

Let me know if yall want me to include the supplementary --defaults I think this would force non-flagged fields to use defaults, but without --defaults the non-flagged fields would need user input?

@schultzjim
Copy link
Copy Markdown
Contributor Author

Out of interest how much of this was written with Claude. We don't have an AI policy as of yet. There are issues with open source including AI generated code, as we can't copyright it. Not sure how much of an issue this is yet.

yes I tried to be transparent about Claude usage by keeping the "Generated with Claude" thing. I can see what you mean. I have definitely leveraged claude with this. I guess it depends on definitions on all this. did claude do all of this on its own, absolutely not. did I do it all on my own, absolutely not. I would say I am definitely the mind behind the change and the reason for it, the motivation etc. I also came up with the solution/concept for how to solve the "I need a non-interactive way to use this script." But I did not personally write every line of code. I definitely reviewed it carefully and tried to make sure claude conformed to what I wanted it to write.

I'm not sure the right way to handle these dilemmas though. I probably wouldn't have submitted this PR without being able to leverage claude, but the opposite is true as well. I don't think claude would have done this on its own either.

@schultzjim
Copy link
Copy Markdown
Contributor Author

schultzjim commented Mar 10, 2026

if you are interested the motivation behind this is a little project I'm building for myself mostly to help me scaffold projects quickly and uniformly. Its very much a work in progress, lots to figure out still but its is working enough at this point for me to use it on my own projects:

https://github.com/argylebits/Kolache

I have it working off my fork of the template currently. I also still need to support all the hummingbird script field/flags, but I am able to scaffold a basic hummingbird project with it kolache init MyProject --hummingbird scaffolds a basic hummingbird project. combining flags creates a monorepo project structure.

kolache init Atlas --app --cli --hummingbird --package --git

All four sub-packages: Core, app, CLI, and server.

Atlas/
├── AtlasCore/            ← shared library
├── Atlas/                ← SwiftUI app (depends on Core)
├── AtlasCLI/             ← CLI tool (depends on Core)
├── AtlasHummingbird/     ← Hummingbird server (depends on Core)
├── README.md
├── .gitignore
└── .kolache.json

tons of stuff I still have to figure out. but I'm considering it a personal (scratch my own itch) project for now. but I thought the flags might enable some interesting interactions outside of what I'm doing.

@adam-fowler
Copy link
Copy Markdown
Member

Thanks for your considered response. I think a --defaults would be a good addition in the end as it provides more flexibility. Could you also add --help which provides details about all the options.

With those changes I'll be happy to merge.

@schultzjim
Copy link
Copy Markdown
Contributor Author

no problem, and thanks for the feedback and working with me on this. I'm happy to make those adjustments. it may be a day or 2, but I'll get back to you shortly on it.

@schultzjim
Copy link
Copy Markdown
Contributor Author

@adam-fowler do you have a preference on the Generated with claude line in the description? I can do whatever you want with that. keep it, leave it, change it...

Add --package-name, --executable-name, --lambda, --openapi, and
--vscode-snippets flags for scripted project configuration.

Add --defaults flag to use default values for any option not explicitly
set by a flag. Without --defaults, flags only pre-fill their specific
option while still prompting interactively for everything else.

Add --help flag to display usage information.

Add test suite with both non-interactive (bash) and interactive (expect)
tests, along with a CI workflow to run them.
@schultzjim schultzjim force-pushed the feature/non-interactive-flags branch from aa77629 to 8fe6148 Compare March 13, 2026 15:10
@schultzjim
Copy link
Copy Markdown
Contributor Author

@adam-fowler I've got the PR updated per your feedback and requests. please let me know if you'd like any other changes.

@adam-fowler
Copy link
Copy Markdown
Member

adam-fowler commented Mar 13, 2026

I think I'm good with everything. I'm away for a week so I'll get @Joannis to approve and merge.

Copy link
Copy Markdown
Member

@Joannis Joannis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work @schultzjim

@Joannis Joannis merged commit 5ded8e5 into hummingbird-project:main Mar 14, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants