command

package
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2022 License: MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// Commands is a map of Command names to their Command
	Commands = make(map[string]Command)
)
View Source
var Commit = Command{
	Meta: api.CreateCommandData{
		Name:        "commit",
		Description: "Commit information",
		Type:        discord.ChatInputCommand,
		Options: []discord.CommandOption{
			&discord.StringOption{
				OptionName:  "sha",
				Description: "The commit SHA (partial or full)",
				Required:    true,
			},
		},
	},
	Handler: func(ctx *Context) {
		if err := ctx.State.RespondInteraction(ctx.Event.ID, ctx.Event.Token, deferredInteraction); err != nil {
			log.Err(err).Msg("")
			return
		}

		sha := ctx.Event.Data.(*discord.CommandInteraction).Options[0].String()

		commit, err := ctx.Forge.Commit(sha)
		if err != nil {
			log.Err(err).Msg("")
			ctx.DeferredError("could not retrieve commit")
			return
		}

		body := ctx.Forge.ReplaceIssueLinks(commit.Message)
		if len(body) > 1000 {
			body = body[:1000] + "..."
		}
		embed := discord.Embed{
			Author: &discord.EmbedAuthor{
				Name: commit.Author.Username,
				URL:  commit.Author.URL,
				Icon: commit.Author.Image,
			},
			Thumbnail: &discord.EmbedThumbnail{
				URL: ctx.Forge.Image(),
			},
			Title:       commit.SHA,
			URL:         commit.URL,
			Description: body,
			Footer: &discord.EmbedFooter{
				Text: "Created",
			},
			Timestamp: discord.NewTimestamp(commit.Time),
			Fields: []discord.EmbedField{
				{
					Name:   "Stats",
					Value:  fmt.Sprintf("%d ++ %d --", commit.Additions, commit.Deletions),
					Inline: true,
				},
				{
					Name:   "Verified",
					Value:  strconv.FormatBool(commit.Verified),
					Inline: true,
				},
			},
		}

		data := api.EditInteractionResponseData{
			Embeds: &[]discord.Embed{
				embed,
			},
		}

		if _, err := ctx.State.EditInteractionResponse(ctx.App.ID, ctx.Event.Token, data); err != nil {
			log.Err(err).Msg("")
		}
	},
}

Commit is the command for getting a forge.Commit by its SHA

View Source
var Debug = Command{
	Meta: api.CreateCommandData{
		Name:        "debug",
		Description: "Debugging info",
		Type:        discord.ChatInputCommand,
	},
	Handler: func(ctx *Context) {
		data := api.InteractionResponse{
			Type: api.MessageInteractionWithSource,
			Data: &api.InteractionResponseData{
				Content: option.NewNullableString(debugMessage),
			},
		}
		if err := ctx.State.RespondInteraction(ctx.Event.ID, ctx.Event.Token, data); err != nil {
			log.Err(err).Msg("")
		}
	},
}

Debug is the debugging command

View Source
var Issue = Command{
	Meta: api.CreateCommandData{
		Name:        "issue",
		Description: "Issue/PR information",
		Type:        discord.ChatInputCommand,
		Options: []discord.CommandOption{
			&discord.IntegerOption{
				OptionName:  "num",
				Description: "The issue/PR number",
				Min:         option.NewInt(1),
				Required:    true,
			},
		},
	},
	Handler: func(ctx *Context) {
		if err := ctx.State.RespondInteraction(ctx.Event.ID, ctx.Event.Token, deferredInteraction); err != nil {
			log.Err(err).Msg("")
			return
		}

		num, err := ctx.Event.Data.(*discord.CommandInteraction).Options[0].IntValue()
		if err != nil {
			log.Err(err).Msg("")
			ctx.DeferredError("could not parse num")
			return
		}

		embed, err := forgeIssue(ctx, int(num))
		if err != nil {
			log.Err(err).Msg("")
			ctx.DeferredError("could not retrieve issue/PR")
			return
		}

		data := api.EditInteractionResponseData{
			Embeds: &[]discord.Embed{
				embed,
			},
		}

		if _, err := ctx.State.EditInteractionResponse(ctx.App.ID, ctx.Event.Token, data); err != nil {
			log.Err(err).Msg("")
		}
	},
}

Issue is the command for getting a forge.Issue by its number

