@@ -2,8 +2,10 @@ package cli
22
33import (
44 "fmt"
5+ "os"
56 "path/filepath"
67 "slices"
8+ "strings"
79
810 "github.com/project-chip/alchemy/cmd/common"
911 "github.com/project-chip/alchemy/internal/files"
@@ -16,8 +18,9 @@ import (
1618)
1719
1820type ZAP struct {
19- ZAPXML ZAPXML `cmd:"" name:"xml" default:"withargs"`
20- ZAPRegen ZAPRegen `cmd:"" name:"regen"`
21+ ZAPXML ZAPXML `cmd:"" name:"xml" default:"withargs"`
22+ ZAPRegen ZAPRegen `cmd:"" name:"regen"`
23+ ControllerClusters ZAPControllerClusters `cmd:"" name:"controller-clusters"`
2124}
2225
2326type ZAPXML struct {
@@ -224,7 +227,6 @@ type ZAPRegen struct {
224227 spec.FilterOptions `embed:""`
225228 sdk.SDKOptions `embed:""`
226229 render.TemplateOptions `embed:""`
227- ControllerClusters bool `name:"controller-clusters" help:"Generate controller-clusters.matter from all spec clusters"`
228230}
229231
230232func (z * ZAPRegen ) Run (cc * Context ) (err error ) {
@@ -240,10 +242,6 @@ func (z *ZAPRegen) Run(cc *Context) (err error) {
240242 return
241243 }
242244
243- if z .ControllerClusters {
244- return z .runControllerClusters (cc , specification )
245- }
246-
247245 zapTargeter := regen .Targeter (z .SdkRoot )
248246
249247 var zapPaths pipeline.Paths
@@ -283,7 +281,26 @@ func (z *ZAPRegen) Run(cc *Context) (err error) {
283281 return
284282}
285283
286- func (z * ZAPRegen ) runControllerClusters (cc * Context , specification * spec.Specification ) error {
284+ type ZAPControllerClusters struct {
285+ common.ASCIIDocAttributes `embed:""`
286+ pipeline.ProcessingOptions `embed:""`
287+ files.OutputOptions `embed:""`
288+ spec.ParserOptions `embed:""`
289+ Output string `name:"output" placeholder:"path" help:"Output file or directory for controller-clusters.matter" optional:"" default:"controller-clusters.matter"`
290+ }
291+
292+ func (z * ZAPControllerClusters ) Run (cc * Context ) (err error ) {
293+ var specification * spec.Specification
294+ specification , _ , err = spec .Parse (cc , z .ParserOptions , z .ProcessingOptions , []spec.BuilderOption {spec .PatchForSdk (true )}, z .ASCIIDocAttributes .ToList ())
295+ if err != nil {
296+ return
297+ }
298+
299+ err = sdk .ApplyErrata (specification )
300+ if err != nil {
301+ return
302+ }
303+
287304 var clusterRefs []zap.ClusterRef
288305 for code , cluster := range specification .ClustersByID {
289306 clusterRefs = append (clusterRefs , zap.ClusterRef {
@@ -326,7 +343,25 @@ func (z *ZAPRegen) runControllerClusters(cc *Context, specification *spec.Specif
326343 }
327344 renderer .SuppressEndpoints = true
328345
329- zapPath := filepath .Join (z .SdkRoot , "src/controller/data_model/controller-clusters.zap" )
346+ var zapPath string
347+ outPath := filepath .Clean (z .Output )
348+ isDir := false
349+ if fi , err := os .Stat (outPath ); err == nil {
350+ isDir = fi .IsDir ()
351+ } else if strings .HasSuffix (z .Output , "/" ) || strings .HasSuffix (z .Output , string (filepath .Separator )) {
352+ isDir = true
353+ }
354+
355+ if isDir {
356+ zapPath = filepath .Join (outPath , "controller-clusters.zap" )
357+ } else {
358+ ext := filepath .Ext (outPath )
359+ if ext == "" {
360+ zapPath = outPath + ".zap"
361+ } else {
362+ zapPath = strings .TrimSuffix (outPath , ext ) + ".zap"
363+ }
364+ }
330365 zapData := pipeline .NewData [* zap.File ](zapPath , syntheticFile )
331366
332367 outputs , _ , err := renderer .Process (cc , zapData , 0 , 1 )
0 commit comments