Code Monkey home page Code Monkey logo

mage's People

Contributors

aknuds1 avatar captjt avatar chilts avatar darkowlzz avatar ihgann avatar interlock avatar jen20 avatar jonasrmichel avatar justinclift avatar marcel avatar mathew-fleisch avatar mbialon avatar mirogta avatar natefinch avatar nilslice avatar ntrrg avatar omarkohl avatar perj avatar perrito666 avatar philoserf avatar pmcatominey avatar ryanfaerman avatar siddhesh avatar srp avatar turutcrane avatar viktorvoltaire avatar vrischmann avatar webrat avatar williamroynelson avatar zbindenren avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mage's Issues

Proposal: Add sequential deps helper

I'd like to see a helper function in mg that could run deps sequentially without parallelism. Some of the deps in Hugo are memory intensive, and I'd like to just run them sequentially.

We can already do this now with multiple if err := A(); err != nil {} blocks (or create my own helper function), but a helper function in mg would be convenient.

sh execution in different path or directory

The Go project I'm working on has a sub-project in JavaScript that has its own build tools. To run them, I need to change directory. The current build script I'm using is:

func BuildAssets() {
	cmd := exec.Command("yarn", "install")
	cmd.Dir = "front"
	cmd.Stdout = os.Stdout
	cmd.Run()
}

Is there any way to use the much less cumbersome sh.RunV() and related methods in a different path?

The obvious solution of adding cd front && yarn to the command doesn't work as it searches for the executable in the PATH:

Error: failed to run "cd front && yarm install: exec: "cd front && yarm": executable file not found in $PATH"

Using os.Chdir should also work, but is quite awkward when everything else expects to be run from the base path. Perhaps this is the only way?

mg.Deps and anonymous functions

mg.Deps() doesn't seem to handle anonymous functions properly. Given a loop like below:

func Demo() error {
	cmds := []interface{}{}
	for i:=0; i < 10; i++ {
		k := i
		f := func() error {
			fmt.Println(k)
			return nil
		}
		cmds = append(cmds, f)
	}
	mg.Deps(cmds...)
	return nil
}

I get the following output:

Running target: Demo
0

I ran into this while generating dynamic build targets for a multi-platform build (to give a use case).

import targets from another magefile

If you have common targets you want to use for multiple magefiles, right now there's no way to share the targets.

A . import statement could be a good implementation. It's pretty obvious and fairly straightforward to implement.

import . "example.com/my-mage/std-magefile"

Support for Aliases

Let users define a list of aliases for targets:

var Aliases = map[string]interface{}{
    "example-foo" : ExampleFoo,
}

Alias names would be compared vs. the lowercased target name specified on the command line. The code would check for alias matches first, and if found, use reflection to get the function name specified, and replace the CLI target name with the reflection generated name.

run multiple targets?

might be nice to do mage foo,bar to run both foo and bar. However, this may have adverse impacts on other features, so it requires some thought. Input herre is welcome

Auto-glob in sh.Exec

Just as we auto-expand env vars, it would be nice to expand glob (*.foo) into the correct filenames.

Also possibly add a config variable var AutoGlob=false

Getting random crashes on CircleCI

I've had several issues, so I'm not sure what's what anymore, but I thought I should raise this issue to get a complete picture.

This is with the latest go get mage, but I saw this also with the 1.0 version. It does not happen all the time, so may be a memory thing ... But I have never seen this with make doing the exact same thing.

#!/bin/bash -eo pipefail
git clone [email protected]:gohugoio/hugoDocs.git
cd hugo
mage vendor
mage check
Cloning into 'hugoDocs'...
remote: Counting objects: 42080, done.        
remote: Compressing objects: 100% (143/143), done.        
remote: Total 42080 (delta 115), reused 113 (delta 62), pack-reused 41873        
Receiving objects: 100% (42080/42080), 82.94 MiB | 57.03 MiB/s, done.
Resolving deltas: 100% (29294/29294), done.
go build testmain: /usr/local/go/pkg/tool/linux_amd64/link: signal: killed
go build testmain: /usr/local/go/pkg/tool/linux_amd64/link: signal: killed
go build testmain: /usr/local/go/pkg/tool/linux_amd64/link: signal: killed
go build testmain: /usr/local/go/pkg/tool/linux_amd64/link: signal: killed
go build testmain: /usr/local/go/pkg/tool/linux_amd64/link: signal: killed
go build testmain: /usr/local/go/pkg/tool/linux_amd64/link: signal: killed
go build testmain: /usr/local/go/pkg/tool/linux_amd64/link: signal: killed
go build testmain: /usr/local/go/pkg/tool/linux_amd64/link: signal: killed
go build testmain: /usr/local/go/pkg/tool/linux_amd64/link: signal: killed
Error: exit status 1
Error: exit status 1
Error: running "govendor test +local" failed with exit code 2
running "govendor test -race +local" failed with exit code 2
Exited with code 2

