Skip to content

Commit 8dfb5d4

Browse files
committed
fix: expose xorm and xormigrate to yaegi plugins
The plugin docs tell plugins to implement Migrations() returning []*xormigrate.Migration, but neither `xorm.io/xorm` nor `src.techknowlogick.com/xormigrate` was in the yaegi symbol table, so an interpreted plugin failed at the import before it could ever be loaded. Add both packages to yaegiSymbolPackages and commit the generated symbol tables, plus a loader test that runs an interpreted plugin migration against a real engine. Fixes #3501
1 parent 0a2b644 commit 8dfb5d4

5 files changed

Lines changed: 1029 additions & 0 deletions

File tree

magefile.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,8 @@ var yaegiSymbolPackages = []struct {
14371437
{"github.com/labstack/echo/v5", "echo.go"},
14381438
{"github.com/ThreeDotsLabs/watermill/message", "watermill.go"},
14391439
{"github.com/spf13/viper", "viper.go"},
1440+
{"src.techknowlogick.com/xormigrate", "xormigrate.go"},
1441+
{"xorm.io/xorm", "xorm.go"},
14401442
}
14411443

14421444
// YaegiSymbols regenerates the yaegi symbol tables in pkg/yaegi_symbols so
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Vikunja is a to-do list application to facilitate your life.
2+
// Copyright 2018-present Vikunja and contributors. All rights reserved.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
package yaegi
18+
19+
import (
20+
"testing"
21+
22+
_ "github.com/mattn/go-sqlite3" // Needed to open the in-memory engine the migration runs against.
23+
"xorm.io/xorm"
24+
)
25+
26+
const migrationPluginDir = "testdata/migrationplugin"
27+
28+
func TestLoadPluginWithMigrations(t *testing.T) {
29+
loaded, err := LoadPluginFull(migrationPluginDir)
30+
if err != nil {
31+
t.Fatalf("LoadPluginFull failed: %v", err)
32+
}
33+
34+
if loaded.Migration == nil {
35+
t.Fatal("Migration is nil — typed factory NewMigrationPlugin not found")
36+
}
37+
38+
migrations := loaded.Migration.Migrations()
39+
if len(migrations) != 1 {
40+
t.Fatalf("expected 1 migration, got %d", len(migrations))
41+
}
42+
if migrations[0].ID != "20260101000000-create-plugin-migration-test" {
43+
t.Errorf("unexpected migration id %q", migrations[0].ID)
44+
}
45+
46+
// The interpreted MigrateFunc has to survive the interface boundary and run
47+
// against a real engine, not just be non-nil.
48+
engine, err := xorm.NewEngine("sqlite3", "file::memory:")
49+
if err != nil {
50+
t.Fatalf("could not create test engine: %v", err)
51+
}
52+
defer engine.Close()
53+
54+
if err := migrations[0].Migrate(engine); err != nil {
55+
t.Fatalf("running the plugin migration failed: %v", err)
56+
}
57+
58+
exists, err := engine.IsTableExist("plugin_migration_test")
59+
if err != nil {
60+
t.Fatalf("checking for the migrated table failed: %v", err)
61+
}
62+
if !exists {
63+
t.Error("plugin migration ran but did not create its table")
64+
}
65+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Vikunja is a to-do list application to facilitate your life.
2+
// Copyright 2018-present Vikunja and contributors. All rights reserved.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
package main
18+
19+
import (
20+
"code.vikunja.io/api/pkg/plugins"
21+
22+
"src.techknowlogick.com/xormigrate"
23+
"xorm.io/xorm"
24+
)
25+
26+
type MigrationTestPlugin struct{}
27+
28+
// Interpreted types reach xorm as anonymous reflect structs with no methods, so
29+
// TableName() is invisible and the table name has to be passed via Table().
30+
type pluginData struct {
31+
ID int64 `xorm:"pk autoincr"`
32+
Name string `xorm:"varchar(250)"`
33+
}
34+
35+
func (p *MigrationTestPlugin) Name() string { return "migration-test" }
36+
func (p *MigrationTestPlugin) Version() string { return "1.0.0" }
37+
func (p *MigrationTestPlugin) Init() error { return nil }
38+
func (p *MigrationTestPlugin) Shutdown() error { return nil }
39+
40+
func (p *MigrationTestPlugin) Migrations() []*xormigrate.Migration {
41+
return []*xormigrate.Migration{
42+
{
43+
ID: "20260101000000-create-plugin-migration-test",
44+
Description: "Create the plugin migration test table",
45+
Migrate: func(tx *xorm.Engine) error {
46+
return tx.Table("plugin_migration_test").Sync2(&pluginData{})
47+
},
48+
Rollback: func(tx *xorm.Engine) error {
49+
return tx.DropTables("plugin_migration_test")
50+
},
51+
},
52+
}
53+
}
54+
55+
func NewPlugin() plugins.Plugin { return &MigrationTestPlugin{} }
56+
57+
func NewMigrationPlugin() plugins.MigrationPlugin { return &MigrationTestPlugin{} }

0 commit comments

Comments
 (0)