From 11002376606ae31c852c11dce7b0721bd1453751 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 06:53:02 +0000 Subject: [PATCH 1/4] Migrate WU CLI to WU-Go-ui Wails application - Migrated core business logic (auth, devcenter, drivermeta, shippinglabel) from `WU-Go` to `WU-Go-ui/internal`. - Implemented Wails bridge (`app.go`) to expose backend functionality to the frontend. - Created a modern, frameless React+Tailwind frontend with a 4-step wizard workflow. - Implemented `AuthStep`, `SubmissionStep`, `MetadataStep` (with filtering), and `LabelStep`. - Added unit tests for metadata parsing. - Verified frontend build and visual appearance. - Configured Wails project settings and styling. --- WU-Go-ui/app.go | 91 +- WU-Go-ui/frontend/index.html | 3 +- WU-Go-ui/frontend/package-lock.json | 2331 +++++++++++++++++ WU-Go-ui/frontend/package.json | 10 +- WU-Go-ui/frontend/postcss.config.js | 6 + WU-Go-ui/frontend/src/App.tsx | 64 +- WU-Go-ui/frontend/src/components/Layout.tsx | 12 + .../frontend/src/components/StepIndicator.tsx | 45 + WU-Go-ui/frontend/src/components/TitleBar.tsx | 20 + .../frontend/src/components/ui/Button.tsx | 49 + WU-Go-ui/frontend/src/components/ui/Card.tsx | 78 + .../frontend/src/components/ui/Checkbox.tsx | 24 + WU-Go-ui/frontend/src/components/ui/Input.tsx | 24 + WU-Go-ui/frontend/src/components/ui/Label.tsx | 19 + WU-Go-ui/frontend/src/lib/utils.ts | 6 + WU-Go-ui/frontend/src/style.css | 79 +- WU-Go-ui/frontend/src/types/index.ts | 50 + WU-Go-ui/frontend/src/views/AuthStep.tsx | 71 + WU-Go-ui/frontend/src/views/LabelStep.tsx | 133 + WU-Go-ui/frontend/src/views/MetadataStep.tsx | 123 + .../frontend/src/views/SubmissionStep.tsx | 77 + WU-Go-ui/frontend/tailwind.config.js | 52 + WU-Go-ui/frontend/wailsjs/go/main/App.d.ts | 10 +- WU-Go-ui/frontend/wailsjs/go/main/App.js | 13 +- WU-Go-ui/internal/auth/credential.go | 53 + WU-Go-ui/internal/auth/token.go | 49 + WU-Go-ui/internal/devcenter/client.go | 20 + .../internal/devcenter/shippinglabel_api.go | 67 + WU-Go-ui/internal/devcenter/submission.go | 75 + .../internal/drivermeta/hardware_target.go | 11 + WU-Go-ui/internal/drivermeta/parse.go | 107 + WU-Go-ui/internal/drivermeta/parse_test.go | 64 + WU-Go-ui/internal/format/json.go | 13 + WU-Go-ui/internal/shippinglabel/payload.go | 89 + WU-Go-ui/internal/support/cancel.go | 14 + WU-Go-ui/internal/support/errors.go | 15 + WU-Go-ui/internal/support/strings.go | 50 + WU-Go-ui/internal/validate/chid.go | 39 + WU-Go-ui/main.go | 3 +- WU-Go-ui/wails.json | 13 +- 40 files changed, 4010 insertions(+), 62 deletions(-) create mode 100644 WU-Go-ui/frontend/package-lock.json create mode 100644 WU-Go-ui/frontend/postcss.config.js create mode 100644 WU-Go-ui/frontend/src/components/Layout.tsx create mode 100644 WU-Go-ui/frontend/src/components/StepIndicator.tsx create mode 100644 WU-Go-ui/frontend/src/components/TitleBar.tsx create mode 100644 WU-Go-ui/frontend/src/components/ui/Button.tsx create mode 100644 WU-Go-ui/frontend/src/components/ui/Card.tsx create mode 100644 WU-Go-ui/frontend/src/components/ui/Checkbox.tsx create mode 100644 WU-Go-ui/frontend/src/components/ui/Input.tsx create mode 100644 WU-Go-ui/frontend/src/components/ui/Label.tsx create mode 100644 WU-Go-ui/frontend/src/lib/utils.ts create mode 100644 WU-Go-ui/frontend/src/types/index.ts create mode 100644 WU-Go-ui/frontend/src/views/AuthStep.tsx create mode 100644 WU-Go-ui/frontend/src/views/LabelStep.tsx create mode 100644 WU-Go-ui/frontend/src/views/MetadataStep.tsx create mode 100644 WU-Go-ui/frontend/src/views/SubmissionStep.tsx create mode 100644 WU-Go-ui/frontend/tailwind.config.js create mode 100644 WU-Go-ui/internal/auth/credential.go create mode 100644 WU-Go-ui/internal/auth/token.go create mode 100644 WU-Go-ui/internal/devcenter/client.go create mode 100644 WU-Go-ui/internal/devcenter/shippinglabel_api.go create mode 100644 WU-Go-ui/internal/devcenter/submission.go create mode 100644 WU-Go-ui/internal/drivermeta/hardware_target.go create mode 100644 WU-Go-ui/internal/drivermeta/parse.go create mode 100644 WU-Go-ui/internal/drivermeta/parse_test.go create mode 100644 WU-Go-ui/internal/format/json.go create mode 100644 WU-Go-ui/internal/shippinglabel/payload.go create mode 100644 WU-Go-ui/internal/support/cancel.go create mode 100644 WU-Go-ui/internal/support/errors.go create mode 100644 WU-Go-ui/internal/support/strings.go create mode 100644 WU-Go-ui/internal/validate/chid.go diff --git a/WU-Go-ui/app.go b/WU-Go-ui/app.go index af53038..21df46e 100644 --- a/WU-Go-ui/app.go +++ b/WU-Go-ui/app.go @@ -3,16 +3,27 @@ package main import ( "context" "fmt" + "path/filepath" + "os" + + "WU-Go-ui/internal/auth" + "WU-Go-ui/internal/devcenter" + "WU-Go-ui/internal/drivermeta" + "WU-Go-ui/internal/shippinglabel" + "WU-Go-ui/internal/support" ) // App struct type App struct { - ctx context.Context + ctx context.Context + httpClient *devcenter.Client } // NewApp creates a new App application struct func NewApp() *App { - return &App{} + return &App{ + httpClient: devcenter.NewClient("https://manage.devcenter.microsoft.com/v2.0/my/hardware"), + } } // startup is called when the app starts. The context is saved @@ -21,7 +32,77 @@ func (a *App) startup(ctx context.Context) { a.ctx = ctx } -// Greet returns a greeting for the given name -func (a *App) Greet(name string) string { - return fmt.Sprintf("Hello %s, It's show time!", name) +// Config Methods + +func (a *App) LoadConfig() (*auth.Credential, error) { + path := a.getCredentialPath() + return auth.LoadCredential(path), nil +} + +func (a *App) SaveConfig(c auth.Credential) error { + path := a.getCredentialPath() + auth.SaveCredential(path, &c) + return nil +} + +func (a *App) getCredentialPath() string { + // Attempt to store in same dir as executable, fallback to local + exe, err := os.Executable() + if err != nil { + return "credential.json" + } + return filepath.Join(filepath.Dir(exe), "credential.json") +} + +// Auth Methods + +func (a *App) AcquireToken(tenantID, clientID, clientSecret string) (string, error) { + return auth.AcquireToken(a.ctx, a.httpClient.HTTP, tenantID, clientID, clientSecret) +} + +// Submission Methods + +func (a *App) GetSubmission(token, productID, submissionID string) (map[string]any, error) { + if support.IsBlank(productID) || support.IsBlank(submissionID) { + return nil, support.NewAPIError("Product ID and Submission ID are required") + } + return devcenter.GetSubmission(a.ctx, a.httpClient, token, productID, submissionID) +} + +// Metadata Methods + +func (a *App) AnalyzeMetadata(token string, submission map[string]any) (*drivermeta.ParseResult, error) { + url, err := devcenter.FindDriverMetadataURL(submission) + if err != nil { + return nil, err + } + + metaRoot, err := devcenter.DownloadDriverMetadata(a.ctx, a.httpClient, token, url) + if err != nil { + return nil, err + } + + return drivermeta.Parse(metaRoot) +} + +// Label Methods + +func (a *App) CreateShippingLabel( + token, productID, submissionID string, + options shippinglabel.LabelOptions, + name string, + targets []drivermeta.HardwareTarget, + chids []string, +) (map[string]any, error) { + + if support.IsBlank(name) { + return nil, support.NewAPIError("Shipping label name is required") + } + + payload, err := shippinglabel.BuildPayload(options, name, targets, chids) + if err != nil { + return nil, err + } + + return devcenter.CreateShippingLabel(a.ctx, a.httpClient, token, productID, submissionID, payload) } diff --git a/WU-Go-ui/frontend/index.html b/WU-Go-ui/frontend/index.html index 3f3c67d..0d9f3a3 100644 --- a/WU-Go-ui/frontend/index.html +++ b/WU-Go-ui/frontend/index.html @@ -3,11 +3,10 @@
-