configure sh options

Auto-expand environment variables in sh should be configurable.. on or off for everything, or include/exclude command names. Include/exclude would be a list of command names to either turn expanding environment variables on or off for. For example, "don't expand environment variables when I run the 'foo' command.". Thus if you have a command that expects an argument with a $ in it, you can pass that to it without it getting auto-expanded.

All of the above also for the upcoming auto-glob in #55

API:

func CfgExpandEnv(m CfgMode, cmds ...string) {}
func CfgGlobFIles(m CfgMode, cmds ....string) {}

var CfgMode int
const (
    OnForAll CfgMode = iota // enable the config for all commands (default)
    OffForAll               // disable the config for all commands
    IncludeCmds             // disable the config except for the given commands
    ExcludeCmds             // enable the config except for the given commands
)

If you pass a list of commands for OnForAll or OffForAll, we panic. If you don't pass a list of commands for IncludeCmds or ExcludeCmds, we panics.

This would generally be used in an init function so that it takes effect for all targets... but nothing forces you to do it that way.

document best practices

Examples of dependencies, usage of sh and mg, how to structure files for readability, etc.

The description is misleading.

"a Makefile replacement for go" gives the impression that this is a tool for building Go code. "A tool for writing Makefiles using Go" might be better.

Camel case the commands in listing

I get that this is very subjective, but this is from the Hugo build:

โ–ถ mage
  check            Run tests and linters
  checkvendor      Verify that vendored packages match git HEAD
  docker           Build hugo Docker container
  fmt              Run gofmt linter
  hugo             Build hugo binary
  hugonogitinfo    Build hugo without git info
  hugorace         Build hugo binary with race detector enabled
  install          Install hugo binary
  lint             Run golint linter
  test             Run tests
  test386          Run tests in 32-bit mode
  testcoverhtml    Generate test coverage report
  testrace         Run tests with race detector
  vendor           Install govendor and sync Hugo's vendored dependencies
  vet              Run go vet linter

Which is mostly beautiful. But the all lower-case command names looks "wrong" in my eyes. I would much prefer that it followed the original case of the method, but with a lowercase first letter, so hugoRace, testCoverHTMLetc. I would still expect the all lowercase variant to work.

Feature Request : Prefix returned errors with something such as `Error:`

In the video demo your example of return errors.New("boo!") just prints out "boo!" and whilst the echo $? shows a non-zero exit code, there is nothing on the screen to visually show the command failed.

I know some people have prompts which display something when the previous command failed, however I think it would be nice to show it visually too. Nothing too big, but just big enough.

For example:

$ mage install
Error: boo!

As a comparison let's just look at what make does. We don't have to copy this nor am I holding it up as the ideal, but just a curiosity. For example, if my target just tried to cat a non-existant file:

$ make target
cat hello.go
cat: hello.go: No such file or directory
Makefile:2: recipe for target 'target' failed
make: *** [build] Error 1

Which (I think) is made up of the command, stderr from the command and then output from make itself. I'm happy to keep it real simple as above and just prefix the output with Error:.

(Note: I think we could or should also do the same for functions that don't return errors, so I'm not sure how we'd do that - perhaps if they wrote something on stderr? This comment is a non-goal of this ticket and perhaps another ticket should be opened, however it's pertinent to raise this here in case it impacts what we do here.)

Release binary does not work in a Docker container

I may investigate this later, but thought I should post this in case someone else has any tips:

Resolving deltas: 100% (28797/28797), done.
Error: magefile.go:6:2: could not import bytes (cannot find package "bytes" in any of:
	/go/src/github.com/gohugoio/hugo/vendor/bytes (vendor tree)
	/Users/finchnat/src/github.com/golang/go/src/bytes (from $GOROOT)
	/go/src/bytes (from $GOPATH))

I use the Linux binary from the v1 release.

Cannot import `mg` for a mage file

Problem: When running mage with the included example code below the following error is reported.

