changes

package module
v0.2.8 Latest Latest
Warning

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

Go to latest
Published: May 7, 2021 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package changes implements Go module version management for a multi-module git repository.

Repository

The Repository struct is a representation of a git repository containing multiple Go modules. Repository handles the whole release process with respect to versioning, including tagging the git repository and updating CHANGELOG, version.go, and go.mod files. The sequence of steps required to create a release of the SDK can be run from the Repository's DoRelease function:

repo, err := changes.NewRepository("path/to/repository")
if err != nil {
	panic(err)
}

repo.DoRelease("2020-08-12")

After this code snippet runs, the versions of modules within the specified repository will be updated based on change metadata contained in the repository.

Metadata

In order to make module versioning decisions during a release, the Repository's DoRelease function consumes metadata about changes included in the release. The metadata is stored in the root of the repository in a .changes directory. The Metadata struct provides a way to load, create, and modify the metadata in the .changes directory. The .changes directory is structured as follows:

.changes/
	next-release/	contains Change metadata for pending changes (to be included in the next release).
	releases/	contains Release metadata for previous releases.
	versions.json	is a VersionEnclosure representing the state of the repository at the last release.

There are three file formats used in the .changes directory corresponding to three structs: Change, Release, and VersionEnclosure.

Changelogs

The Repository's DoRelease function pdates both a top level CHANGELOG.md and per-module CHANGELOG.md files. The CHANGELOG.md in the root of the repository provides a consolidated view of all changelog entries for every module. This means that the root module does not have its own CHANGELOG.

The Release struct handles the rendering of CHANGELOG files, generating an entry that is prepended to CHANGELOG files during a release.

Dependencies within the SDK

As part of the Repository's release process, any module within the repository that depends upon another module in the repository will have its dependency updated to the latest version. So, after a release all modules in the SDK depend on the latest version of any other SDK module.

Index

Constants

View Source
const SchemaVersion = 1

SchemaVersion defines the current JSON schema version for persistent data types (Change, Release, ...)

Variables

This section is empty.

Functions

func AffectedModules

func AffectedModules(changes []Change) []string

AffectedModules returns a sorted list of all modules affected by the given Changes. A module is considered affected if it is the Module of one or more Changes that will result in a version increment.

func ChangeToTemplate

func ChangeToTemplate(change Change) ([]byte, error)

ChangeToTemplate returns a Change template populated with the given Change's data.

func GetChangesPath

func GetChangesPath() (string, error)

GetChangesPath searches upward from the current directory for a .changes directory, returning a relative path from the current directory to the .changes directory.

func GetCurrentModule

func GetCurrentModule() (string, error)

GetCurrentModule returns a shortened module path (from the root of the repository to the module, not a full import path) for the Go module containing the current directory.

func MatchWildcardModules

func MatchWildcardModules(modules []string, wildcard string) ([]string, error)

MatchWildcardModules filters modules, returning only the modules that match the given wildcard.

func ModIsWildcard

func ModIsWildcard(mod string) bool

ModIsWildcard returns whether the given module ends in the wildcard pattern.

Types

type Change

type Change struct {
	ID            string     // ID is a unique identifier for this Change.
	SchemaVersion int        // SchemaVersion is the version of the library's types used to create this Change.
	Module        string     // Module is a shortened Go module path for the module affected by this Change. Module is the path from the root of the repository to the module.
	Type          ChangeType // Type indicates what category of Change was made. Type may be either "feature" or "bugfix".
	Description   string     // Description is a human readable description of this Change meant to be included in a CHANGELOG.
	MinVersion    string     // MinVersion is a semver tag that the module should be minimally bumped to.

	// AffectedModules is a list of modules affected by this Change. AffectedModules is only non-nil when the Change's
	// Module has a wildcard, in which case AffectedModules contains all modules matching the wildcard Module that the
	// Change affects.
	AffectedModules []string
}

Change represents a change to a single Go module.

func NewChanges

func NewChanges(modules []string, changeType ChangeType, description string, minVersion string) ([]Change, error)

NewChanges returns a Change slice containing a Change with the given type and description for each of the specified modules.

func NewWildcardChange

func NewWildcardChange(modulePath string, changeType ChangeType, description string, affectedModules []string, minVersion string) (Change, error)

NewWildcardChange creates a wildcard Change.

func TemplateToChanges

