command

package
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Apr 27, 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
		}
		issue, err := ctx.Forge.Issue(int(num))
		if err != nil {
			log.Err(err).Msg("")
			ctx.DeferredError("could not retrieve issue/PR")
			return
		}

		body := ctx.Forge.ReplaceIssueLinks(issue.Body)
		if len(body) > 1000 {
			body = body[:1000] + "..."
		}

		embed := discord.Embed{
			Author: &discord.EmbedAuthor{
				Name: issue.User.Username,
				URL:  issue.User.URL,
				Icon: issue.User.Image,
			},
			Thumbnail: &discord.EmbedThumbnail{
				URL: ctx.Forge.Image(),
			},
			Title:       fmt.Sprintf("%s #%d", issue.Title, num),
			URL:         issue.URL,
			Description: body,
			Footer: &discord.EmbedFooter{
				Text: "Created",
			},
			Timestamp: discord.NewTimestamp(issue.Created),
			Fields: []discord.EmbedField{
				{
					Name:   "Comments",
					Value:  strconv.Itoa(issue.Comments),
					Inline: true,
				},
			},
		}
		if len(issue.Labels) > 0 {
			embed.Fields = append(embed.Fields, discord.EmbedField{
				Name:   "Labels",
				Value:  fmt.Sprintf("`%s`", strings.Join(issue.Labels, "`, `")),
				Inline: true,
			})
		}
		state := issue.State
		if !issue.Closed.IsZero() {
			state += fmt.Sprintf(" <t:%d:R>", issue.Closed.Unix())
		}
		embed.Fields = append(embed.Fields, discord.EmbedField{
			Name:   "State",
			Value:  state,
			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("")
		}
	},
}

Issue is the 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