make.go:8:2: could not import github.com/magefile/mage/mg (can't find import: github.com/magefile/mage/mg)

Expected: mage -l to generate and build with the example code, allowing the use of mg for mg.Dep(...).

// +build mage

package main

import (
	"fmt"

	"github.com/magefile/mage/mg"
)

func Build() {
	mg.Deps(Clean)
	fmt.Println("Building")
}

func Clean() {
	fmt.Println("Cleaning")
}

Results of go env

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/interlock/src/go"
GORACE=""
GOROOT="/home/interlock/.asdf/installs/golang/1.8.3/go"
GOTOOLDIR="/home/interlock/.asdf/installs/golang/1.8.3/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build518538770=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"```

Unable to install via README.md instructions

Running the recommended commands from the README.md:

go get -u -d github.com/magefile/mage
cd $GOPATH/src/github.com/magefile/mage
go run bootstrap.go

Getting:

Running target: Build
exec: git rev-parse --short HEAD
exec: git describe --tags
exec: go install -a -ldflags=-X "github.com/magefile/mage/mage.timestamp=2017-10-27T09:39:17-05:00" -X "github.com/magefile/mage/mage.commitHash=accd8ef" -X "github.com/magefile/mage/mage.gitTag=v2.0.1-3-gaccd8ef
" github.com/magefile/mage
go install runtime/internal/sys: open /usr/local/go/pkg/darwin_amd64/runtime/internal/sys.a: permission denied
Error: running "go install -a -ldflags=-X "github.com/magefile/mage/mage.timestamp=2017-10-27T09:39:17-05:00" -X "github.com/magefile/mage/mage.commitHash=accd8ef" -X "github.com/magefile/mage/mage.gitTag=v2.0.1-3-gaccd8ef
" github.com/magefile/mage" failed with exit code 1
exit status 1

macOS 10.12.6

$ go version
go version go1.9.2 darwin/amd64
$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/jake/Projects/Labs/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/h2/whwtkkx168n8333397n69m2r0000gn/T/go-build684654678=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"

Quotes in comments cause an error

Having a magefile like this:

// Creates "something"
func Create() error {
  return nil
}

Will result in an error. It looks like the quotes aren't being escaped when I check out the intermediate file. Probably a trivial fix but posting here before doing anything to verify it should be fixed.

Librarify Mage

Some of the tests are forced to use go run to run full-stack tests for go. It would be a lot easier and better if we could just run the mage main function on a specific directory. This should be pretty trivial.

This will also open up the ability to have one magefile run a target in another magefile (outside the current directory).

Pass in parameters?

Is there no way to pass in variables to a target? I see the docs state a function with no args.

Something like:

mage buildDocker -imageName myimage -tag 1.0

I'm really new to golang so maybe there's some other way to do this without mage needing to care, but seems like it would be hard to know what parameters a target needs without digging into the code implementation vs just looking a function definition.

Returning dynamic functions

func ensureGoTool(tool, pkg string) func() error {
	return func() error {
		_, err := exec.LookPath(tool)
		if err != nil {
			fmt.Printf("couldn't find tool %s, attempting to download\n", tool)
			if _, err := sh.Exec(nil, os.Stdout, os.Stderr, "go", "get", "-u", pkg); err != nil {
				return err
			}
			_, err := exec.LookPath(tool)
			if err != nil {
				return fmt.Errorf("couldn't download tool %s from %s", tool, pkg)
			}
		}
		return nil
	}
}
func Vendor() error {
	mg.Deps(ensureGoTool("vndr", "github.com/LK4D4/vndr"))
	return sh.Run("vndr")
}
func Lint() error {
	mg.Deps(ensureGoTool("gometalinter", "github.com/alecthomas/gometalinter"))
	return sh.Run("gometalinter", "--config", ".gometalinter.json", "./pkg/...")
}
func Do() error {
	mg.Deps(Vendor, Lint)
	return nil
}

The problem is that with mage do, ensureGoTool only get's run once. There is probably some optimization to prevent similar tasks from being called multiple times. How do I disable it in this case?

File Source/Target specifications

You should be able to declare that a target produces one or more files from one or more files. If the source files have been modified more recently than the target files (or if the target files don't exist), then run the target, otherwise skip it, assuming it's done.

Release new version of mage

Hi,

latest release 2.0.1 doesn't support alias. If I use deps as dependency management tool, only 2.0.1 version will be fetched.

My question: can we release a new version of mage?

Running eval in sh.Run()

Migrating my personal project to mage currently and I tried to run eval in sh.Run(). The program outputted
Error: failed to run "eval (docker-machine env cryptotraderbot): exec: "eval": executable file not found in $PATH"

Is there any way to do this with mage or is it currently not supported ?

Relevant code:

if err := sh.Run("eval", "$(docker-machine", "env", "cryptotraderbot)"); err != nil {
     return err
}

add -debug flag & more logging to mage itself

Currently there's very little information about what went wrong if you mess up your mage file or mage otherwise doesn't do what you want. It should be pretty easy to add a -debug flag to mage itself to enable verbose logging of code parsing and generation.

mage -init

create a new flag -init that creates a new default magefile.

build mage with mage

we should have a magefile to build all release targets

For now, we don't need a general build target, but it might be worth making one just so people can see how it works.

Feature Request: automatic insertion of a job-scoped context

This would allow for users to write functions like:

func Build(ctx context.Context) error {
  cmd := exec.CommandContext(ctx, "/usr/local/go/bin/go", "build", "./cmd/...")
  cmd.Stdout = os.Stdout
  cmd.Stderr = os.Stderr
  err := cmd.Run()
}

And then if the user hits control-c to terminate the mage process, the context will instantly cancel and cause the process started by the Build function to be killed.

Mage itself would need to start and manage these contexts.

It would be nice to also have a command line flag -t that would set a timeout on these contexts.

Logging wrappers?

What's the normally intended use of stdout/stderr in mage files for user functions? I notice mage has no logging wrappers for adding build specific information, so I'm not super clear on the design intent here?

Broken mage

This commit 0c1c4dc

Seem to have broken Hugo (cannot find any of the targets)

Verbose output shown in init function

func init() {
	if exe := os.Getenv("GOEXE"); exe != "" {
		goexe = exe
	}

	// Update the GOARCH.
	if output, err := sh.Output(goexe, "env", "GOARCH"); err == nil {
		goarch = output
	} else {
		panic(fmt.Sprintf("couldn't get GOARCH: %v", err))
	}
}
> mage
2018/01/26 21:55:25 exec: go env GOARCH

I expected that output only when invoking mage -v.

When the actual targets get run, the sh commands are properly muted.

Distribute binaries in archived ("standardized") form

Your release binary distro does not resemble "anything else" ... and I would suggest doing something more standardize so people can use the bash scripts they already set up for similar stuff. Package the binary mage (i.e. no need for renaming on extract) in a tar file with the execution permissions set. I suspect most Windows AV scanners will jump at the exe downloads etc. Also, I suspect sha 256 hashes are more common.

I started to update my scripts, and what I thought should be a 5 minute task is now turning into real work.

Goreleaser does this right.

auto-args for targets?

It wouldn't be too hard to auto-generate a CLI for each target so the user could pass in positional args or flags per arg.

e.g.

func Build(OS string, ARCH string) error {
     // build with GOOS and GOARCH
}

$ mage build -os darwin -arch amd64
building with GOOS=darwin GOARCH=amd64

The mage released binary isn't self contained

Resolving deltas: 100% (29367/29367), done.
Error: failed to check types in directory: magefile.go:14:2: could not import github.com/magefile/mage/mg (cannot find package "github.com/magefile/mage/mg" in any of:
	/go/src/github.com/gohugoio/hugo/vendor/github.com/magefile/mage/mg (vendor tree)
	/usr/local/go/src/github.com/magefile/mage/mg (from $GOROOT)
	/go/src/github.com/magefile/mage/mg (from $GOPATH))
Exited with code 1

And while I do understand the error above and know the workaround for it, I did expect this to just work without any "go getting". I guess the released binary is just for bootstrapping and not really something one can use for added stability?

Having it in my vendor file would not work either (chicken and egg).

Nitpicking over usage/help text output

Asking mage to display supported options yields:

$ mage -h
mage [options] [target]
Options:
  -f    force recreation of compiled magefile
  -h    show this help
  -init
        create a starting template if no mage files exist
  -keep
        keep intermediate mage files around after running
  -l    list mage targets in this directory
  -v    show verbose output when running mage targets
  -version
        show version info for the mage binary

but typing the following yields:

$ mage --help
mage [options] [target]
Options:
  -f    force recreation of compiled magefile
  -h    show this help
  -init
        create a starting template if no mage files exist
  -keep
        keep intermediate mage files around after running
  -l    list mage targets in this directory
  -v    show verbose output when running mage targets
  -version
        show version info for the mage binary
mage [options] [target]
Options:
  -f    force recreation of compiled magefile
  -h    show this help
  -init
        create a starting template if no mage files exist
  -keep
        keep intermediate mage files around after running
  -l    list mage targets in this directory
  -v    show verbose output when running mage targets
  -version
        show version info for the mage binary

instead of:

$ mage --help
flag provided but not defined: -help
mage [options] [target]
Options:
  -f    force recreation of compiled magefile
  -h    show this help
  -init
        create a starting template if no mage files exist
  -keep
        keep intermediate mage files around after running
  -l    list mage targets in this directory
  -v    show verbose output when running mage targets
  -version
        show version info for the mage binary
Error: flag provided but not defined: -help

You may want to fix this ๐Ÿ˜‰

Remove stutter in `mage -l`

When writing things using function commentary such as:

// Build builds and re-generates all needed dependencies and compiles all binaries for $APP_NAME.
func Build() {
// ... etc

This gets recorded in the mage task list as:

$ mage -l 
Targets:
  build      Build builds and re-generates all needed dependencies and compiles all binaries for $APP_NAME.

What I would expect would be something akin to:

$ mage -l 
Targets:
  build      builds and re-generates all needed dependencies and compiles all binaries for $APP_NAME.

I have a proof of concept patch here that implements this in a rather hacky way that seems to work pretty well.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.