Skip to content

Commit d028856

Browse files
authored
feat: add repository URL support for plugin manifest (#262)
* feat: add repository URL support for plugin manifest - Introduced a new optional flag for specifying the plugin repository URL during initialization. - Updated the InitPluginWithFlags function to handle the new repository parameter. - Enhanced profile management to include repository input. - Modified related tests to validate the new repository functionality. * fix: improve input validation in profile checkRule method - Updated the checkRule method to ensure cursor is within valid range before checking for empty input values. This change prevents potential out-of-bounds errors and enhances the robustness of the input validation process.
1 parent 7492a3d commit d028856

5 files changed

Lines changed: 33 additions & 4 deletions

File tree

cmd/commandline/plugin.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
var (
1212
author string
1313
name string
14+
repo string
1415
description string
1516
allowRegisterEndpoint bool
1617
allowInvokeTool bool
@@ -38,6 +39,7 @@ If no parameters are provided, an interactive mode will be started.`,
3839
Run: func(c *cobra.Command, args []string) {
3940
author, _ := c.Flags().GetString("author")
4041
name, _ := c.Flags().GetString("name")
42+
repo, _ := c.Flags().GetString("repo")
4143
description, _ := c.Flags().GetString("description")
4244
allowRegisterEndpoint, _ := c.Flags().GetBool("allow-register-endpoint")
4345
allowInvokeTool, _ := c.Flags().GetBool("allow-invoke-tool")
@@ -60,6 +62,7 @@ If no parameters are provided, an interactive mode will be started.`,
6062
plugin.InitPluginWithFlags(
6163
author,
6264
name,
65+
repo,
6366
description,
6467
allowRegisterEndpoint,
6568
allowInvokeTool,
@@ -234,6 +237,7 @@ func init() {
234237
pluginInitCommand.Flags().StringVar(&author, "author", "", "Author name (1-64 characters, lowercase letters, numbers, dashes and underscores only)")
235238
pluginInitCommand.Flags().StringVar(&name, "name", "", "Plugin name (1-128 characters, lowercase letters, numbers, dashes and underscores only)")
236239
pluginInitCommand.Flags().StringVar(&description, "description", "", "Plugin description (cannot be empty)")
240+
pluginInitCommand.Flags().StringVar(&repo, "repo", "", "Plugin repository URL (optional)")
237241
pluginInitCommand.Flags().BoolVar(&allowRegisterEndpoint, "allow-endpoint", false, "Allow the plugin to register endpoints")
238242
pluginInitCommand.Flags().BoolVar(&allowInvokeTool, "allow-tool", false, "Allow the plugin to invoke tools")
239243
pluginInitCommand.Flags().BoolVar(&allowInvokeModel, "allow-model", false, "Allow the plugin to invoke models")

cmd/commandline/plugin/init.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ func InitPlugin() {
3939
func InitPluginWithFlags(
4040
author string,
4141
name string,
42+
repo string,
4243
description string,
4344
allowRegisterEndpoint bool,
4445
allowInvokeTool bool,
@@ -345,7 +346,10 @@ func (m model) createPlugin() {
345346
},
346347
}
347348

348-
fmt.Println(m.subMenus[SUB_MENU_KEY_VERSION_REQUIRE].(versionRequire).MinimalDifyVersion())
349+
repo := m.subMenus[SUB_MENU_KEY_PROFILE].(profile).Repo()
350+
if repo != "" {
351+
manifest.Repo = parser.ToPtr(repo)
352+
}
349353

350354
categoryString := m.subMenus[SUB_MENU_KEY_CATEGORY].(category).Category()
351355
if categoryString == "tool" {

cmd/commandline/plugin/init_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ func TestInitPluginWithFlags(t *testing.T) {
2525
testName string
2626
author string
2727
pluginName string
28+
repo string
2829
description string
2930
quick bool
3031
permissions struct {
@@ -47,6 +48,7 @@ func TestInitPluginWithFlags(t *testing.T) {
4748
testName: "Quick mode with minimal permissions",
4849
author: "test-author",
4950
pluginName: "test-plugin",
51+
repo: "https://github.com/langgenius/dify-official-plugins",
5052
description: "Test plugin description",
5153
quick: true,
5254
permissions: struct {
@@ -80,6 +82,7 @@ func TestInitPluginWithFlags(t *testing.T) {
8082
testName: "Quick mode with all permissions",
8183
author: "test-author",
8284
pluginName: "test-plugin-full",
85+
repo: "https://github.com/langgenius/dify-official-plugins",
8386
description: "Test plugin with all permissions",
8487
quick: true,
8588
permissions: struct {
@@ -122,6 +125,7 @@ func TestInitPluginWithFlags(t *testing.T) {
122125
testName: "Non-quick mode with tool permissions",
123126
author: "test-author",
124127
pluginName: "test-plugin-tool",
128+
repo: "https://github.com/langgenius/dify-official-plugins",
125129
description: "Test plugin with tool permissions",
126130
quick: false,
127131
permissions: struct {
@@ -157,6 +161,7 @@ func TestInitPluginWithFlags(t *testing.T) {
157161
InitPluginWithFlags(
158162
tt.author,
159163
tt.pluginName,
164+
tt.repo,
160165
tt.description,
161166
tt.permissions.endpoint,
162167
tt.permissions.tool,
@@ -261,34 +266,39 @@ func TestInitPluginWithFlagsValidation(t *testing.T) {
261266
name string
262267
author string
263268
pluginName string
269+
repo string
264270
description string
265271
expectError bool
266272
}{
267273
{
268274
name: "Valid inputs",
269275
author: "test-author",
270276
pluginName: "test-plugin",
277+
repo: "https://github.com/langgenius/dify-official-plugins",
271278
description: "Test description",
272279
expectError: false,
273280
},
274281
{
275282
name: "Invalid author (uppercase)",
276283
author: "Test-Author",
277284
pluginName: "test-plugin",
285+
repo: "https://github.com/langgenius/dify-official-plugins",
278286
description: "Test description",
279287
expectError: true,
280288
},
281289
{
282290
name: "Invalid plugin name (uppercase)",
283291
author: "test-author",
284292
pluginName: "Test-Plugin",
293+
repo: "https://github.com/langgenius/dify-official-plugins",
285294
description: "Test description",
286295
expectError: true,
287296
},
288297
{
289298
name: "Empty description",
290299
author: "test-author",
291300
pluginName: "test-plugin",
301+
repo: "https://github.com/langgenius/dify-official-plugins",
292302
description: "",
293303
expectError: true,
294304
},
@@ -312,6 +322,7 @@ func TestInitPluginWithFlagsValidation(t *testing.T) {
312322
InitPluginWithFlags(
313323
tt.author,
314324
tt.pluginName,
325+
tt.repo,
315326
tt.description,
316327
false, // allowRegisterEndpoint
317328
false, // allowInvokeTool

cmd/commandline/plugin/profile.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,13 @@ func newProfile() profile {
3232
description.CharLimit = 1024
3333
description.Prompt = "Description (press Enter to next step): "
3434

35+
repo := ti.New()
36+
repo.Placeholder = "Repository URL (Optional)"
37+
repo.CharLimit = 128
38+
repo.Prompt = "Repository URL (Optional) (press Enter to next step): "
39+
3540
return profile{
36-
inputs: []ti.Model{name, author, description},
41+
inputs: []ti.Model{name, author, description, repo},
3742
}
3843
}
3944

@@ -49,16 +54,20 @@ func (p profile) Description() string {
4954
return p.inputs[2].Value()
5055
}
5156

57+
func (p profile) Repo() string {
58+
return p.inputs[3].Value()
59+
}
60+
5261
func (p profile) View() string {
53-
s := fmt.Sprintf("Edit profile of the plugin\n%s\n%s\n%s\n", p.inputs[0].View(), p.inputs[1].View(), p.inputs[2].View())
62+
s := fmt.Sprintf("Edit profile of the plugin\n%s\n%s\n%s\n%s\n", p.inputs[0].View(), p.inputs[1].View(), p.inputs[2].View(), p.inputs[3].View())
5463
if p.warning != "" {
5564
s += fmt.Sprintf("\033[31m%s\033[0m\n", p.warning)
5665
}
5766
return s
5867
}
5968

6069
func (p *profile) checkRule() bool {
61-
if p.inputs[p.cursor].Value() == "" {
70+
if p.cursor >= 0 && p.cursor <= 2 && p.inputs[p.cursor].Value() == "" {
6271
p.warning = "Name, author and description cannot be empty"
6372
return false
6473
} else if p.cursor == 0 && !plugin_entities.PluginNameRegex.MatchString(p.inputs[p.cursor].Value()) {

pkg/entities/plugin_entities/plugin_declaration.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ type PluginDeclarationWithoutAdvancedFields struct {
153153
Tags []manifest_entities.PluginTag `json:"tags" yaml:"tags,omitempty" validate:"omitempty,dive,plugin_tag,max=128"`
154154
CreatedAt time.Time `json:"created_at" yaml:"created_at,omitempty" validate:"required"`
155155
Privacy *string `json:"privacy,omitempty" yaml:"privacy,omitempty" validate:"omitempty"`
156+
Repo *string `json:"repo,omitempty" yaml:"repo,omitempty" validate:"omitempty,url"`
156157
}
157158

158159
func (p *PluginDeclarationWithoutAdvancedFields) UnmarshalJSON(data []byte) error {

0 commit comments

Comments
 (0)