Skip to content

Commit

Permalink
Merge pull request #11 from cbegin/go-modules-support
Browse files Browse the repository at this point in the history
Go modules support
  • Loading branch information
cbegin authored Jun 25, 2021
2 parents f440487 + 9a7b619 commit f1e8758
Show file tree
Hide file tree
Showing 76 changed files with 539 additions and 381 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
vendor
graven
graven.exe
target
.DS_Store
temp
.vscode
.vscode
.idea
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .modules/github.com/fatih/color/@v/v1.7.0.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .modules/golang.org/x/mod/@v/v0.1.0.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
114 changes: 57 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Graven is a build management tool for Go projects. It takes light
cues from projects like Maven and Leiningen, but given Go's much
simpler environment and far different take on dependency management,
simpler environment and far different take on dependency management,
little is shared beyond the goals.

Want to know more? Read about the [Motivation for Graven](docs/motivation.md).
Expand All @@ -16,12 +16,12 @@ Want to know more? Read about the [Motivation for Graven](docs/motivation.md).
Graven currently requires the following tools to be on your path:

* `go` - the Go build tool, used to compile and test your application.
* `git` - used during the release process to validate the state of your repo,
* `git` - used during the release process to validate the state of your repo,
and tag your repo.

Of course if you don't plan to use the `release` command commands, you
can still use `graven` just for building, testing and packaging, and thus
would only require the `go` tool.
can still use `graven` just for building, testing and packaging, and thus
would only require the `go` tool.

## Installation

Expand All @@ -31,16 +31,16 @@ If you want to run the latest, you can just `go get` the tool.
go get -u github.com/cbegin/graven
```

For greater consistency and stability, you can run a specific relese version from:
For greater consistency and stability, you can run a specific relese version from:

* https://github.com/cbegin/graven/releases

## Workflow Example

Whether your starting an entirely new project, or working with existing source,
the workflow should be the same.
Whether your starting an entirely new project, or working with existing source,
the workflow should be the same.

Not all of these steps are always necessary. See below for a description of
Not all of these steps are always necessary. See below for a description of
implied workflow dependencies.

```bash
Expand All @@ -63,52 +63,52 @@ $ graven release
$ graven bump [major|minor|patch|QUALIFIER]
```

A typical development cycle looks like the following diagram. The `init` command
is run once per project, then `clean`, `build`, `test` and `package` are typically used
throughout the development cycle. Releases occur less frequently, and versions
A typical development cycle looks like the following diagram. The `init` command
is run once per project, then `clean`, `build`, `test` and `package` are typically used
throughout the development cycle. Releases occur less frequently, and versions
are bumped after the release.

The `freeze` and `unfreeze` commands are optional and on a completely
The `freeze` and `unfreeze` commands are optional and on a completely
independent flow, thus can be executed any time. They are discussed separately
here: [Freezing Dependencies](docs/freezing.md).

```
+----------+
> | build | \
/ +----------+ \
/ \
/ v
+----------+ +----------+ +----------+
| init |--->| clean | | test |
+----------+ +----------+ +----------+
^ /
\ /
\ +----------+ /
\| package |<-
+----------+ +----------+
| freeze | |
+----------+ v
| +----------+
| | release |
+-----v----+ +----------+
| unfreeze | |
+----------+ |
+-----v----+
| bump |
+----------+
+----------+
> | build | \
/ +----------+ \
/ \
/ v
+----------+ +----------+ +----------+
| init |--->| clean | | test |
+----------+ +----------+ +----------+
^ /
\ /
\ +----------+ /
\| package |<-
+----------+ +----------+
| freeze | |
+----------+ v
| +----------+
| | release |
+-----v----+ +----------+
| unfreeze | |
+----------+ |
+-----v----+
| bump |
+----------+
```

## project.yaml example

**Before you have flashbacks of Maven POMs...** note that this is probably the
**Before you have flashbacks of Maven POMs...** note that this is probably the
biggest project.yaml file you'll ever see. Most projects will have shorter,
simpler project.yaml files, and you'll rarely have to modify them once initialized.

The following documented structure (derived from this
very project) will help better understand what you can do with it.
very project) will help better understand what you can do with it.

```yaml
# Name, initially derived from parent directory.
# Name, initially derived from parent directory.
name: graven
# Version is typically managed with the graven bump command.
version: 0.6.6
Expand Down Expand Up @@ -158,11 +158,11 @@ artifacts:
env:
GOARCH: amd64
GOOS: windows
# Resources will be included in the packaged archive. Can be overridden at
# Resources will be included in the packaged archive. Can be overridden at
# artifact level.
resources:
- LICENSE
# Configures a repository for deployment.
# Configures a repository for deployment.
# Use graven repo --login --name [name] to authenticate
repositories:
github:
Expand All @@ -171,15 +171,15 @@ repositories:
artifact: graven
type: github
# Github repos only support releases
roles:
roles:
- release
artifactory:
url: http://localhost:8081/artifactory/releases/
group: cbegin
artifact: graven
type: maven
# Supports both releases and frozen dependencies
roles:
roles:
- release
- dependency
nexus:
Expand All @@ -188,7 +188,7 @@ repositories:
artifact: graven
type: maven
# Supports both releases and frozen dependencies
roles:
roles:
- release
- dependency
docker:
Expand All @@ -198,7 +198,7 @@ repositories:
type: docker
file: Dockerfile
# Docker repos only support releases
roles:
roles:
- release
```
## Name and Version
Expand All @@ -220,7 +220,7 @@ M.m.p-Q
* M: Major version. Incremented when the software changes significantly and typically in incompatible ways.
* m: Minor version. Incremented when new features are added, and backward compatibility is maintained.
* p: Patch version. Incremented when bugs are fixed. Backward compatibility is typically maintained, but is
* sometimes unavoidably broken.
* sometimes unavoidably broken.
* Q: Qualifier. This is used to qualify a pre-release build and is typically something like RC1, DEV or TEST.

## Artifacts
Expand All @@ -242,9 +242,9 @@ artifacts:
```
Each entity listed in the artifacts section represents a distributable artifact that consists of
one or more executables built from a number of packages compiled with specified flags and environment
variables. The resulting binaries are packaged up in an archive format (e.g. zip or tar.gz) and
variables. The resulting binaries are packaged up in an archive format (e.g. zip or tar.gz) and
additional resources can be included in the archive, specified in the resources array. Both resources
and environment variables can be specified at higher levels to avoid duplication. More specific
and environment variables can be specified at higher levels to avoid duplication. More specific
environment variables will override broader scoped ones. The classifier specifies a suffix for the
artifact that is usually used to indicate the target platform, but can be used to indicate anything
that differs among distributable artifacts.
Expand All @@ -259,35 +259,35 @@ repositories:
artifact: graven
type: maven
# Supports both releases and frozen dependencies
roles:
roles:
- release
- dependency
...
```
In the repositories section you can define both release and dependency repositories. A release repository
is where this project will be released. A dependency repository will be used to store frozen vendor
dependencies, so that you don't need to check in your vendor directories or .freezer directory.
is where this project will be released. A dependency repository will be used to store frozen vendor
dependencies, so that you don't need to check in your vendor directories or .modules directory.
Three repository types are currently supported: Github, Docker and Maven (including Nexus and Artifactory).
Three repository types are currently supported: Github, Docker and Maven (including Nexus and Artifactory).
Their capabilities and settings are summarized in the table below.
| Field | Github | Docker | Maven |
| Field | Github | Docker | Maven |
|-------|--------|--------|-------|
| type | github | docker | maven |
| url | Github API URL | Docker registry URL | Maven release URL |
| group | Owner | Repository | Group ID |
| artifact | Repo | Image Name | Artifact ID |
| group | Owner | Repository | Group ID |
| artifact | Repo | Image Name | Artifact ID |
| roles | release | release | release, dependency |
| file | unused | Dockerfile | unused |
### Authenticating
### Authenticating
In order to use a repository for releases or dependencies, you'll need to authenticate.
To do so, simply call `graven repo --login --name [repo-name]`. The credentials you enter
will be stored in your home directory in the .graven.yaml file. Your credentials will be
obfuscated to discourage over-the-shoulder or casual exposure. Even though a strong
encryption algorithm is used, the key is not secure and thus you should treat it as
obfuscated to discourage over-the-shoulder or casual exposure. Even though a strong
encryption algorithm is used, the key is not secure and thus you should treat it as
such.
7 changes: 5 additions & 2 deletions buildtool/go_buildtool.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ func (g *GoBuildTool) Build(outputPath string, project *domain.Project, artifact

fmt.Printf("Building %v/%v:%v\n", artifact.Classifier, target.Executable, project.Version)
var c *exec.Cmd
if target.Flags == "" {
if len(target.Flags) == 0 {
c = exec.Command("go", "build", "-o", filepath.Join(outputPath, target.Executable), target.Package)
} else {
c = exec.Command("go", "build", "-o", filepath.Join(outputPath, target.Executable), target.Flags, target.Package)
args := []string{"build", "-o", filepath.Join(outputPath, target.Executable)}
args = append(args, target.Flags...)
args = append(args, target.Package)
c = exec.Command("go", args...)
}
c.Stdout = os.Stdout
c.Stderr = os.Stderr
Expand Down
17 changes: 8 additions & 9 deletions commands/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"fmt"
"os"
"path"
"testing"
"path/filepath"
"testing"

"github.com/cbegin/graven/domain"
"github.com/cbegin/graven/test_fixtures/hello/version"
Expand Down Expand Up @@ -109,17 +109,17 @@ func TestShouldInitDirectory(t *testing.T) {
func TestShouldFreezeResources(t *testing.T) {
c := &cli.Context{}

_ = os.RemoveAll("../test_fixtures/hello/.freezer")
_ = os.RemoveAll("../test_fixtures/hello/.modules")

err := freeze(c)
assert.NoError(t, err)

assert.True(t, util.PathExists("../test_fixtures/hello/.freezer/jackfan.us.kg-davecgh-go-spew-spew-346938d642f2ec3594ed81d874461961cd0faa76.zip"))
assert.True(t, util.PathExists("../test_fixtures/hello/.freezer/jackfan.us.kg-fatih-color-62e9147c64a1ed519147b62a56a14e83e2be02c1.zip"))
assert.True(t, util.PathExists("../test_fixtures/hello/.freezer/jackfan.us.kg-mattn-go-colorable-941b50ebc6efddf4c41c8e4537a5f68a4e686b24.zip"))
assert.True(t, util.PathExists("../test_fixtures/hello/.freezer/jackfan.us.kg-mattn-go-isatty-fc9e8d8ef48496124e79ae0df75490096eccf6fe.zip"))
assert.True(t, util.PathExists("../test_fixtures/hello/.freezer/jackfan.us.kg-pmezard-go-difflib-difflib-792786c7400a136282c1664665ae0a8db921c6c2.zip"))
assert.True(t, util.PathExists("../test_fixtures/hello/.freezer/jackfan.us.kg-stretchr-testify-assert-f6abca593680b2315d2075e0f5e2a9751e3f431a.zip"))
assert.True(t, util.PathExists("../test_fixtures/hello/.modules/jackfan.us.kg-davecgh-go-spew-spew-346938d642f2ec3594ed81d874461961cd0faa76.zip"))
assert.True(t, util.PathExists("../test_fixtures/hello/.modules/jackfan.us.kg-fatih-color-62e9147c64a1ed519147b62a56a14e83e2be02c1.zip"))
assert.True(t, util.PathExists("../test_fixtures/hello/.modules/jackfan.us.kg-mattn-go-colorable-941b50ebc6efddf4c41c8e4537a5f68a4e686b24.zip"))
assert.True(t, util.PathExists("../test_fixtures/hello/.modules/jackfan.us.kg-mattn-go-isatty-fc9e8d8ef48496124e79ae0df75490096eccf6fe.zip"))
assert.True(t, util.PathExists("../test_fixtures/hello/.modules/jackfan.us.kg-pmezard-go-difflib-difflib-792786c7400a136282c1664665ae0a8db921c6c2.zip"))
assert.True(t, util.PathExists("../test_fixtures/hello/.modules/jackfan.us.kg-stretchr-testify-assert-f6abca593680b2315d2075e0f5e2a9751e3f431a.zip"))

}

Expand Down Expand Up @@ -217,4 +217,3 @@ func resetVersion() {
util.CopyFile("../test_fixtures/hello/project.fixture", "../test_fixtures/hello/project.yaml")
util.CopyFile("../test_fixtures/hello/version/version.fixture", "../test_fixtures/hello/version/version.go")
}

20 changes: 13 additions & 7 deletions commands/freeze.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ package commands
import (
"fmt"
"os"
"path/filepath"

"github.com/cbegin/graven/domain"
"github.com/cbegin/graven/repotool"
"github.com/cbegin/graven/util"
"github.com/cbegin/graven/vendortool"
"github.com/urfave/cli"
"github.com/cbegin/graven/repotool"
)

var supportedVendorTools = []vendortool.VendorTool{
&vendortool.ModVendorTool{},
&vendortool.GovendorVendorTool{},
&vendortool.GlideVendorTool{},
&vendortool.DepVendorTool{},
Expand All @@ -23,7 +25,6 @@ var FreezeCommand = cli.Command{
Action: freeze,
}


func selectVendorTool(project *domain.Project) (vendortool.VendorTool, error) {
for _, vt := range supportedVendorTools {
if vt.VendorFileExists(project) {
Expand All @@ -50,27 +51,32 @@ func freeze(c *cli.Context) error {
return err
}

freezerPath := project.ProjectPath(".freezer")
freezerPath := project.ProjectPath(".modules")

if _, err := os.Stat(freezerPath); !os.IsNotExist(err) {
if err := os.RemoveAll(freezerPath); err != nil {
return fmt.Errorf("Could not clean .freezer: %v", err)
return fmt.Errorf("Could not clean .modules: %v", err)
}
}

if err := os.Mkdir(freezerPath, 0755); err != nil {
return fmt.Errorf("Could not make .freezer: %v", err)
return fmt.Errorf("Could not make .modules: %v", err)
}

for _, p := range vendorTool.Dependencies() {
sourcePath := project.ProjectPath("vendor", p.PackagePath())
targetFile := project.ProjectPath(".freezer", p.ArchiveFileName())
targetFile := project.ProjectPath(".modules", p.ArchiveFileName())

if _, err := os.Stat(sourcePath); os.IsNotExist(err) {
fmt.Printf("MISSING dependency %v\n", p.PackagePath())
fmt.Printf("Skipping %v wasn't found in vendor folder (may be an empty dependency).\n", p.PackagePath())
continue
}

dirString, _ := filepath.Split(targetFile)
if dirString != "" {
os.MkdirAll(dirString, 0755)
}

err = util.ZipDir(sourcePath, targetFile, false)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion commands/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func initialize(c *cli.Context) error {
targets = append(targets, domain.Target{
Executable: fmt.Sprintf("%v%v", executable, template.Extension),
Package: pkg,
Flags: "",
Flags: []string{},
})
}
}
Expand Down
Loading

0 comments on commit f1e8758

Please sign in to comment.