Add manifest apply command to generate server and webapp manifest files
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
0bc6d51b24
commit
6403d1a51d
2 changed files with 91 additions and 3 deletions
|
@ -131,7 +131,7 @@ Commands:
|
||||||
reset Reset plugin from current directory (disable then enable)
|
reset Reset plugin from current directory (disable then enable)
|
||||||
deploy Upload and enable plugin bundle to Mattermost server
|
deploy Upload and enable plugin bundle to Mattermost server
|
||||||
updateassets Update plugin files from embedded assets
|
updateassets Update plugin files from embedded assets
|
||||||
manifest Get plugin manifest information using templates (get {{.field}}, check)
|
manifest Get plugin manifest information using templates (get {{.field}}, apply, check)
|
||||||
logs View plugin logs (use --watch to follow logs in real-time)
|
logs View plugin logs (use --watch to follow logs in real-time)
|
||||||
create-plugin Create a new plugin from the starter template (supports --name and --module flags)
|
create-plugin Create a new plugin from the starter template (supports --name and --module flags)
|
||||||
help Show this help message
|
help Show this help message
|
||||||
|
@ -147,6 +147,7 @@ Examples:
|
||||||
pluginctl deploy --bundle-path ./bundle.tar.gz # Deploy specific bundle file
|
pluginctl deploy --bundle-path ./bundle.tar.gz # Deploy specific bundle file
|
||||||
pluginctl updateassets # Update plugin files from embedded assets
|
pluginctl updateassets # Update plugin files from embedded assets
|
||||||
pluginctl manifest get '{{.id}}' # Get any manifest field using templates
|
pluginctl manifest get '{{.id}}' # Get any manifest field using templates
|
||||||
|
pluginctl manifest apply # Generate manifest files for server/webapp
|
||||||
pluginctl manifest check # Validate plugin manifest
|
pluginctl manifest check # Validate plugin manifest
|
||||||
pluginctl logs # View recent plugin logs
|
pluginctl logs # View recent plugin logs
|
||||||
pluginctl logs --watch # Watch plugin logs in real-time
|
pluginctl logs --watch # Watch plugin logs in real-time
|
||||||
|
|
91
manifest.go
91
manifest.go
|
@ -2,15 +2,97 @@ package pluginctl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost/server/public/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// File permissions for generated directories and files.
|
||||||
|
manifestDirPerm = 0o750
|
||||||
|
manifestFilePerm = 0o600
|
||||||
|
)
|
||||||
|
|
||||||
|
const pluginIDGoFileTemplate = `// This file is automatically generated. Do not modify it manually.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost/server/public/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var manifest *model.Manifest
|
||||||
|
|
||||||
|
const manifestStr = ` + "`%s`" + `
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
_ = json.NewDecoder(strings.NewReader(manifestStr)).Decode(&manifest)
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const pluginIDJSFileTemplate = `// This file is automatically generated. Do not modify it manually.
|
||||||
|
|
||||||
|
const manifest = JSON.parse(` + "`%s`" + `);
|
||||||
|
|
||||||
|
export default manifest;
|
||||||
|
`
|
||||||
|
|
||||||
|
// applyManifest generates manifest files for server and webapp components.
|
||||||
|
func applyManifest(manifest *model.Manifest, pluginPath string) error {
|
||||||
|
manifestBytes, err := json.Marshal(manifest)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to marshal manifest: %w", err)
|
||||||
|
}
|
||||||
|
manifestStr := string(manifestBytes)
|
||||||
|
|
||||||
|
// Generate server manifest file if server exists
|
||||||
|
if HasServerCode(manifest) {
|
||||||
|
serverDir := filepath.Join(pluginPath, "server")
|
||||||
|
if err := os.MkdirAll(serverDir, manifestDirPerm); err != nil {
|
||||||
|
return fmt.Errorf("failed to create server directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
serverManifestPath := filepath.Join(serverDir, "manifest.go")
|
||||||
|
serverContent := fmt.Sprintf(pluginIDGoFileTemplate, manifestStr)
|
||||||
|
|
||||||
|
if err := os.WriteFile(serverManifestPath, []byte(serverContent), manifestFilePerm); err != nil {
|
||||||
|
return fmt.Errorf("failed to write server manifest: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Info("Generated server manifest", "path", serverManifestPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate webapp manifest file if webapp exists
|
||||||
|
if HasWebappCode(manifest) {
|
||||||
|
webappDir := filepath.Join(pluginPath, "webapp", "src")
|
||||||
|
if err := os.MkdirAll(webappDir, manifestDirPerm); err != nil {
|
||||||
|
return fmt.Errorf("failed to create webapp directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
webappManifestPath := filepath.Join(webappDir, "manifest.ts")
|
||||||
|
webappContent := fmt.Sprintf(pluginIDJSFileTemplate, manifestStr)
|
||||||
|
|
||||||
|
if err := os.WriteFile(webappManifestPath, []byte(webappContent), manifestFilePerm); err != nil {
|
||||||
|
return fmt.Errorf("failed to write webapp manifest: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Info("Generated webapp manifest", "path", webappManifestPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// RunManifestCommand implements the 'manifest' command functionality with subcommands.
|
// RunManifestCommand implements the 'manifest' command functionality with subcommands.
|
||||||
func RunManifestCommand(args []string, pluginPath string) error {
|
func RunManifestCommand(args []string, pluginPath string) error {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return fmt.Errorf("manifest command requires a subcommand: get {{.field_name}}, check")
|
return fmt.Errorf("manifest command requires a subcommand: get {{.field_name}}, apply, check")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to absolute path
|
// Convert to absolute path
|
||||||
|
@ -45,6 +127,10 @@ func RunManifestCommand(args []string, pluginPath string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Print(buf.String())
|
fmt.Print(buf.String())
|
||||||
|
case "apply":
|
||||||
|
if err := applyManifest(manifest, absPath); err != nil {
|
||||||
|
return fmt.Errorf("failed to apply manifest: %w", err)
|
||||||
|
}
|
||||||
case "check":
|
case "check":
|
||||||
if err := manifest.IsValid(); err != nil {
|
if err := manifest.IsValid(); err != nil {
|
||||||
Logger.Error("Plugin manifest validation failed", "error", err)
|
Logger.Error("Plugin manifest validation failed", "error", err)
|
||||||
|
@ -53,7 +139,8 @@ func RunManifestCommand(args []string, pluginPath string) error {
|
||||||
}
|
}
|
||||||
Logger.Info("Plugin manifest is valid")
|
Logger.Info("Plugin manifest is valid")
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown subcommand: %s. Available subcommands: get {{.field_name}}, check", subcommand)
|
return fmt.Errorf("unknown subcommand: %s. Available subcommands: get {{.field_name}}, apply, check",
|
||||||
|
subcommand)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue