Modern Make

Overview

Modern Make

About

Mmake is a small program which wraps make to provide additional functionality, such as user-friendly help output, remote includes, and eventually more. It otherwise acts as a pass-through to standard make.

Installation

Via gobinaries.com:

$ curl -sf https://gobinaries.com/tj/mmake/cmd/mmake | sudo sh

Build from source:

$ go get github.com/tj/mmake/cmd/mmake

Homebrew:

$ brew tap tj/mmake https://github.com/tj/mmake.git
$ brew install tj/mmake/mmake

Next add the following alias to your profile:

alias make=mmake

Features

Help output

Make's primary function is not to serve as a "task runner", however it's often used for that scenario due to its ubiquitous nature, and if you're already using it, why not! Make is however lacking a built-in mechanism for displaying help information.

Here's an example Makefile:

# Start the dev server.
#
# Note that the API server must
# also be running.
start:
	@gopherjs -m -v serve --http :3000 github.com/tj/docs/client
.PHONY: start

# Start the API server.
api:
	@go run server/cmd/api/api.go
.PHONY: api

# Display dependency graph.
deps:
	@godepgraph github.com/tj/docs/client | dot -Tsvg | browser
.PHONY: deps

# Display size of dependencies.
#- Any comment preceded by a dash is omitted.
size:
	@gopherjs build client/*.go -m -o /tmp/out.js
	@du -h /tmp/out.js
	@gopher-count /tmp/out.js | sort -nr
.PHONY: size

Mmake provides a help command to display all target comments in short form:

$ alias make=mmake
$ make help

  start      Start the dev server.
  api        Start the API server.
  deps       Display dependency graph.
  size       Display size of dependencies.

You can optionally filter which commands to view the help dialogue for (this supports standard Unix glob patterns):

$ make help start

  start   Start the dev server.

$ make help s*

  size    Display size of dependencies.
  start   Start the dev server.

The help command also supports displaying longer output with the verbose flag (-v / --verbose):

$ make help -v start

  Start the dev server.

  Note that the API server must
  also be running.

$ make help -v

  start:
    Start the dev server.

    Note that the API server must
    also be running.

  api:    
    Start the API server.

  deps:       
    Display dependency graph.

  size:
    Display size of dependencies.
    

The default behaviour of Make is of course preserved:

$ make
serving at http://localhost:3000 and on port 3000 of any available addresses

$ make size
...

Remote includes

Includes may specify a URL (http, https, or github shortcut) for inclusion, which are automatically downloaded to /usr/local/include and become available to Make. Note that make resolves includes to this directory by default, so the Makefile will still work for regular users.

Includes are resolved recursively. For example you may have a standard set of includes for your team to run tests, lint, and deploy:

include github.com/apex/make/deploy
include github.com/apex/make/lint
include github.com/apex/make/test
include https://github.com/apex/make/test/Makefile
include https://github.com/apex/make/test/make.mk

This can be a lot to remember, so you could also provide a file which includes the others:

include github.com/apex/make/all

If the given repository contains an index.mk file, you can just declare:

include github.com/apex/make

Or perhaps one per dev environment such as Node or Golang:

include github.com/apex/make/node
include github.com/apex/make/golang

If you're worried about arbitrary code execution, then simply fork a project and maintain control over it.

Update

Once the remote includes are downloaded to /usr/local/include, mmake will not try to fetch them again. In order to get an updated copy of the remote includes, mmake provides an update target that will download them again:

$ make update

Registry

If you're looking to find or share makefiles check out the Wiki, and feel free to add a category if it is missing.

Links

Badges

GoDoc


tjholowaychuk.com  ·  GitHub @tj  ·  Twitter @tjholowaychuk

Comments
  • Support a custom includes path

    Support a custom includes path

    This adds support for a custom includes path. This helps when you do not have permission to modify /usr/local/include, for example.

    It relies on the standard -I flag, so something like make -I /tmp/custom/path and make -I/var/lib/whatever work.

    opened by codekoala 9
  • Contributing back from a fork

    Contributing back from a fork

    Hi @tj,

    I like the concept of this project and looked through forks and PRs to bring it current and extend it for a few desired features. Repo: https://github.com/zph/mmake

    • [x] Allow direct http/s based includes via new resolver
    • [x] Support standard makefile names (per GNUMake, ie GNUmakefile, makefile, or Makefile) #33 (though I rewrote this one myself)
    • [x] Allow custom include paths #25
    • [x] Highlight default target #29
    • [x] Fixed tests broken by custom include path.
    • [x] Use goreleaser
    • [x] Setup a brew recipe for installation on mac/linux
    • [x] Use golang modules for dependency tracking/download
    • [ ] Implements #3 tag/commit/sha support for github based resolver

    I want to make sure to contribute back and am happy to do any of the following:

    • Merge this back into your repo and optionally get a commit bit to tidy up the issues/PRs
    • Maintain my own copy indefinitely
    • Or another combination of these :).

    Thanks for putting this project together and if any of these outcomes sound good, great! If not, I'm quite happy to have my own repo for it too 👍.

    Cheers, ZPH

    enhancement 
    opened by zph 7
  • Colorize help output

    Colorize help output

    (Builds on #36, will rebase when those land)

    Adds colorized output for easier reading :D.

    https://www.dropbox.com/s/xpk7s53natouyyo/Screenshot%202019-09-21%2022.51.44.png?dl=0

    opened by zph 6
  • Publish Homebrew Formula

    Publish Homebrew Formula

    In your .goreleaser configuration you have homebrew configured, but you haven't yet published the formula. I would love to be able to install mmake via brew. Could you publish your formula?

    opened by wburningham 5
  • Add go releaser

    Add go releaser

    (Builds on #37, will rebase after prior PRs land)

    This PR sets up GoReleaser as a mechanism for building binaries and setting up a homebrew formula for use as brew install tj/mmake.

    opened by zph 4
  • Use go modules for dependency tracking and fix broken dependency (go-env)

    Use go modules for dependency tracking and fix broken dependency (go-env)

    This pr introduces use of go mod for handling dependencies.

    It also removes go-env, used in 1 location but broken in newer versions. I replaced it with stdlib code. Fixes warnings/error from mmake.go.

    opened by zph 4
  • Add HTTP Resolver and Support alternate valid GNUMake filenames

    Add HTTP Resolver and Support alternate valid GNUMake filenames

    (Builds off #35 but will rebase it when those are in master. So only later commits are relevant)

    1. Adds an http resolver to allow for:
    include https://example.com/Makefile
    

    I updated the readme to document this and it keeps backwards compatibility when include statement doesn't have a remote that starts with http.

    1. Allows for alternate filenames in local repo per guidelines from GNUMake, in precedence based ordering. These are:
    var makefileVariants = [3]string{"GNUmakefile", "makefile", "Makefile"}
    
    opened by zph 3
  •  Add the ability to resolve locally

    Add the ability to resolve locally

    Hi. This one allows to include local files and get help output for them. What's kind of is messing with my head is what to do with local includes within remote includes. An example:

    # Makefile that sits at https://github.com/mrblah/make/foo.mk
    
    include ./bar.mk
    

    Should we consider bar.mk local to https://github.com/mrblah/make/foo.mk (option 1)? Or should we just assume that bar.mk has already been saved on the disk and is relative to the makefile we've run make on (option 2)? I went with the option 2 :)

    Closes #14

    opened by tryzniak 3
  • Info about fetching includes

    Info about fetching includes

    Right now if we run Makefile via mmake for the first time it fetches github.com includes, it might be cool to have some kind of info / spinner running, dunno..

    Since this exists, might as well be used here: https://github.com/tj/go-spin :p

    opened by rpunkfu 3
  • Verbose flag for `help` command

    Verbose flag for `help` command

    Might be cool to have, for a quick glance at what the makefile does instead of going through every command :)

    $ make help -v
    
      start:
        Start the dev server.
    
        Note that the API server must
        also be running.
    
      api:    
        Start the API server.
    
      deps:       
        Display dependency graph.
    
      size:
        Display size of dependencies.
    
    opened by rpunkfu 2
  • WIP to export Makefiles that replace include with file content

    WIP to export Makefiles that replace include with file content

    This spike is to transpile makefiles to replace include statements with their file contents.

    This will solve 2 issues:

    • Wanting a way to export Makefile into transpiled Makefile that has inlined includes (Issue #18)
    • Providing help output that includes targets from include makefiles (Issue #31)

    I spiked it out in ruby for easy of scripting: https://gist.github.com/zph/8b3f6afd7a56613a80ef09319c20c7be

    mmake export will read the Makefile, then parse it line by line for include statements, then each include will be recursively filled in with the file content of the include Makefile, which will be recursively parsed for include statements...

    So running mmake export on the Makefile at root of this project would yield a portable Makefile like:

    #- start=include github.com/tj/make/golang
    #- start=include github.com/tj/make/cloc
    # Output source statistics.
    cloc:
            @cloc --exclude-dir=client,vendor .
    .PHONY: cloc
    #- end=include github.com/tj/make/cloc
    
    #- start=include github.com/tj/make/todo
    # Output to-do items per file.
    todo:
            @grep \
                    --exclude-dir=./vendor \
                    --exclude-dir=./client/node_modules \
                    --text \
                    --color \
                    -nRo ' TODO:.*' .
    .PHONY: todo
    #- end=include github.com/tj/make/todo
    
    # Run all tests.
    test:
            @go test -cover ./...
    .PHONY: test
    
    # Install the commands.
    install:
            @go install ./cmd/...
    .PHONY: install
    
    # Release binaries to GitHub.
    release:
            @goreleaser --rm-dist --config .goreleaser.yml
    .PHONY: release
    
    # Show size of imports.
    size:
            @curl -sL https://gist.githubusercontent.com/tj/04e0965e23da00ca33f101e5b2ed4ed4/raw/9aa16698b2bc606cf911219ea540972edef05c4b/gistfile1.txt | bash
    .PHONY: size
    #- end=include github.com/tj/make/golang
    

    That full Makefile output can then be used for mmake help to correctly report all targets :D.

    Anyway, it looked fun and caught my attention. Now I need to do the actual work of transcribing and re-implementing.

    Priority: Low 
    opened by zph 1
  • permission denied

    permission denied

    This was installed using homebrew.

    $ cat Makefile | head -1
    include https://gitlab.com/REDACTED/make-templates.git
    
    $ make
       ⨯ installing                error=installing "https://gitlab.com/REDACTED/make-templates.git": mkdir: mkdir /usr/local/include: permission denied
    

    I'm thinking this is an issue with M1 Mac's and how homebrew changed the install directory: /usr/local vs /opt/homebrew

    Also tried installing with curl:

    $ curl -sf https://gobinaries.com/tj/mmake/cmd/mmake | sudo sh
    Password:
    
      ==> Downloading github.com/tj/mmake/cmd/[email protected]
      ==> Resolved version master to v1.4.0
      ==> Downloading binary for darwin arm64
    
      Error downloading, got 500 response from server
    
    $ sw_vers
    ProductName:	macOS
    ProductVersion:	12.4
    BuildVersion:	21F79
    
    opened by heydonovan 0
  • Wishlist: Duration between targets

    Wishlist: Duration between targets

    Be cool to pretty print duration between targets and such

    https://stackoverflow.com/questions/37725552/show-the-build-duration-time-in-makefile is rather nasty

    opened by kaihendry 1
  • mmake help doesn't output comments from include targets

    mmake help doesn't output comments from include targets

    @tj , thanks for this awesome tooling. I'm not sure if this was ever possible. But in 1.3.0 mmake help does not output any help data for a simple included common makefile.

    Makefile

    include ../common.mk
    

    common.mk

    # example command help string
    start:
      @echo test
    .PHONY: start
    
    help wanted 
    opened by sourcec0de 0
  • Ignore .PHONY line

    Ignore .PHONY line

    Many style guides suggest putting the .PHONY before the target. This is also my preferred style.

    # Remove all build artifacts and dependencies
    .PHONY: clean
    clean:
    	-rm -r build
    

    This, however, leads to a not very helpful help output

    $ make help
    
      .PHONY                        Remove all build artifacts and dependencies
    

    I think mmake should ignore the .PHONY line.

    bug 
    opened by adius 3
  • Ability to generate Makefiles and/or update targets

    Ability to generate Makefiles and/or update targets

    I was thinking about how to use mmake with projects where potential contributors may or may not have it, and asking them to install it is another step that doesn't feel totally necessary. The idea I came up with is to have a secondary MMakefile (or similar) that contains remote includes, and can (optionally) be used to generate a Makefile with the remote includes inlined.

    For instance:

    # MMakefile
    
    include github.com/foo/make/bar
    

    $ mmake gen

    # Makefile
    
    bar:
        // Contents of github.com/foo/make/bar
    

    Basically mmake would check for MMakefile before Makefile when executing a target, so you could have either a MMakefile, Makefile, or both.

    Alternatively, it could suffice to support overwriting a target in a Makefile with the latest version of a remote. For example, the sanity and precommit targets here are actually copy+pasted from what would have been remote includes if I were to enforce mmake being installed, which isn't ideal because there are already hurdles to contributing to that project. What would be nice is to be able to update these targets inline with the latest contents of the remote targets, something like:

    $ mmake update sanity github.com/KyleBanks/make/go/sanity
    

    After this the Makefile would contain the latest version of sanity.

    enhancement 
    opened by KyleBanks 0
Releases(v1.4.0)
Owner
TJ Holowaychuk
TJ Holowaychuk
a Make/rake-like dev tool using Go

About Mage is a make-like build tool using Go. You write plain-old go functions, and Mage automatically uses them as Makefile-like runnable targets. I

Mage 3.3k Nov 21, 2022
Concurrent task runner, developer's routine tasks automation toolkit. Simple modern alternative to GNU Make 🧰

taskctl - concurrent task runner, developer's routine tasks automation toolkit Simple modern alternative to GNU Make. taskctl is concurrent task runne

null 229 Nov 26, 2022
Go-Guardian is a golang library that provides a simple, clean, and idiomatic way to create powerful modern API and web authentication.

❗ Cache package has been moved to libcache repository Go-Guardian Go-Guardian is a golang library that provides a simple, clean, and idiomatic way to

Sanad Haj Yahya 418 Nov 20, 2022
A Commander for modern Go CLI interactions

Cobra is both a library for creating powerful modern CLI applications as well as a program to generate applications and command files. Cobra is used i

Steve Francia 29.6k Nov 19, 2022
✨ #PTerm is a modern go module to beautify console output. Featuring charts, progressbars, tables, trees, and many more 🚀 It's completely configurable and 100% cross-platform compatible.

?? PTerm | Pretty Terminal Printer A golang module to print pretty text Show Demo Code PTerm.sh | Installation | Documentation | Quick Start | Example

null 3.1k Nov 25, 2022
Write your SQL queries in raw files with all benefits of modern IDEs, use them in an easy way inside your application with all the profit of compile time constants

About qry is a general purpose library for storing your raw database queries in .sql files with all benefits of modern IDEs, instead of strings and co

Sergey Treinis 25 Nov 5, 2022
A modern and intuitive terminal-based text editor

micro is a terminal-based text editor that aims to be easy to use and intuitive, while also taking advantage of the capabilities of modern terminals.

Zachary Yedidia 20.7k Nov 28, 2022
Build cross-platform modern desktop apps in Go + HTML5

Lorca A very small library to build modern HTML5 desktop apps in Go. It uses Chrome browser as a UI layer. Unlike Electron it doesn't bundle Chrome in

Serge Zaitsev 7.5k Nov 24, 2022
Golang bindings of Sciter: the Embeddable HTML/CSS/script engine for modern UI development

Go bindings for Sciter Check this page for other language bindings (Delphi / D / Go / .NET / Python / Rust). Attention The ownership of project is tra

Terra Informatica Software, Inc 2.5k Nov 18, 2022
Project Flogo is an open source ecosystem of opinionated event-driven capabilities to simplify building efficient & modern serverless functions, microservices & edge apps.

Project Flogo is an Open Source ecosystem for event-driven apps Ecosystem | Core | Flows | Streams | Flogo Rules | Go Developers | When to use Flogo |

TIBCO Software Inc. 2.1k Nov 22, 2022
Modern Go Application example

Modern Go Application Go application boilerplate and example applying modern practices This repository tries to collect the best practices of applicat

Márk Sági-Kazár 1.4k Nov 20, 2022
:rocket: Modern cross-platform HTTP load-testing tool written in Go

English | 中文 Cassowary is a modern HTTP/S, intuitive & cross-platform load testing tool built in Go for developers, testers and sysadmins. Cassowary d

Roger Welin 634 Nov 19, 2022
Modern Job Scheduler

Kala Kala is a simplistic, modern, and performant job scheduler written in Go. Features: Single binary No dependencies JSON over HTTP API Job Stats Co

AJ Bahnken 1.9k Nov 27, 2022
A modern and intuitive terminal-based text editor

micro is a terminal-based text editor that aims to be easy to use and intuitive, while also taking advantage of the capabilities of modern terminals

Zachary Yedidia 20.7k Nov 23, 2022
webrpc is a schema-driven approach to writing backend services for modern Web apps and networks

webrpc is a schema-driven approach to writing backend servers for the Web. Write your server's api interface in a schema format of RIDL or JSON, and t

null 487 Nov 22, 2022
A modern text indexing library for go

bleve modern text indexing in go - blevesearch.com Features Index any go data structure (including JSON) Intelligent defaults backed up by powerful co

bleve 8.7k Nov 22, 2022
A modern, fast and scalable websocket framework with elegant API written in Go

About neffos Neffos is a cross-platform real-time framework with expressive, elegant API written in Go. Neffos takes the pain out of development by ea

Gerasimos (Makis) Maropoulos 477 Nov 22, 2022
High performance, self-hosted newsletter and mailing list manager with a modern dashboard. Single binary app.

listmonk is a standalone, self-hosted, newsletter and mailing list manager. It is fast, feature-rich, and packed into a single binary. It uses a Postg

Kailash Nadh 8.9k Nov 28, 2022
A modern layer 7 load balancer from baidu

BFE BFE is a modern layer 7 load balancer from baidu. Advantages Multiple protocols supported, including HTTP, HTTPS, SPDY, HTTP2, WebSocket, TLS, Fas

null 5.7k Nov 18, 2022
A modern UNIX ed (line editor) clone written in Go

ed (the awesome UNIX line editor) ed is a clone of the UNIX command-line tool by the same name ed a line editor that was nortorious for being and most

James Mills 45 May 29, 2021