package module
Version: v0.0.0-...-5f916b1 Latest Latest

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

Go to latest
Published: Feb 5, 2017 License: MIT Imports: 22 Imported by: 0



Build Status Coverage Status GoDoc

apicompat is a tool to check for the introduction of backwards incompatible changes.


  • Guarantees that all consumers of a library will still build without failure
  • Only checks exported declarations
  • There are no false positives (if there are, it's a bug)
  • Not every backwards incompatible change can be detected, swapping argument parameters and other changes still need to be considered by the library author
  • Can be simply consumed as a library
  • Is in its infancy, see Status, feedback and review appreciated
  • Was originally named abicheck during early development

Secondary tasks could include:

  • Detecting current semver and suggesting an appropriate increase
  • Listing all changes for help in writing release notes/commit messages.

Try at abicheck.bradleyf.id.au or via CLI:

go get -u github.com/bradleyfalzon/apicompat/cmd/apicompat
cd /your/project/dir/with/committed/changes

Proposed Arguments

apicompat also comes with a command line tool, as well as being used as a library, the following are the proposed flags and arguments for the command line tool.

-vcs    (auto|git|svn|etc) - Version control system to use (default: auto)
-before revision           - Revisions to check as before  (default: if unstaged changes, check those, else check last two commits)
-after  revision           - Revisions to check as after   (default: if unstaged changes, check those, else check last two commits)
-vcsDir path               - Path to root VCS directory    (default: let VCS tool search)
-all                       - Show non-breaking changes as well as breaking (default: false)

apicompat        # current package only
apicompat ./...  # check subdirectory packages

Another tool, called abichanges may also be included which will list all detected changes to assist in producing release notes.


apicompat is currently under heavy development and refactoring. This initial version was a proof of concept and shortcuts were taken. The current tasks are focused on (but not limited to):

  • Adding Mercurial, SVN and potentially other VCS systems
  • Improve VCS options such as:
    • Detection of VCS and flag to overwrite
    • Choosing base VCS path to allow running for a different directory
    • Filtering vendor/ directories (if this is the best place to do it, or leave it to go/type ast packages)
    • Check subdirectories if ran from a subdirectory of the VCS (currently checks all committed code)
  • Add docs, flow diagram and fixing of existing docs
  • Improve output formats (such as vim quickfix)
  • Move these tasks to GitHub issues
  • Once all other steps have been completed, performance will be investigated


This uses golden masters for the tests, currently (and only due to time constraints) testdata/ directory contains before.go and after.go, which are before and after versions of a test package, each time go test is ran, the output is compared to testdata/exp.txt, which should not change.

If adding new test cases, you should expect the test to fail as the code changes should create a difference with exp.txt. Then, you'll need to update the golden master (see below), and commit those changes. If you add a new test case to before.go and after.go, and the tests still pass, you've uncovered a bug within apicompat which will need a code change to fix, once code has change, the tests should fail, so update the master, review all your changes and commit.

  • This uses golden master testdata/exp.txt for the tests
  • Run tests with: go test
  • Update master with: go test -args update
  • Alternatively to do a test run: go install && ( cd testgit; ./make.sh && apicompat )




View Source
const (
	None        = "no change"
	NonBreaking = "non-breaking change"
	Breaking    = "breaking change"

The different declaration messages the package can generate.


This section is empty.


func RelativePathToTarget

func RelativePathToTarget(path string) (rel string, recurse bool, err error)

RelativePathToTarget returns the relative path to the given path, wether it's an import path or direct path and also returns if the path had recursion requested (/...).

func SetExcludeDir

func SetExcludeDir(pattern string) func(*Checker)

SetExcludeDir excludes checking of a directory based on regexp pattern. Usually only help when running recursively.

func SetExcludeFile

func SetExcludeFile(pattern string) func(*Checker)

SetExcludeFile excludes checking of files based on regexp pattern

func SetVCS

func SetVCS(vcs VCS) func(*Checker)

SetVCS is an option to New that sets the VCS for the checker.

func SetVLog

func SetVLog(w io.Writer) func(*Checker)

SetVLog is an option to New that sets the logger for the checker.


type Change

type Change struct {
	Pkg    string   // Pkg is the name of the package the change occurred in
	ID     string   // ID is an identifier to match a declaration between versions
	Msg    string   // Msg describes the change
	Change string   // Change describes whether it was unknown, no change, non-breaking or breaking change
	Pos    string   // Pos is the ASTs position prefixed with a version
	Before ast.Decl // Before is the previous declaration
	After  ast.Decl // After is the new declaration

Change is the ast declaration containing the before and after

func (Change) String

func (c Change) String() string

type Checker

type Checker struct {
	// contains filtered or unexported fields

Checker is used to check for changes between two versions of a package.

func New

func New(options ...func(*Checker)) *Checker

New returns a Checker with the given options.

func (*Checker) Check

func (c *Checker) Check(rel string, recurse bool, beforeRev, afterRev string) ([]Change, error)

Check an import path and before and after revision for changes. Import path maybe empty, if so, the current working directory will be used. If a revision is blank, the default VCS revision is used.

type DeclChange

type DeclChange struct {
	// Change is the type of change, see None, NonBreaking and Breaking.
	Change string
	// Msg describes what changed, such as "members added".
	Msg string
	// Pos is the position of the change.
	Pos token.Pos

DeclChange represents a single change between 2 revision.

type DeclChecker

type DeclChecker struct {
	// contains filtered or unexported fields

DeclChecker takes a list of changes and verifies which, if any, change breaks the API.

func NewDeclChecker

func NewDeclChecker(bi, ai *types.Info) *DeclChecker

NewDeclChecker creates a DeclChecker.

func (DeclChecker) Check

func (c DeclChecker) Check(before, after ast.Decl) (DeclChange, error)

Check compares two declarations and returns the DeclChange associated with that change. For example, comments aren't compared, names of arguments aren't compared etc.

type Git

type Git struct {
	// contains filtered or unexported fields

Git implements vcs and uses exec.Command to access repository

func NewGit

func NewGit(path string) (*Git, error)

NewGit returns a VCS based based on git.

func (*Git) DefaultRevision

func (g *Git) DefaultRevision() (string, string)

DefaultRevision returns the default revisions if none specified

func (*Git) OpenFile

func (g *Git) OpenFile(revision, path string) (io.ReadCloser, error)

OpenFile returns a reader for a given absolute path at a revision

func (*Git) ReadDir

func (g *Git) ReadDir(revision, path string) ([]os.FileInfo, error)

ReadDir returns a list of files in a directory at revision

type StrVCS

type StrVCS struct {
	// contains filtered or unexported fields

StrVCS provides a in memory vcs used for testing, but does not support subdirectories.

func (StrVCS) DefaultRevision

func (StrVCS) DefaultRevision() (string, string)

DefaultRevision implements VCS.DefaultRevision

func (StrVCS) OpenFile

func (v StrVCS) OpenFile(revision, path string) (io.ReadCloser, error)

OpenFile implements VCS.OpenFile

func (StrVCS) ReadDir

func (v StrVCS) ReadDir(revision, path string) (files []os.FileInfo, err error)

ReadDir implements VCS.ReadDir

func (*StrVCS) SetFile

func (v *StrVCS) SetFile(revision, path string, contents []byte)

SetFile contents for a particular revision and path

type VCS

type VCS interface {
	// ReadDir returns a list of files in a directory at revision
	ReadDir(revision, path string) ([]os.FileInfo, error)
	// OpenFile returns a reader for a given absolute path at a revision
	OpenFile(revision, path string) (io.ReadCloser, error)
	// DefaultRevision returns the default revisions if none specified
	DefaultRevision() (before string, after string)

VCS defines a version control system the vcs should be able to handle calls to ReadFile concurrently A special case for the revision of "." (without quotes) is used to check local filesystem


Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL