Can i have a logic which imports a package if it exists in the source code?

54 Views Asked by At

I am trying to write a boiler plate code - where the use case is following. Consider the following as my directory structure:

sample-service

  • migrations
    • migration.go
  • main.go

In main.go I want to write a logic which will import the migration package if the directory or the files exist.

After importing the package I want to call the function/methods of that package.

I have tried using plugins but that would restrict me with Operating System.

I am not sure if go/importer or reflect can work, i tried few approaches but none worked.

1

There are 1 best solutions below

0
Peter On

The only way to import a package is to write an import statement. Imports happen during the build of the program, so you can't change them at runtime.

If plugins are not an option you can have the migrations package register itself somewhere (other than the main package because that cannot be imported).

For instance:

// migrations/migration.go
package migrations

import "my.module/migrations/registry"

func init() {
    registry.Register(SomeFunc)
}

func SomeFunc() {
    // ...
}

// migrations/registry/registry.go
package registry

var funcs []func()

func Register(f func()) {
    funcs = append(funcs, f)
}

func RunAll() {
    for _, f := range funcs {
        f()
    }
}

// main.go
package main

import "my.module/migrations/registry"

func main() {
    registry.RunAll()
}

Consider generating the init function in the migrations package automatically during the build. This can be as simple as:

#!/bin/sh

rm -f migrations/init.go
if [ -f migrations/migration.go ]; then
    cat > migrations/init.go <<EOF
// Generated file. Do not edit.
package migrations

import "my.module/migrations/registry"

func init() {
    registry.Register(SomeFunc)
}
EOF
fi