Verified Commit 4d6bb1f7 authored by Che's avatar Che
Browse files

Prepare v0.1.0

parent 8f560974
Pipeline #368 passed with stage
in 4 minutes and 45 seconds
# v0.1.0
- Add skeleton files
- Add go.mod
- Add Makefile
- Add CI definitions
- Add CHANGELOG
- Create the "Go project layout" and move code accordingly
- [cmd] Fix the selected project path by removing the go run workaround
- [cmd] Add -v parameter to enable verbose output
- [proj] Add function Analyze which does the heavy-lifting and glues together all needed steps.
- [proj] Remove the raw go.mod output section
- [proj] Rewrite the output to a verbose and a default stream
- [proj] Rename function setProject to resolveProjectPath
- [proj] Split function doSomethingWonderfulWithTheseBytes to parseRaw which parses the raw go.mod file, filling the properties of the mod struct and prettyPrint which prints a representation of the module dependencies for use in terminal environments
- Add README
- Add LICENSE
This diff is collapsed.
......@@ -3,7 +3,7 @@ GOLANGCI-LINT := $(BIN_DIR)/golangci-lint
PKGS := $(shell go list ./...)
VERSION ?= $(shell git describe --always --dirty)
BUILDTAG = $(shell echo "$$(date +'%y.%-m.%-d')-$$(printf %x $$(($$(date -d now +'%s') - $$(date -d $$(date +'%F') +'%s'))))")
BUILDPKG := "lab.madbox.synology.me/gophers/goamod"
BUILDPKG := "lab.madbox.synology.me/gophers/goamod/cmd/goamod"
BINARY := goamod
.PHONY: test
......
WIP
# goamod
[![pipeline status](https://lab.madbox.synology.me/gophers/goamod/badges/master/pipeline.svg)](https://lab.madbox.synology.me/gophers/goamod/pipelines)
[![coverage report](https://lab.madbox.synology.me/gophers/goamod/badges/master/coverage.svg)](https://lab.madbox.synology.me/gophers/goamod)
Go analyze module
## Download
If you would like to give goamod a try but don't want to build the project yourself, you can find prebuilt binaries available for download on the [Releases](https://lab.madbox.synology.me/gophers/goamod/releases) page.
In case you would like to know how these binaries are created, have a look at the: [.gitlab-ci.yml](.gitlab-ci.yml).
## Usage
```bash
goamod [-h | --help] | [-v] [--] [<project>]
```
* `<project>`: The project name to check
See `goamod -h` for more information about the parameters.
## Examples
```bash
# TODO Add examples
```
## License
The GNU General Public License v3.0 (GPLv3) - see [`LICENSE`](LICENSE) for more details
// goamod - Go analyze module
package main
import (
"flag"
"fmt"
"runtime"
"lab.madbox.synology.me/gophers/clog"
"lab.madbox.synology.me/gophers/goamod/internal/pkg/proj"
)
var (
build = "-x-"
version = "latest"
)
func main() {
// recursive := flag.Bool("R", false, "search recursively from given path")
flVerbose := flag.Bool("v", false, "enable verbose output")
flag.Parse()
printStartup()
if *flVerbose {
clog.EnableVerbosity()
clog.Verbln("[verb] verbose output enabled.")
}
proj.Analyze()
}
// printStartup outputs the version and build tags.
func printStartup() {
fmt.Printf("[*] Initializing goamod %s Build %s (%s %s-%s %s)\n",
version,
build,
runtime.Version(),
runtime.GOOS,
runtime.GOARCH,
runtime.Compiler)
}
// goamod - Go analyze module
package main
package proj
import (
"bufio"
"bytes"
"flag"
"fmt"
gobuild "go/build"
"go/build"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"lab.madbox.synology.me/gophers/clog"
)
// All "real" code for the moment
type dep struct {
name string
tag string
......@@ -28,48 +29,47 @@ type mod struct {
rawMod []byte
}
var (
build = "-x-"
version = "latest"
)
func main() {
// recursive := flag.Bool("R", false, "search recursively from given path")
// flag.Parse()
printStartup()
project := setProject()
fmt.Println("project:", project)
// Analyze does the heavy-lifting and glues together all needed steps.
func Analyze() {
var m mod
project := resolveProjectPath()
modPath := filepath.Join(project, "go.mod")
clog.Verbf("[verb] initial try: %s ... ", modPath)
file, err := ioutil.ReadFile(modPath)
if err != nil {
clog.Verbln("failed.")
if os.IsNotExist(err) {
// Check wether we can find the project using the GOPATH
modPath = filepath.Join(gobuild.Default.GOPATH, "src", project, "go.mod")
fmt.Println("NEW MODPATH:", modPath)
modPath = filepath.Join(build.Default.GOPATH, "src", project, "go.mod")
clog.Verbf("[verb] retry based on GOPATH: %s ... ", modPath)
file, err = ioutil.ReadFile(modPath)
if err != nil {
clog.Verbln("failed.")
fmt.Println("there are no go module definitions in", project)
os.Exit(1)
}
m.isInGOPATH = true
}
if !m.isInGOPATH {
clog.Verbln("failed.")
fmt.Println("coult not read go.mod file:", err)
os.Exit(1)
}
clog.Verbln("succeeded!")
} else {
clog.Verbln("succeeded!")
}
m.rawMod = file
doSomethingWonderfulWithTheseBytes(m)
m.parseRaw()
prettyPrint(m)
}
func doSomethingWonderfulWithTheseBytes(m mod) {
fmt.Println("[proto] --- start raw ---\n" + string(m.rawMod) + "--- end raw ---")
// parseRaw parses the raw go.mod file, filling the properties of the mod struct.
func (m *mod) parseRaw() {
clog.Verbln("[verb] line parsing results:")
scanner := bufio.NewScanner(bytes.NewReader(m.rawMod))
scanner.Split(bufio.ScanLines)
var (
......@@ -116,36 +116,51 @@ func doSomethingWonderfulWithTheseBytes(m mod) {
}
}
}
fmt.Println(i, line)
clog.Verbln("[verb]", i, line)
}
fmt.Print(">>> MAIN MODULE: ", m.mainModule)
clog.Verbf("[verb] m: %+v\n", m)
}
// prettyPrint prints a representation of the module dependencies for use in
// terminal environments.
func prettyPrint(m mod) {
var mainPref string
hasDeps := len(m.deps) > 0
if hasDeps {
mainPref = "╥"
} else {
mainPref = "─"
}
fmt.Print(mainPref, " ", m.mainModule)
if m.isInGOPATH {
fmt.Print(" (in GOPATH)")
}
fmt.Println("\n>>> USED GO:", m.usedGo)
if len(m.deps) > 0 {
fmt.Println("Dependencies:")
for _, d := range m.deps {
fmt.Println(">\t", d.name, "tag:", d.tag)
}
} else {
fmt.Println("No dependencies found!")
if m.usedGo != "" {
fmt.Print(", written with: Go v", m.usedGo)
}
fmt.Println()
clog.Preff("proto", "m: %+v", m)
}
func setProject() (project string) {
if len(os.Args) != 0 {
if strings.HasPrefix(os.Args[0], "/tmp/go-build") {
fmt.Println("[proto] assuming go run, skipping first arg")
if len(os.Args) > 1 {
project = os.Args[1]
if hasDeps {
max := len(m.deps) - 1
for i, d := range m.deps {
if i == max {
fmt.Println("╙─>", d.name, "tag:", d.tag)
} else {
fmt.Println("╟─>", d.name, "tag:", d.tag)
}
} else {
project = os.Args[0]
}
}
}
// resolveProjectPath returns the initial path to try to find the go.mod file
// in. It uses the first argument (if given) and falls back to the current
// working directory.
func resolveProjectPath() (project string) {
if len(flag.Args()) > 0 {
project = flag.Arg(0)
}
if project == "" {
wd, err := os.Getwd()
......@@ -156,14 +171,3 @@ func setProject() (project string) {
return project
}
// printStartup outputs the version and build tags.
func printStartup() {
fmt.Printf("[*] Initializing goamod %s Build %s (%s %s-%s %s)\n",
version,
build,
runtime.Version(),
runtime.GOOS,
runtime.GOARCH,
runtime.Compiler)
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment