Skip to content

feat(cli): define plugin objects and basic plugin listing ability#1

Closed
QMalcolm wants to merge 10 commits into
qmalcolm--feat-cli-scaffoldfrom
qmalcolm--feat-plugin-discovery
Closed

feat(cli): define plugin objects and basic plugin listing ability#1
QMalcolm wants to merge 10 commits into
qmalcolm--feat-cli-scaffoldfrom
qmalcolm--feat-plugin-discovery

Conversation

@QMalcolm

@QMalcolm QMalcolm commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Stacked on apache/ossie#4

Summary

Define the basic structure of a plugin (plugin.yaml). In addition, add ability to list installed plugins. Note, this does not add the ability to install plugins, their associated setup, or convert invocations. This is simply the initial "how should a plugin be defined and found when it exists".

Screen.Recording.2026-06-23.at.16.59.01.mov

Migrated from apache/ossie#154 following the project's move to the Apache Software Foundation. This PR targets a branch in my fork rather than apache/ossie:main because it stacks on #4 (apache/ossie#151) — will retarget to apache/ossie:main once that merges.

QMalcolm added 10 commits July 7, 2026 14:18
Downstream segments (convert, plugin list, plugin install) all need
a way to find and parse installed plugins. This adds the shared
foundation: a typed Plugin struct and a Discover() function that
scans ~/.ossie/plugins/ for valid plugin.yaml files.

Design decisions:
- internal/plugin accepts pluginsDir as a parameter rather than
  calling ossiedir.PluginDir() internally — keeps the package
  testable without env var manipulation
- plugin.yaml supports both ossie_* (preferred) and osi_* (deprecated
  fallback) key families to avoid breaking plugins written before the
  OSI → OSSIE rename; ossie_* wins when both are present
- Malformed plugin dirs emit a warning to an io.Writer and are
  skipped; only an unreadable plugins directory is a hard error,
  matching the behavior specified in the architecture doc
- Non-directory entries in the plugins dir are silently skipped
  (no warning); non-existent dir returns nil, nil

Caveats:
- Symlinked plugin directories are not yet handled — os.ReadDir
  reports symlinks with ModeSymlink, not IsDir(); a TODO comment
  marks the location for a future follow-up
- cmd/plugin/list.go wiring is deferred to P1, which also requires
  the embedded registry before the full table output can be rendered
go.mod declares go 1.22 so slices.Equal (stdlib since 1.21) is
available. Removes the hand-rolled utility in favour of the standard
library equivalent.
os.IsNotExist does not handle wrapped errors correctly. Replace both
occurrences with errors.Is(err, os.ErrNotExist), the modern idiom
since Go 1.13.
Replace hardcoded /this/path/does/not/exist with a path derived from
t.TempDir(). The parent is guaranteed to exist by the test harness
but the child subdir does not, making the fixture deterministically
nonexistent without relying on filesystem assumptions.
Adds two cases: setup path is correctly parsed when present, and
setup is empty string when the field is absent from plugin.yaml.
The setup path is consumed by the install segment (P2) when running
the plugin's setup script.
Unknown fields in plugin.yaml are silently ignored by yaml.Unmarshal.
Adding a comment to make clear this is a deliberate forward-
compatibility choice, not an oversight.
…nd invoke args

ConvertConfig.ToOSI/FromOSI and the plugin.yaml fields to_osi/from_osi
were left using the old brand name. This sweeps them to ossie
consistently with the rest of the CLI rename.

to_ossie/from_ossie are now the canonical yaml keys. to_osi/from_osi
are kept as deprecated fallbacks in rawPlugin, using the same
ossie-wins merge pattern already established for
ossie_plugin_spec/osi_plugin_spec. The invoke-arg convention
(to-ossie, from-ossie) is updated in all canonical test fixtures; the
two backward-compat tests (TestDiscover_ossieKeyPreferred,
TestDiscover_osiKeyFallback) intentionally retain to_osi/from_osi
since they exercise the deprecated-key path.
The preemptive osi_* fallback fields (osi_plugin_spec, osi_spec_version,
to_osi, from_osi) were added in anticipation of backward compatibility,
but no plugins exist yet using that format — the rename is happening
before any external consumers. Carrying dead compatibility code with no
real users adds noise and keeps osi in the codebase.

Drops all deprecated fields and merge logic from rawPlugin, simplifying
validate() and toPlugin() back to direct field access.
TestDiscover_ossieKeyPreferred and TestDiscover_osiKeyFallback (which
existed solely to exercise the now-removed paths) are replaced with
TestDiscover_unknownFieldsIgnored, which covers the lenient-YAML
behavior (future spec fields are silently tolerated) that discover.go
explicitly documents.
Wires plugin list to the discovery infrastructure added in F2. Reads
from the resolved plugin directory, prints a NAME/PLATFORM/SPEC table
via tabwriter, and falls back to a "no plugins installed" message when
the directory is empty or missing.

This is a minimal first pass — the full P1 spec calls for
cross-referencing against the embedded plugin registry (installed vs.
available, latest version, update indicator), which depends on registry
embedding (F4) not yet implemented.
go install . names the binary after the module path's last segment
(cli) rather than the intended ossie. make install uses go build -o
directly into $GOPATH/bin with the correct binary name.
@QMalcolm

QMalcolm commented Jul 8, 2026

Copy link
Copy Markdown
Owner Author

Superseded by apache/ossie#6 — converting the stack to draft PRs opened directly against apache/ossie:main instead of stacking within this fork, so each PR's diff shrinks in place as its parent merges rather than needing to be closed/reopened.

@QMalcolm QMalcolm closed this Jul 8, 2026
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.

1 participant