View Source
var IssueMessage = Command{
	Meta: api.CreateCommandData{
		Name: "View Issue(s)",
		Type: discord.MessageCommand,
	},
	Handler: func(ctx *Context) {
		if err := ctx.State.RespondInteraction(ctx.Event.ID, ctx.Event.Token, deferredInteractionEphemeral); err != nil {
			log.Err(err).Msg("")
			return
		}

		var message discord.Message
		for _, msg := range ctx.Event.Data.(*discord.CommandInteraction).Resolved.Messages {
			message = msg
		}

		matches := findIssueMatches(message.Content)
		if len(matches) == 0 {
			ctx.DeferredError("no matches found for issues/PRs")
			return
		}

		embeds := make([]discord.Embed, 0, len(matches))
		for _, match := range matches {
			embed, err := forgeIssue(ctx, match)
			if err != nil {
				log.Err(err).Msg("")
				embed = discord.Embed{
					Title:       "Error",
					Description: fmt.Sprintf("Could not retrieve issue/PR #%d", match),
				}
			}
			embeds = append(embeds, embed)
		}

		data := api.EditInteractionResponseData{
			Embeds: &embeds,
		}

		if _, err := ctx.State.EditInteractionResponse(ctx.App.ID, ctx.Event.Token, data); err != nil {
			log.Err(err).Msg("")
		}
	},
}

IssueMessage is the message command for getting a forge.Issue by its number

View Source
var Social = Command{
	Meta: api.CreateCommandData{
		Name:        "social",
		Description: "Social info",
		Type:        discord.ChatInputCommand,
	},
	Handler: func(ctx *Context) {
		desc := make([]string, 0, len(socials))
		for _, social := range socials {
			desc = append(desc, fmt.Sprintf("[%s](%s)", social.name, social.link))
		}
		embed := discord.Embed{
			Thumbnail: &discord.EmbedThumbnail{
				URL: ctx.Forge.Image(),
			},
			Title:       "Gitea Social",
			Description: strings.Join(desc, "\n"),
		}
		data := api.InteractionResponse{
			Type: api.MessageInteractionWithSource,
			Data: &api.InteractionResponseData{
				Embeds: &[]discord.Embed{
					embed,
				},
			},
		}
		if err := ctx.State.RespondInteraction(ctx.Event.ID, ctx.Event.Token, data); err != nil {
			log.Err(err).Msg("")
		}
	},
}

Social is the social (media) command

View Source
var Source = Command{
	Meta: api.CreateCommandData{
		Name:        "source",
		Description: "File information",
		Type:        discord.ChatInputCommand,
		Options: []discord.CommandOption{
			&discord.StringOption{
				OptionName:  "path",
				Description: "The path to the source file",
				Required:    true,
			},
			&discord.StringOption{
				OptionName:  "lines",
				Description: "Specific lines in the source file",
			},
			&discord.StringOption{
				OptionName:  "branch",
				Description: "Branch for the source file",
			},
		},
	},
	Handler: func(ctx *Context) {
		if err := ctx.State.RespondInteraction(ctx.Event.ID, ctx.Event.Token, deferredInteraction); err != nil {
			log.Err(err).Msg("")
			return
		}

		var path, branch string
		var lines *parsedLines
		for _, opt := range ctx.Event.Data.(*discord.CommandInteraction).Options {
			switch opt.Name {
			case "path":
				path = opt.String()
			case "lines":
				l, err := parseLines(opt.String())
				if err != nil {
					ctx.DeferredError(err.Error())
					return
				}
				lines = l
			case "branch":
				branch = opt.String()
			}
		}

		file, err := ctx.Forge.File(strings.TrimPrefix(path, "/"), branch)
		if err != nil {
			ctx.DeferredError("could not retrieve file")
			return
		}

		content := fmt.Sprintf("<%s%s>", file.URL, lines.fragment())
		if lines != nil {
			contents := strings.Split(file.Contents, "\n")
			content += fmt.Sprintf("\n```go\n%s\n```", strings.Join(contents[lines.lower():lines.upper()], "\n"))
		}
		if len(content) > 2000 {
			content = content[:1991] + "//...\n```"
		}

		data := api.EditInteractionResponseData{
			Content: option.NewNullableString(content),
		}

		if _, err := ctx.State.EditInteractionResponse(ctx.App.ID, ctx.Event.Token, data); err != nil {
			log.Err(err).Msg("")
		}
	},
}

Source is the command for getting a forge.File by its path

Functions

This section is empty.

Types

type Command

type Command struct {
	Meta    api.CreateCommandData
	Handler func(*Context)
}

Command is a discord command

type Context

type Context struct {
	App   *discord.Application
	State *state.State
	Event *gateway.InteractionCreateEvent
	Forge Forge
}

Context is passed in to each Command.Handler

func (*Context) DeferredError

func (c *Context) DeferredError(msg string)

DeferredError is a quick way to respond to a failed deferred interaction

type Forge

type Forge interface {
	Image() string
	Commit(sha string) (*forge.Commit, error)
	Issue(num int) (*forge.Issue, error)
	File(path string, branch string) (*forge.File, error)
	ReplaceIssueLinks(content string) string
}

Forge is a vcs that can return information to distea

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL