Skip to content

Commit 3bd15f4

Browse files
committed
Initial release
1 parent 66f454f commit 3bd15f4

File tree

11 files changed

+324
-2
lines changed

11 files changed

+324
-2
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2019 Plex Systems
3+
Copyright (c) 2019 Plex Systems, Inc.
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,24 @@
11
# pacmod
2-
Package your Go modules
2+
3+
![logo](logo/pacmod_logo.png)
4+
5+
[![GoDoc](https://godoc.org/github.com/plexsystems/pacmod?status.svg)](https://godoc.org/github.com/plexsystems/pacmod)
6+
[![Go Report Card](https://goreportcard.com/badge/github.com/plexsystems/pacmod)](https://goreportcard.com/report/github.com/plexsystems/pacmod)
7+
8+
Pacmod is a small tool that can be used to package up your Go modules for distribution. This will be typically used for pushing artifacts to a Go module store such as [Athens](https://github.com/gomods/athens).
9+
10+
## Installation
11+
12+
`go get github.com/plexsystems/pacmod/cmd/pacmod`
13+
14+
## Usage
15+
16+
Run the `pack` command in the directory containing your `go.mod`. For example:
17+
18+
`pacmod pack mymodule v1.0.0`
19+
20+
This will result in the following files:
21+
22+
- `go.mod` - The current mod file when the `pack` command was executed
23+
- `v1.0.0.info` - The info file containing the module version and timestamp
24+
- `v1.0.0.zip` - An archive containing the Go module

cmd/pacmod/main.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package main
2+
3+
import (
4+
"github.com/plexsystems/pacmod/internal/commands"
5+
"os"
6+
)
7+
8+
func main() {
9+
err := commands.NewDefaultCommand().Execute()
10+
if err != nil {
11+
os.Exit(1)
12+
}
13+
}

go.mod

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module github.com/plexsystems/pacmod
2+
3+
go 1.12
4+
5+
require (
6+
github.com/hugocarreira/go-decent-copy v0.0.0-20181018112419-9f482c9a2943
7+
github.com/spf13/cobra v0.0.5
8+
)

go.sum

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
2+
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
3+
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
4+
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
5+
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
6+
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
7+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8+
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
9+
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
10+
github.com/hugocarreira/go-decent-copy v0.0.0-20181018112419-9f482c9a2943 h1:uuMUrGtG7EelzCDzq7VNfexyMnbWJzHK+lA2yEHfTk8=
11+
github.com/hugocarreira/go-decent-copy v0.0.0-20181018112419-9f482c9a2943/go.mod h1:LGbo2Li3Ub3ZNYZHIUFZ4qfwsFNvOI+If5lpEQNYJIU=
12+
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
13+
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
14+
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
15+
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
16+
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
17+
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
18+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
19+
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
20+
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
21+
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
22+
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
23+
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
24+
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
25+
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
26+
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
27+
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
28+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
29+
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
30+
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
31+
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
32+
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
33+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
34+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
35+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

internal/commands/default.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package commands
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
)
6+
7+
// NewDefaultCommand creates the default command
8+
func NewDefaultCommand() *cobra.Command {
9+
10+
cmd := cobra.Command{
11+
Use: "pacmod <subcommand>",
12+
Short: "Command line tool to assist with packaging Go modules",
13+
}
14+
15+
cmd.AddCommand(newPackCommand())
16+
17+
return &cmd
18+
}

internal/commands/pack.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package commands
2+
3+
import (
4+
"github.com/hugocarreira/go-decent-copy"
5+
"github.com/plexsystems/pacmod/pkg/pack"
6+
"github.com/spf13/cobra"
7+
"log"
8+
"os"
9+
"path/filepath"
10+
)
11+
12+
func newPackCommand() *cobra.Command {
13+
cmd := cobra.Command{
14+
Use: "pack <module> <version>",
15+
Short: "Package your Go module",
16+
Args: cobra.MinimumNArgs(2),
17+
18+
RunE: func(cmd *cobra.Command, args []string) error {
19+
return runPackCommand(args)
20+
},
21+
}
22+
23+
return &cmd
24+
}
25+
26+
func runPackCommand(args []string) error {
27+
path, err := os.Getwd()
28+
if err != nil {
29+
return err
30+
}
31+
32+
name := args[0]
33+
version := args[1]
34+
35+
module := pack.Module{
36+
Path: path,
37+
Name: name,
38+
Version: version,
39+
}
40+
41+
outputDirectory := filepath.Join(module.Path, module.Version)
42+
err = os.Mkdir(outputDirectory, 0777)
43+
if err != nil {
44+
return err
45+
}
46+
47+
log.Printf("Packing module %s into output directory %s", module.Name, outputDirectory)
48+
49+
log.Println("Creating archive...")
50+
err = module.ZipModule(outputDirectory)
51+
if err != nil {
52+
return err
53+
}
54+
55+
log.Println("Creating info...")
56+
info := pack.Info{
57+
Version: version,
58+
}
59+
err = info.CreateInfo(outputDirectory)
60+
if err != nil {
61+
return err
62+
}
63+
64+
log.Println("Copying mod...")
65+
return copyModuleFile(module.Path, outputDirectory)
66+
}
67+
68+
func copyModuleFile(source string, destination string) error {
69+
sourceModFile := filepath.Join(source, "go.mod")
70+
destinationModFile := filepath.Join(destination, "go.mod")
71+
72+
err := decentcopy.Copy(sourceModFile, destinationModFile)
73+
if err != nil {
74+
return err
75+
}
76+
77+
return nil
78+
}

logo/pacmod_logo.png

16.7 KB
Loading

pkg/pack/archive.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package pack
2+
3+
import (
4+
"archive/zip"
5+
"fmt"
6+
"io"
7+
"os"
8+
"path/filepath"
9+
"strings"
10+
)
11+
12+
// Module represents a Go module
13+
type Module struct {
14+
Path string
15+
Name string
16+
Version string
17+
}
18+
19+
// ZipModule zips the module and outputs the result to the specified output path
20+
func (m *Module) ZipModule(outPath string) error {
21+
zipOutputPath := filepath.Join(outPath, m.Version+".zip")
22+
23+
zipFile, err := os.Create(zipOutputPath)
24+
if err != nil {
25+
return err
26+
}
27+
defer zipFile.Close()
28+
29+
zipWriter := zip.NewWriter(zipFile)
30+
31+
err = filepath.Walk(m.Path, func(currentFilePath string, fileInfo os.FileInfo, err error) error {
32+
33+
if err != nil {
34+
return err
35+
}
36+
37+
if fileInfo.IsDir() && fileInfo.Name() == ".git" {
38+
return filepath.SkipDir
39+
}
40+
41+
if fileInfo.IsDir() || filepath.Ext(currentFilePath) == ".zip" {
42+
return nil
43+
}
44+
45+
file, err := os.Open(currentFilePath)
46+
if err != nil {
47+
return err
48+
}
49+
defer file.Close()
50+
51+
zipPath := m.getZipPath(currentFilePath)
52+
zipFileWriter, err := zipWriter.Create(zipPath)
53+
if err != nil {
54+
return err
55+
}
56+
57+
_, err = io.Copy(zipFileWriter, file)
58+
return err
59+
})
60+
61+
if err != nil {
62+
return err
63+
}
64+
65+
return zipWriter.Close()
66+
}
67+
68+
func (m *Module) getZipPath(currentFilePath string) string {
69+
fileName := strings.TrimPrefix(currentFilePath, m.Path)
70+
moduleName := fmt.Sprintf("%s@%s", m.Name, m.Version)
71+
72+
return filepath.Join(moduleName, fileName)
73+
}

pkg/pack/archive_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package pack
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestGetZipPath(t *testing.T) {
8+
module := Module{
9+
Path: "/linux",
10+
Name: "modulename",
11+
Version: "v1.0.0",
12+
}
13+
14+
actual := module.getZipPath("/linux/file.go")
15+
expected := "[email protected]\\file.go"
16+
17+
if actual != expected {
18+
t.Errorf("Linux: expected %v, got %v", expected, actual)
19+
}
20+
21+
module = Module{
22+
Path: "C:\\windows",
23+
Name: "modulename",
24+
Version: "v1.0.0",
25+
}
26+
27+
actual = module.getZipPath("C:\\windows\\file.go")
28+
expected = "[email protected]\\file.go"
29+
30+
if actual != expected {
31+
t.Errorf("Windows expected %v, got %v", expected, actual)
32+
}
33+
}

0 commit comments

Comments
 (0)