func applyManifest(manifest *model.Manifest) error {
	if manifest.HasServer() {
		manifestBytes, err := json.MarshalIndent(manifest, "", "  ")
		if err != nil {
			return err
		}
		manifestStr := string(manifestBytes)
		if err := ioutil.WriteFile(
			"server/manifest.go",
			[]byte(fmt.Sprintf(pluginIDGoFileTemplate, manifestStr)),
			0644,
		); err != nil {
			return errors.Wrap(err, "failed to write server/manifest.go")
		}
	}
	if manifest.HasWebapp() {
		manifestBytes, err := json.MarshalIndent(manifest, "", "    ")
		if err != nil {
			return err
		}
		manifestStr := string(manifestBytes)
		if err := ioutil.WriteFile(
			"webapp/src/manifest.ts",
			[]byte(fmt.Sprintf(pluginIDJSFileTemplate, manifestStr)),
			0644,
		); err != nil {
			return errors.Wrap(err, "failed to open webapp/src/manifest.ts")
		}
	}
	return nil
}
applyManifest propagates the plugin_id into the server and webapp folders, as necessary
package main
import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"github.com/mattermost/mattermost-server/v5/model"
	"github.com/pkg/errors"
)
const pluginIDGoFileTemplate = ` 
package main
import (
	"strings"
	"github.com/mattermost/mattermost-server/v5/model"
)
var manifest *model.Manifest
const manifestStr = ` + "`" + `
%s
` + "`" + `
func init() {
	manifest = model.ManifestFromJson(strings.NewReader(manifestStr))
}
`
const pluginIDJSFileTemplate = ` 
const manifest = JSON.parse(` + "`" + `
%s
` + "`" + `);
export default manifest;
export const id = manifest.id;
export const version = manifest.version;
`
func main() {
	if len(os.Args) <= 1 {
		panic("no cmd specified")
	}
	manifest, err := findManifest()
	if err != nil {
		panic("failed to find manifest: " + err.Error())
	}
	cmd := os.Args[1]
	switch cmd {
	case "id":
		dumpPluginID(manifest)
	case "version":
		dumpPluginVersion(manifest)
	case "has_server":
		if manifest.HasServer() {
			fmt.Printf("true")
		}
	case "has_webapp":
		if manifest.HasWebapp() {
			fmt.Printf("true")
		}
	case "apply":
		if err := applyManifest(manifest); err != nil {
			panic("failed to apply manifest: " + err.Error())
		}
	default:
		panic("unrecognized command: " + cmd)
	}
}
func findManifest() (*model.Manifest, error) {
	_, manifestFilePath, err := model.FindManifest(".")
	if err != nil {
		return nil, errors.Wrap(err, "failed to find manifest in current working directory")
	}
	manifestFile, err := os.Open(manifestFilePath)
	if err != nil {
		return nil, errors.Wrapf(err, "failed to open %s", manifestFilePath)
	}
	defer manifestFile.Close()
	var manifest model.Manifest
	decoder := json.NewDecoder(manifestFile)
	decoder.DisallowUnknownFields()
	if err = decoder.Decode(&manifest); err != nil {
		return nil, errors.Wrap(err, "failed to parse manifest")
	}
	return &manifest, nil
}
func dumpPluginID(manifest *model.Manifest) {
	fmt.Printf("%s", manifest.Id)
}
func dumpPluginVersion(manifest *model.Manifest) {
	fmt.Printf("%s", manifest.Version)
}