func TemplateToChanges(filledTemplate []byte) ([]Change, error)

TemplateToChanges parses the provided filledTemplate into the provided Change. If Change has no ID, TemplateToChange will set the ID.

func (Change) IndentedDescription

func (c Change) IndentedDescription(indent string) string

IndentedDescription returns the Change's Description with each line except for the first prefixed with the given string.

func (Change) String

func (c Change) String() string

String returns a string representation of a Change suitable to be included in a Changelog.

type ChangeType

type ChangeType string

ChangeType describes the type of change made to a Go module.

const (
	// FeatureChangeType is a constant change type for a new feature.
	FeatureChangeType ChangeType = "feature"
	// BugFixChangeType is a constant change type for a bug fix.
	BugFixChangeType ChangeType = "bugfix"
	// MajorChangeType is a constant change type for a major version updates (from v0 => v1).
	MajorChangeType ChangeType = "major"
	// DependencyChangeType is a constant change type for a dependency update.
	DependencyChangeType ChangeType = "dependency"
	// AnnouncementChangeType is a constant change type for an SDK announcement.
	AnnouncementChangeType ChangeType = "announcement"
	// DocumentationChangeType is a constant change type for an SDK announcement.
	DocumentationChangeType ChangeType = "documentation"
)

func ParseChangeType

func ParseChangeType(v string) (ChangeType, error)

ParseChangeType attempts to parse the given string v into a ChangeType, returning an error if the string is invalid.

func (ChangeType) ChangelogPrefix

func (c ChangeType) ChangelogPrefix() string

ChangelogPrefix returns the CHANGELOG header the ChangeType should be grouped under.

func (*ChangeType) Set

func (c *ChangeType) Set(s string) error

Set parses the given string and correspondingly sets the ChangeType, returning an error if the string could not be parsed.

func (ChangeType) String

func (c ChangeType) String() string

String returns a string representation of the ChangeType

func (*ChangeType) UnmarshalJSON

func (c *ChangeType) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the encoding/json package's Unmarshaler interface, additionally providing change type validation.

func (*ChangeType) UnmarshalYAML

func (c *ChangeType) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML implements yaml.v2's Unmarshaler interface, additionally providing change type validation.

func (ChangeType) VersionIncrement

func (c ChangeType) VersionIncrement() VersionIncrement

VersionIncrement returns the VersionIncrement corresponding to the given ChangeType.

type Metadata

type Metadata struct {
	ChangePath      string           // ChangePath is the relative path from the current directory to .changes
	Changes         []Change         // Changes holds all pending change metadata in the .changes/next-release directory
	Releases        []*Release       // Releases contains all releases in the .changes/releases directory
	CurrentVersions VersionEnclosure // CurrentVersions is the .changes/versions.json enclosure of current module versions
}

Metadata is a representation of the change metadata stored in a .changes directory.

func LoadMetadata

func LoadMetadata(path string) (*Metadata, error)

LoadMetadata loads the .changes directory at the given path.

func (*Metadata) AddChange

func (m *Metadata) AddChange(c Change) error

AddChange adds the given Change to the Metadata's Changes and saves the Change to the next-release directory.

func (*Metadata) AddChanges

func (m *Metadata) AddChanges(changes []Change) error

AddChanges adds the given Changes to Metadata's Changes and saves the Changes to the next-release directory.

func (*Metadata) AddChangesFromTemplate

func (m *Metadata) AddChangesFromTemplate(template []byte) ([]Change, error)

AddChangesFromTemplate parses the given YAML template, adding the resulting Changes to Metadata's Changes and saving the Changes to the next-release directory. AddChangesFromTemplate returns the created Changes.

func (*Metadata) ClearChanges

func (m *Metadata) ClearChanges() error

ClearChanges removes all Changes from the Metadata's Changes and deletes the Change files in the .changes/next-release directory.

func (*Metadata) CreateRelease

func (m *Metadata) CreateRelease(id string, bumps map[string]VersionBump, dryRun bool) (*Release, error)

CreateRelease consolidates the Metadata's pending Changes into a Release. This operation will remove all Changes from the Metadata and delete change files in .changes/next-release. A release file will also be created in .changes/releases. If dryRun is true, CreateRelease will return a Release, but not modify change or release files.

func (*Metadata) GetChangeByID

func (m *Metadata) GetChangeByID(id string) (Change, error)

GetChangeByID returns the pending Change with the given id.

func (*Metadata) GetChanges

func (m *Metadata) GetChanges(module string) []Change

GetChanges returns all pending Changes with a module matching the given module. If module is empty, returns all Changes.

func (*Metadata) RemoveChangeByID

func (m *Metadata) RemoveChangeByID(id string) error

RemoveChangeByID removes the Change with the specified id from the Metadata's Changes and also removes the Change from the .changes/next-release directory.

func (*Metadata) SaveChange

func (m *Metadata) SaveChange(c Change) error

SaveChange saves the given change to the .changes/next-release directory.

func (*Metadata) SaveEnclosure

func (m *Metadata) SaveEnclosure(enc VersionEnclosure) error

SaveEnclosure updates the Metadata's enclosure and updates the versions.json file.

func (*Metadata) UpdateChangeFromTemplate

func (m *Metadata) UpdateChangeFromTemplate(oldChange Change, template []byte) ([]Change, error)

UpdateChangeFromTemplate removes oldChange and creates a new Change from the given template.

type ModuleGraph

type ModuleGraph map[string][]string

ModuleGraph is a mapping between modules in a repository and a list of modules within the same repository that depend on that module.

type Release

type Release struct {
	ID            string
	SchemaVersion int
	VersionBumps  map[string]VersionBump
	Changes       []Change
}

Release represents a single SDK release, which contains all change metadata and their resulting version bumps.

func (*Release) AffectedModules

func (r *Release) AffectedModules() []string

AffectedModules returns a sorted list of all modules affected by this Release. A module is considered affected if it is the Module of one or more Changes in the Release.

func (*Release) AnnouncementsSection

func (r *Release) AnnouncementsSection() ([]string, error)

AnnouncementsSection returns a list of Changelog bullet entries that should be included under the Announcements header.

func (*Release) CoreSection

func (r *Release) CoreSection() ([]string, error)

CoreSection returns a list of Changelog bullet entries that should be included under the Core SDK header.

func (*Release) RenderChangelog

func (r *Release) RenderChangelog() (string, error)

RenderChangelog generates a top level CHANGELOG.md for the Release r.

func (*Release) RenderChangelogForModule

func (r *Release) RenderChangelogForModule(module string, topLevel bool) (string, error)

RenderChangelogForModule returns a new markdown section of a module's CHANGELOG based on the Changes in the Release.

func (*Release) ServiceSection

func (r *Release) ServiceSection() ([]string, error)

ServiceSection returns a list of Changelog bullet entries that should be included under the Service Clients header.

type Repository

type Repository struct {
	RootPath string    // RootPath is the path to the root of the repository.
	Metadata *Metadata // Metadata is the repository's .changes metadata.

	// Logf is a logging function. If nil, Repository will not log anything.
	Logf func(string, ...interface{})
	// contains filtered or unexported fields
}

Repository is a representation of a git repository containing multiple Go modules.

func NewRepository

func NewRepository(path string) (*Repository, error)

NewRepository loads the repository at the given path.

func (*Repository) DiscoverVersions

func (r *Repository) DiscoverVersions(selector VersionSelector) (VersionEnclosure, map[string]VersionBump, error)

DiscoverVersions creates a VersionEnclosure containing all Go modules in the Repository. The version of each module is determined by the provided VersionSelector.

func (*Repository) DoRelease

func (r *Repository) DoRelease(releaseID string, push, interactive bool) error

DoRelease runs the automated release process, consuming the given Repository's Metadata, updating module's go.mod files, creating a release JSON file, committing changes, tagging the repository, and pushing.

func (*Repository) InitializeVersions

func (r *Repository) InitializeVersions() error

InitializeVersions creates an initial versions.json enclosure in the Repository's .changes directory. The VersionEnclosure created by InitializeVersions will include all modules that have a tagged version in git and their corresponding versions.

func (*Repository) ModuleHashes

func (r *Repository) ModuleHashes(enc VersionEnclosure) (map[string]string, error)

ModuleHashes computes and returns a mapping between shortened module names and their corresponding Go module checksum. Since the version of a module is used to compute the Go checksum (i.e. two modules with the same directory contents have a different checksum if their versions are different), the versions of the given VersionEnclosure will be used for this purpose.

func (*Repository) Modules

func (r *Repository) Modules() ([]string, error)

Modules returns all Go modules under the given Repository. The list of module names returns are shortened to be relative to the root of the repository.

func (*Repository) Tidy

func (r *Repository) Tidy() error

Tidy runs go mod tidy on all modules in the repository.

func (*Repository) UpdateAllChangelogs

func (r *Repository) UpdateAllChangelogs(release *Release, pending bool) error

UpdateAllChangelogs generates changelog entries for both the top level CHANGELOG.md and per-module CHANGELOG.md files.

func (*Repository) UpdateChangelog

func (r *Repository) UpdateChangelog(release *Release, pending bool) error

UpdateChangelog generates a new CHANGELOG entry for the given release. If pending is true, the contents of CHANGELOG_PENDING.md will be replaced with the new entry. Otherwise, the entry will be prepended to CHANGELOG.md.

func (*Repository) UpdateModuleChangelog

func (r *Repository) UpdateModuleChangelog(release *Release, module string, pending bool) error

UpdateModuleChangelog generates a changelog entry for the specified module, updating the module's CHANGELOG.md file.

func (*Repository) UpdateVersionFiles

func (r *Repository) UpdateVersionFiles(enc VersionEnclosure) error

UpdateVersionFiles updates the version.go file with the version present in the VersionEnclosure enc. If version.go does not exist for a module, UpdateVersionFiles does not create one.

type Version

type Version struct {
	Module     string // Module is the repo relative module path of the Go module.
	ImportPath string // ImportPath is the full module import path.
	Version    string // Version is a valid Go module semantic version, which can potentially be a pseudo-version.
	ModuleHash string // ModuleHash is the Go module checksum of the the Version's module.
}

Version is the version of a Go module.

type VersionBump

type VersionBump struct {
	From string // From is the old module version
	To   string // To is the new module version
}

VersionBump describes a version increment to a module.

type VersionEnclosure

type VersionEnclosure struct {
	SchemaVersion  int                // SchemaVersion is the version of the library's types used to create this VersionEnclosure
	ModuleVersions map[string]Version // ModuleVersions is a mapping between shortened module paths and their corresponding Version.
	Packages       map[string]string  // Packages maps each package in the repo to the shortened module path that provides the package.
}

VersionEnclosure is a set of versions for Go modules in a given repository.

func (*VersionEnclosure) HashDiff

func (v *VersionEnclosure) HashDiff(hashes map[string]string) []string

HashDiff returns all modules whose hash provided in hashes differs from the has present in VersionEnclosure v. hashes is a map between shortened module names and their Go checksum.

type VersionIncrement

type VersionIncrement int

VersionIncrement describes how a Change should affect a module's version.

const (
	// NoBump indicates the module's version should not change.
	NoBump VersionIncrement = iota
	// PatchBump indicates the module's version should be incremented by a patch version bump.
	PatchBump
	// MinorBump indicates the module's version should be incremented by a minor version bump.
	MinorBump
	// MajorBump indicates the module's major version should be incremented from v0 to v1.
	MajorBump
	// NewModule indicates that a new modules has been discovered and will be assigned a default version.
	NewModule
)

func DevelopmentVersionSelector

func DevelopmentVersionSelector(r *Repository, module string) (string, VersionIncrement, error)

DevelopmentVersionSelector returns a commit hash based version if the module has associated pending Changes, otherwise returns the latest version from the repo's metadata version enclosure.

func ReleaseVersionSelector

func ReleaseVersionSelector(r *Repository, module string) (string, VersionIncrement, error)

ReleaseVersionSelector returns a version for the given module suitable for use during the release process. A version will be returned based upon what type of version bump the Change metadata for the given module requires. ReleaseVersionSelector will properly version modules that are not present in the versions.json file by checking git tags for an existing version, or by providing a default version suitable for the module's major version.

func TaggedVersionSelector

func TaggedVersionSelector(r *Repository, module string) (string, VersionIncrement, error)

TaggedVersionSelector returns the greatest version of module tagged in the git repository.

type VersionSelector

type VersionSelector func(r *Repository, module string) (string, VersionIncrement, error)

VersionSelector is a function that decides what version of a Go module should be passed to code generation.

func (*VersionSelector) Set

func (v *VersionSelector) Set(s string) error

Set parses the input s and correspondingly sets the appropriate VersionSelector.

func (*VersionSelector) String

func (v *VersionSelector) String() string

String returns an empty string to satisfy the flag.Value interface.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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