Skip to content

Implement spfx list-templates command#175

Merged
nick-pape merged 9 commits intoSharePoint:mainfrom
nick-pape:nick-pape/list-templates
Mar 24, 2026
Merged

Implement spfx list-templates command#175
nick-pape merged 9 commits intoSharePoint:mainfrom
nick-pape:nick-pape/list-templates

Conversation

@nick-pape
Copy link
Contributor

Description

Implements issue #89: adds a spfx list-templates command that fetches and displays available templates from configured sources.

Key design decision: unlike create (which uses an exclusive local-vs-github model), list-templates uses an additive model — the default GitHub source is always included, and --local-source / --remote-source add on top of it.

Changes

New files:

  • src/utilities/github.ts — shared DEFAULT_GITHUB_REPO, SPFX_TEMPLATE_REPO_URL_ENV_VAR_NAME, and parseGitHubUrlAndRef(), extracted from CreateAction so both actions can reuse them
  • src/cli/actions/ListTemplatesAction.ts — new action with --template-url, --spfx-version, --local-source, --remote-source
  • src/cli/actions/tests/ListTemplatesAction.test.ts — 18 tests (written TDD before the implementation)

Modified files:

  • CreateAction.ts — now imports shared values from utilities/github (no behavior change)
  • SPFxCommandLineParser.ts — registers ListTemplatesAction
  • CommandLineHelp.test.ts.snap — updated to include list-templates in help output
  • CLAUDE.md — documents the heft test --clean -u snapshot update command

How was this tested

  • rushx build — 54/54 tests pass (18 new ListTemplatesAction tests, 35 existing CreateAction tests, 1 CommandLineHelp snapshot test)
  • Tests were written before the implementation (TDD)

Type of change

  • New feature (non-breaking change which adds functionality)

Closes #89

🤖 Generated with Claude Code

Adds a new `list-templates` command that fetches and displays available
templates from configured sources. Unlike `create`, the source model is
additive — the default GitHub source is always included alongside any
`--local-source` or `--remote-source` flags.

Also extracts shared GitHub URL utilities (DEFAULT_GITHUB_REPO,
SPFX_TEMPLATE_REPO_URL_ENV_VAR_NAME, parseGitHubUrlAndRef) into
src/utilities/github.ts so both actions can reuse them.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 24, 2026 16:19
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new list-templates command to @microsoft/spfx-cli for enumerating available SPFx templates from the default GitHub repo plus any user-specified local/remote sources, and refactors shared GitHub URL parsing into a utility.

Changes:

  • Introduces spfx list-templates action with flags for default repo URL, SPFx branch/ref, and additive local/remote template sources.
  • Extracts GitHub repo defaults and /tree/<ref> parsing into src/utilities/github.ts and reuses it from CreateAction.
  • Adds Jest coverage + snapshots for the new command and updates CLI help snapshots and docs.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
common/changes/@microsoft/spfx-cli/list-templates_2026-03-24.json Rush change file for the feature work.
apps/spfx-cli/src/utilities/github.ts New shared GitHub constants + URL/ref parsing helper.
apps/spfx-cli/src/cli/actions/ListTemplatesAction.ts Implements the new list-templates command behavior and output.
apps/spfx-cli/src/cli/actions/tests/ListTemplatesAction.test.ts Unit tests for additive source selection, URL/ref parsing, and error handling.
apps/spfx-cli/src/cli/actions/tests/snapshots/ListTemplatesAction.test.ts.snap Snapshot outputs for list-templates tests.
apps/spfx-cli/src/cli/actions/CreateAction.ts Refactors to use shared GitHub utilities (no intended behavior change).
apps/spfx-cli/src/cli/actions/tests/CreateAction.test.ts Updates tests to import shared env var name constant.
apps/spfx-cli/src/cli/SPFxCommandLineParser.ts Registers the new action with the CLI parser.
apps/spfx-cli/src/cli/test/snapshots/CommandLineHelp.test.ts.snap Updates help snapshots to include list-templates.
apps/spfx-cli/README.md Documents spfx list-templates usage and flags for the published package.
CLAUDE.md Adds guidance for updating Jest snapshots with Heft.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Fix toolFilename: 'spfx-cli' → 'spfx' to match the published binary name
- Document slash-branch limitation in parseGitHubUrlAndRef (cannot express
  feature/foo via /tree/ URL; use --spfx-version instead)
- Use `terminal` alias consistently in ListTemplatesAction (not this._terminal)
- Remove unused SPFX_TEMPLATE_REPO_URL_ENV_VAR_NAME re-export from CreateAction
- Update help snapshots for toolFilename change

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@nick-pape
Copy link
Contributor Author

nick-pape commented Mar 24, 2026

Manual Test Results

Tested on commit e9788bf, Node.js 22.16.0, Linux (codespace).

Test plan

# Command Expected
1 spfx --help list-templates appears in command list
2 spfx list-templates --help All 4 flags shown with descriptions
3 spfx list-templates --local-source ./templates 18 templates listed from local dir
4 Two --local-source flags Both sources included additively (19 templates total)
5 SPFX_TEMPLATE_REPO_URL=.../tree/main spfx list-templates --local-source ... Branch extracted from /tree/ in env var
6 SPFX_TEMPLATE_REPO_URL=.../tree/pending-fixes + --spfx-version 1.22 Warning emitted; --spfx-version takes precedence
7 spfx list-templates (live GitHub fetch) 18 templates fetched from github.com/SharePoint/spfx
8 --local-source /nonexistent/path Error with path + actionable message

Results

✅ Test 1 — Global help
list-templates appears correctly alongside create. toolFilename now shows spfx (not spfx-cli).

✅ Test 2 — Command help
All 4 flags displayed: --template-url, --spfx-version, --local-source, --remote-source. SPFX_TEMPLATE_REPO_URL env var noted in --template-url description.

✅ Test 3 — Single local source
18 templates listed (17 real + 1 test template in the repo). Source log line Adding local template source: /workspaces/spfx/templates printed as expected.

✅ Test 4 — Additive sources (two --local-source flags)
Both source log lines printed. 19 templates shown (18 from first source + 1 fake-template from second). Confirms additive model works correctly.

✅ Test 5 — SPFX_TEMPLATE_REPO_URL with /tree/ notation
Using GitHub template source: https://github.com/SharePoint/spfx (branch: main) — branch correctly extracted from the /tree/main suffix.

✅ Test 6 — --spfx-version precedence warning
Warning shown: --template-url contains a branch ('/tree/pending-fixes\). --spfx-version "1.22" will take precedence. Correct branch passed to source. (Branch 1.22 does not exist, so fetch returned 404 — expected.)

✅ Test 7 — Live GitHub fetch
18 templates successfully fetched from the default SharePoint/spfx repo with no flags. All 17 templates present plus the in-repo test template (which the live repo's main branch includes).

✅ Test 8 — Error handling (nonexistent path)
Clear error: Failed to read templates from /nonexistent/path: Error: File does not exist. Non-zero exit code. The error message suggests --local-source as a workaround, which is slightly awkward when the user is already using it with a bad path — filed as #178.

Notes

  • --remote-source is covered by unit tests (18/18 pass) rather than a live test, since it requires a second public GitHub repo with the right structure.
  • The test template appearing in live output is a real template that exists in the SharePoint/spfx repo's main branch — not a test artifact from this PR.

Issues found during testing

- Add addDefaultGitHubSource() helper to utilities/github.ts, eliminating
  the duplicated GitHub source init block between CreateAction and ListTemplatesAction
- Add TEMPLATE_URL_DESCRIPTION and SPFX_VERSION_DESCRIPTION constants so
  both actions share identical flag descriptions from one source of truth
- Add utilities/tests/github.test.ts with 12 direct unit tests for
  parseGitHubUrlAndRef (plain URLs, .git stripping, /tree/ extraction, GHE, etc.)
- Remove now-unused PublicGitHubRepositorySource import from CreateAction

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 24, 2026 17:34
nick-pape and others added 2 commits March 24, 2026 12:44
Replace the placeholder '[Mocked SPFxTemplateCollection]' toString with
output that matches the real SPFxTemplateCollection/SPFxTemplate format,
so snapshot diffs are meaningful when template display changes.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Replace per-action inline defineStringParameter({...}) objects with
TEMPLATE_URL_PARAMETER_DEFINITION and SPFX_VERSION_PARAMETER_DEFINITION
constants in utilities/github.ts. Both CreateAction and ListTemplatesAction
now call defineStringParameter(TEMPLATE_URL_PARAMETER_DEFINITION) directly,
ensuring the flag names, argument names, descriptions, and env var binding
stay in sync automatically.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
nick-pape and others added 2 commits March 24, 2026 13:42
Main changed --spfx-version to resolve "1.22" to the "version/1.22" branch.
Updated addDefaultGitHubSource() to apply the same mapping so both
CreateAction and ListTemplatesAction get consistent behavior. Also updated
SPFX_VERSION_PARAMETER_DEFINITION description and ListTemplatesAction tests
to expect the new version/ prefixed branch names.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Extract a shared base class `SPFxAction` for `CreateAction` and
`ListTemplatesAction` that owns the common `--template-url` and
`--spfx-version` parameters and the GitHub source registration logic.

- Move `addDefaultGitHubSource` from `utilities/github.ts` into
  `SPFxAction._addGitHubTemplateSource()` (protected method)
- Remove exported `TEMPLATE_URL_PARAMETER_DEFINITION` and
  `SPFX_VERSION_PARAMETER_DEFINITION` constants (now defined in the
  base class)
- Add `protected override` to `onExecuteAsync` in both actions
- Use `parseGitHubUrlAndRef.name` instead of string literal in tests
- Update help snapshots for new parameter order

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@nick-pape nick-pape enabled auto-merge (squash) March 24, 2026 19:04
iclanton
iclanton previously approved these changes Mar 24, 2026
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@nick-pape nick-pape merged commit 5e545ab into SharePoint:main Mar 24, 2026
4 checks passed
nick-pape added a commit to nick-pape/spfx-2 that referenced this pull request Mar 24, 2026
The list-templates command (merged via PR SharePoint#175) had the same misleading
--local-source suggestion. Since list-templates uses an additive model
where GitHub is always included, the hint is removed entirely — the
Details suffix already identifies which source failed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
nick-pape added a commit to nick-pape/spfx-2 that referenced this pull request Mar 24, 2026
Main merged PR SharePoint#175 which extracted parseGitHubUrlAndRef to
utilities/github.ts and introduced SPFxActionBase. Re-added
PublicGitHubRepositorySource import and parseGitHubUrlAndRef import
needed by the --remote-source loop.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
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.

Implement list-templates CLI command

3 participants