@@ -4,9 +4,12 @@ import (
44 "fmt"
55 "os"
66 "os/exec"
7+ "path/filepath"
78 "regexp"
9+ "strings"
810
911 "github.com/spf13/cobra"
12+ "github.com/toob-boot/toob/internal/apiclient"
1013 "github.com/toob-boot/toob/internal/installer"
1114 "github.com/toob-boot/toob/internal/paths"
1215 "github.com/toob-boot/toob/internal/registry"
2124 initDevContainer bool
2225 initSdkUrl string
2326 initSdkRevision string
27+ initPackage bool
2428)
2529
2630var initCmd = & cobra.Command {
@@ -30,8 +34,16 @@ var initCmd = &cobra.Command{
3034 RunE : func (cmd * cobra.Command , args []string ) error {
3135 projectName := args [0 ]
3236
33- validNamePattern := regexp .MustCompile (`^[a-zA-Z0-9_-]+$` )
37+ var validNamePattern * regexp.Regexp
38+ if initPackage {
39+ validNamePattern = regexp .MustCompile (`^(@[a-zA-Z0-9_-]+/)?[a-zA-Z0-9_-]+$` )
40+ } else {
41+ validNamePattern = regexp .MustCompile (`^[a-zA-Z0-9_-]+$` )
42+ }
3443 if ! validNamePattern .MatchString (projectName ) {
44+ if initPackage {
45+ return fmt .Errorf ("invalid package name '%s'. Allowed: unscoped 'name' or scoped '@scope/name' containing alphanumeric, dashes, and underscores" , projectName )
46+ }
3547 return fmt .Errorf ("invalid project name '%s'. Only alphanumeric characters, dashes, and underscores are allowed" , projectName )
3648 }
3749
@@ -78,6 +90,130 @@ var initCmd = &cobra.Command{
7890 return initErr
7991 }
8092
93+ if initPackage {
94+ ui .Step ("Scaffolding publishable package project '%s'..." , projectName )
95+ // Get author login
96+ author := apiclient .GetLogin ()
97+ if author == "" {
98+ author = "unregistered"
99+ }
100+
101+ // Determine core/toolchain versions from matrix
102+ tcVersion := "12.2.0"
103+ coreVersion := "1.0.0"
104+ if matrix , err := cache .FetchLiveMatrix (); err == nil && matrix != nil {
105+ if chipMatrix , ok := (* matrix )[initChip ]; ok {
106+ for _ , v := range chipMatrix .Versions {
107+ if v .Dependencies .Toolchain != "" {
108+ tcVersion = v .Dependencies .Toolchain
109+ }
110+ if v .Dependencies .CoreSDK != "" {
111+ coreVersion = v .Dependencies .CoreSDK
112+ }
113+ break
114+ }
115+ }
116+ }
117+
118+ // Clean base name for files (remove scope if present)
119+ baseName := projectName
120+ if _ , after , ok := strings .Cut (projectName , "/" ); ok {
121+ baseName = after
122+ }
123+
124+ // 1. Create folders: src, include
125+ if err := os .MkdirAll (filepath .Join (projectDir , "src" ), 0o755 ); err != nil {
126+ initErr = err
127+ return err
128+ }
129+ if err := os .MkdirAll (filepath .Join (projectDir , "include" ), 0o755 ); err != nil {
130+ initErr = err
131+ return err
132+ }
133+
134+ // 2. Write driver_manifest.json
135+ manifestPath := filepath .Join (projectDir , "driver_manifest.json" )
136+ manifestJSON := fmt .Sprintf (`{
137+ "name": %q,
138+ "author": %q,
139+ "version": "0.1.0",
140+ "description": "Scaffolded driver for %s",
141+ "reference_build_context": {
142+ "chip": %q,
143+ "core_sdk_version": %q,
144+ "toolchain_version": %q,
145+ "target_architecture": %q
146+ },
147+ "dependencies": {
148+ "core": "^%s"
149+ },
150+ "sources": [
151+ "src/%s.c"
152+ ],
153+ "includes": [
154+ "include"
155+ ]
156+ }
157+ ` , projectName , author , initChip , initChip , coreVersion , tcVersion , ci .Arch , coreVersion , baseName )
158+ if err := os .WriteFile (manifestPath , []byte (manifestJSON ), 0o644 ); err != nil {
159+ initErr = err
160+ return err
161+ }
162+
163+ // 3. Write src/<baseName>.c
164+ cPath := filepath .Join (projectDir , "src" , baseName + ".c" )
165+ funcName := strings .ReplaceAll (baseName , "-" , "_" )
166+ cCode := fmt .Sprintf (`#include "%s.h"
167+
168+ // TODO: Implement your driver initialization function here
169+ void %s_init(void) {
170+ // Hardware initialization
171+ }
172+ ` , baseName , funcName )
173+ if err := os .WriteFile (cPath , []byte (cCode ), 0o644 ); err != nil {
174+ initErr = err
175+ return err
176+ }
177+
178+ // 4. Write include/<baseName>.h
179+ hPath := filepath .Join (projectDir , "include" , baseName + ".h" )
180+ hCode := fmt .Sprintf (`#ifndef %s_H
181+ #define %s_H
182+
183+ void %s_init(void);
184+
185+ #endif // %s_H
186+ ` , strings .ToUpper (funcName ), strings .ToUpper (funcName ), funcName , strings .ToUpper (funcName ))
187+ if err := os .WriteFile (hPath , []byte (hCode ), 0o644 ); err != nil {
188+ initErr = err
189+ return err
190+ }
191+
192+ // 5. Write .toobignore and .gitignore
193+ ignoreList := ".toob/\n build/\n credentials.json\n *.tar.gz\n "
194+ if err := os .WriteFile (filepath .Join (projectDir , ".toobignore" ), []byte (ignoreList ), 0o644 ); err != nil {
195+ initErr = err
196+ return err
197+ }
198+ if err := os .WriteFile (filepath .Join (projectDir , ".gitignore" ), []byte (ignoreList ), 0o644 ); err != nil {
199+ initErr = err
200+ return err
201+ }
202+
203+ // Initialize git repo
204+ gitCmd := exec .Command ("git" , "init" )
205+ _ = gitCmd .Run ()
206+
207+ ui .Divider ()
208+ ui .KeyValue ("Package Name" , ui .Bold (projectName ))
209+ ui .KeyValue ("Chip" , ui .BoldBrand (initChip ))
210+ ui .KeyValue ("Architecture" , ui .Cyan (ci .Arch ))
211+ ui .Divider ()
212+ ui .Success ("Package initialized successfully!" )
213+ ui .Tip ("Run `cd %s` and check out `driver_manifest.json`." , projectName )
214+ return nil
215+ }
216+
81217 if initFramework == "" {
82218 idx , _ := cache .LoadIndex ()
83219 liveIntegrations , liveErr := cache .FetchLiveIntegrations ()
@@ -192,4 +328,6 @@ func init() {
192328 initCmd .Flags ().BoolVar (& initDevContainer , "devcontainer" , false , "Generate VS Code DevContainer configuration for isolated builds" )
193329 initCmd .Flags ().StringVar (& initSdkUrl , "sdk-url" , "https://github.com/Toob-Boot/Toob-Loader.git" , "URL to fetch the Toob-Loader SDK from" )
194330 initCmd .Flags ().StringVar (& initSdkRevision , "sdk-version" , "main" , "Git branch or tag to use for the Toob-Loader SDK" )
331+ // TODO (Gap 10): Scaffold a publishable package project with manifest template.
332+ initCmd .Flags ().BoolVar (& initPackage , "package" , false , "Initialize as a publishable package project instead of a firmware application" )
195333}
0 commit comments