A tool for competitive programming in Go.
Extract only the codes used from main
function, apply gofmt
and output into one file.
go install github.com/murosan/gollect/cmd/gollect@latest
It parses AST at runtime, so it depends on the GoLang's version installed.
Please reinstall when you upgrade (or downgrade) GoLang.
Suppose you have implemented the following Min
,Max
functions in the lib
package:
package lib
import "golang.org/x/exp/constraints"
func Min[T constraints.Ordered](a, b T) T {
if a < b {
return a
}
return b
}
func Max[T constraints.Ordered](a, b T) T {
if a > b {
return a
}
return b
}
Then implement main
package.
The following code reads two numbers and outputs the larger one.
package main
import (
"fmt"
"github.com/your-name/repo-name/lib"
)
func main() {
var a, b int
fmt.Scan(&a, &b)
max := lib.Max(a, b)
fmt.Println(max)
}
Execute gollect
.
$ gollect -in ./main.go
The code you can submit will be outputted as follow:
package main
import (
"fmt"
"golang.org/x/exp/constraints"
)
func main() {
var a, b int
fmt.Scan(&a, &b)
max := Max(a, b)
fmt.Println(max)
}
func Max[T constraints.Ordered](a, b T) T {
if a > b {
return a
}
return b
}
Import statements of self managed package (github.com/your-name/repo-name/lib
) and unused Min
functions are not included.
The package golang.org/x/exp/constraints
is configured to leave by default.
The details of settings are described later.
You can write configuration file by YAML syntax.
To specify configuration file, run gollect with -config
option.
$ gollect -config config.yml
inputFile: main.go
outputPaths:
- stdout
thirdPartyPackagePathPrefixes:
- golang.org/x/exp
- github.com/emirpasic/gods
- github.com/liyue201/gostl
- gonum.org/v1/gonum
You can override default values by specifying each option.
The dafault values are used if the option is omitted.
key | type | description | default |
---|---|---|---|
inputFile | string | The filepath main function is written.If there are multiple files of main package, you have to specify all files by glob. |
main.go |
example:
inputFile: main.go
inputFile: ./*.go
key | type | description | default |
---|---|---|---|
outputPaths | []string | outputs. available values: stdout ,clipboard ,<filepath> |
stdout |
example:
outputPaths:
- stdout
- clipboard
- out/main.go
key | type | description | default |
---|---|---|---|
thirdPartyPackagePathPrefixes | []string | Package-path prefixes that can be used at judge system. The import statements and package selectors specified here will not be deleted. |
golang.org/x/exp github.com/emirpasic/gods github.com/liyue201/gostl gonum.org/v1/gonum |
example:
thirdPartyPackagePathPrefixes:
- golang.org/x/exp
- github.com/emirpasic/gods
thirdPartyPackagePathPrefixes: []
Finally, the declaration which is not used from main
function will be ignored.
Also methods are not exception.
// input
package main
import "sort"
type S[T ~int | ~string] []T
func (s S[T]) Len() int { return len(s) }
func (s S[T]) Less(i, j int) bool { return s[i] < s[j] }
func (s S[T]) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func main() {
var s S[int]
sort.Sort(&s)
}
// output
// !! compile error !!
package main
import "sort"
type S[T ~int | ~string] []T
func main() {
var s S[int]
sort.Sort(&s)
}
The Len
, Less
and Swap
functions have been removed as they are not used directly from the main
function, but the final code will not work without them.
There are two ways to leave them.
// input
package main
import "sort"
type S[T ~int | ~string] struct {
sort.Interface
data []T
}
func (s *S[T]) Len() int { return len(s.data) }
func (s *S[T]) Less(i, j int) bool { return s.data[i] < s.data[j] }
func (s *S[T]) Swap(i, j int) { s.data[i], s.data[j] = s.data[j], s.data[i] }
func (*S[T]) Unused() {} // will be removed
func main() {
var s S[int]
sort.Sort(&s)
}
// output
package main
import "sort"
type S[T ~int | ~string] struct {
sort.Interface
data []T
}
func (s *S[T]) Len() int { return len(s.data) }
func (s *S[T]) Less(i, j int) bool { return s.data[i] < s.data[j] }
func (s *S[T]) Swap(i, j int) { s.data[i], s.data[j] = s.data[j], s.data[i] }
func main() {
var s S[int]
sort.Sort(&s)
}
Write // gollect: keep methods
in the Struct comment, and all methods will be left.
// input
package main
import "sort"
// gollect: keep methods
type S[T ~int | ~string] []T
func (s S[T]) Len() int { return len(s) }
func (s S[T]) Less(i, j int) bool { return s[i] < s[j] }
func (s S[T]) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (S[T]) Unused() {} // will be left
func main() {
var s S[int]
sort.Sort(&s)
}
// output
package main
import "sort"
type S[T ~int | ~string] []T
func (s S[T]) Len() int { return len(s) }
func (s S[T]) Less(i, j int) bool { return s[i] < s[j] }
func (s S[T]) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (S[T]) Unused() {} // will be left
func main() {
var s S[int]
sort.Sort(&s)
}
import "C" // cannot use
package main
import . "fmt" // cannot use
func main() { Println() }
package pkg
func init() {}
package main
import _ "github.com/owner/repo/pkg" // cannot use
func main() {}