go-plugin/plugin.go

102 lines
2.3 KiB
Go

// Copyright 2023 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package plugin
import (
"context"
"net/http"
"os"
"github.com/joho/godotenv"
"github.com/rs/zerolog/log"
"github.com/urfave/cli/v2"
)
// Options defines the options for the plugin.
type Options struct {
// Name of the plugin.
Name string
// Description of the plugin.
Description string
// Version of the plugin.
Version string
// Flags of the plugin.
Flags []cli.Flag
// Execute function of the plugin.
Execute ExecuteFunc
}
// Plugin defines the plugin instance.
type Plugin struct {
app *cli.App
execute ExecuteFunc
client *http.Client
// Metadata of the current pipeline.
Metadata Metadata
}
// ExecuteFunc defines the function that is executed by the plugin.
type ExecuteFunc func(ctx context.Context) error
// New plugin instance.
func New(opt Options) *Plugin {
if _, err := os.Stat("/run/woodpecker/env"); err == nil {
_ = godotenv.Overload("/run/woodpecker/env")
}
app := &cli.App{
Name: opt.Name,
Description: opt.Description,
Version: opt.Version,
Flags: append(opt.Flags, Flags()...),
}
plugin := &Plugin{
app: app,
execute: opt.Execute,
}
plugin.app.Action = plugin.action
return plugin
}
func (p *Plugin) action(ctx *cli.Context) error {
if err := SetupConsoleLogger(ctx); err != nil {
return err
}
p.Metadata = MetadataFromContext(ctx)
p.client = HTTPClientFromContext(ctx)
if p.execute == nil {
panic("plugin execute function is not set")
}
return p.execute(ctx.Context)
}
// HTTPClient returns the http.Client instance.
func (p *Plugin) HTTPClient() *http.Client {
return p.client
}
// Run the plugin.
func (p *Plugin) Run() {
if err := p.app.Run(os.Args); err != nil {
log.Error().Err(err).Msg("execution failed")
os.Exit(1)
}
}