Git Product home page Git Product logo

checkmake's Introduction

checkmake

Build Status Coverage Status Code Climate Packagecloud MIT license

Overview

checkmake is an experimental tool for linting and checking Makefiles. It may not do what you want it to.

Usage

% checkmake Makefile

% checkmake Makefile foo.mk bar.mk baz.mk

% checkmake --help
checkmake.

Usage:
checkmake [--debug|--config=<configPath>] <makefile>...
checkmake -h | --help
checkmake --version

Options:
-h --help               Show this screen.
--version               Show version.
--debug                 Enable debug mode
--config=<configPath>   Configuration file to read
--list-rules            List registered rules

% checkmake fixtures/missing_phony.make

      RULE                 DESCRIPTION             LINE NUMBER

  minphony        Missing required phony target    0
                  "all"
  minphony        Missing required phony target    0
                  "test"
  phonydeclared   Target "all" should be           18
                  declared PHONY.

Docker usage

Build the image, or pull it:

docker build --build-arg BUILDER_NAME='Your Name' --build-arg [email protected] . -t checker

Then run it with your Makefile attached, below is an example of it assuming the Makefile is in your current working directory:

docker run -v "$PWD"/Makefile:/Makefile checker

pre-commit usage

This repo includes a pre-commit hook, which you may choose to use in your own repos. Simply add a .pre-commit-config.yaml to your repo's top-level directory

repos:
-   repo: https://github.com/mrtazz/checkmake.git
    # Or another commit hash or version
    rev: 0.2.2
    hooks:
    # Use this hook to let pre-commit build checkmake in its sandbox
    -   id: checkmake
    # OR Use this hook to use a pre-installed checkmark executable
    # -   id: checkmake-system

There are two hooks available:

  • checkmake (Recommended)

    pre-commit will set up a Go environment from scratch to compile and run checkmake. See the pre-commit golang plugin docs for more information.

  • checkmake-system

    pre-commit will look for checkmake on your PATH. This hook requires you to install checkmake separately, e.g. with your package manager or a prebuilt binary release. Only recommended if it's permissible to require all repository users install checkmake manually.

Then, run pre-commit as usual as a part of git commit or explicitly, for example:

pre-commit run --all-files

pre-commit in GitHub Actions

You may also choose to run this as a GitHub Actions workflow. To do this, add a .github/workflows/pre-commit.yml workflow to your repo:

name: pre-commit

on:
  pull_request:
    branches:
      - master
      - main
    paths:
      - '.pre-commit-config.yaml'
      - '.pre-commit-hooks.yaml'
      - 'Makefile'
      - 'makefile'
      - 'GNUmakefile'
      - '**.mk'
      - '**.make'
  push:
    paths:
      - '.pre-commit-config.yaml'
      - '.pre-commit-hooks.yaml'
      - 'Makefile'
      - 'makefile'
      - 'GNUmakefile'
      - '**.mk'
      - '**.make'

jobs:
  pre-commit:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-python@v3
    - name: Set up Go 1.17
      uses: actions/setup-go@v2
      with:
        go-version: 1.17
      id: go
    - uses: pre-commit/[email protected]

Installation

Requirements

The pandoc document converter utility is required to run checkmate. You can find out if you have it via which pandoc. Install pandoc if the command was not found.

With Go

With go 1.16 or higher:

go install github.com/mrtazz/checkmake/cmd/checkmake@latest
checkmake Makefile

Or alternatively, run it directly:

go run github.com/mrtazz/checkmake/cmd/checkmake@latest Makefile

Packages

There are packages for linux up on packagecloud.io or build it yourself with the steps below.

Build

To build checkmake you will need to have golang installed. Once you have Go installed, you can simply clone the repo and build the binary and man page yourself with the following commands.

git clone https://github.com/mrtazz/checkmake
cd checkmake
make

Use in CI

MegaLinter

checkmake is natively embedded within MegaLinter

To install it, run npx mega-linter-runner --install (requires Node.js)

Inspiration

This is totally inspired by an idea by Dan Buch.

checkmake's People

Contributors

ashmckenzie avatar christian-weiss avatar colindean avatar fdegier avatar haysclark avatar jimmywan avatar joakimr-axis avatar jonzeolla avatar junaruga avatar mrtazz avatar nvuillam avatar peterdavehello avatar silverwind avatar stephengroat-dd avatar trinitronx 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

checkmake's Issues

Simply expanded rule triggered for seemingly nothing

Related to #17

Expected behaviour

check should pass

Actual behaviour

        RULE                   DESCRIPTION             LINE NUMBER  
                                                                    
  timestampexpanded   Variable "PHONY" possibly        13           
                      contains a timestamp and                      
                      should be simply expanded. 

Output of checkmake --version

$ /checkmake --version
checkmake 0.1.0-39-g1383019 built at 2020-04-07T19:00:22Z by  <> with go version go1.13.9 linux/amd64

Output of checkmake --debug <your makefile>

2020/04/07 22:41:06 Unable to match line '' to a Rule or Variable
2020/04/07 22:41:06 Unable to match line 'TERRAFORM_MODULE_PATH ?= $(realpath ./)' to a Rule or Variable
2020/04/07 22:41:06 Unable to match line '' to a Rule or Variable
2020/04/07 22:41:06 Unable to match line '' to a Rule or Variable
2020/04/07 22:41:06 Unable to match line '' to a Rule or Variable
2020/04/07 22:41:06 Unable to match line '' to a Rule or Variable
2020/04/07 22:41:06 Unable to match line '' to a Rule or Variable
2020/04/07 22:41:06 Unable to match line '' to a Rule or Variable
2020/04/07 22:41:06 Unable to match line '' to a Rule or Variable
2020/04/07 22:41:06 Running rule 'phonydeclared'...
2020/04/07 22:41:06 Running rule 'timestampexpanded'...
2020/04/07 22:41:06 Running rule 'maxbodylength'...
2020/04/07 22:41:06 Running rule 'minphony'...
                                                                    
        RULE                   DESCRIPTION             LINE NUMBER  
                                                                    
  timestampexpanded   Variable "PHONY" possibly        25           
                      contains a timestamp and                      
                      should be simply expanded.                    
                                                 

Output of make --version

Make is not available (using the docker image from this repo)

Sample Makefile to reproduce issue

TERRAFORM_MODULE_PATH ?= $(realpath ./)

.PHONY: all
all:

.PHONY: clean
clean:

.PHONY: test
test:

.PHONY: validate
validate:
	docker run -i --rm \
		-v $(TERRAFORM_MODULE_PATH):/data \
		hashicorp/terraform:light validate

(some of these things might not apply but the more you can provide the easier
it will be to fix this bug. Thanks!)

write configuration package

Expected behaviour

have a way to configure the linter itself and any rules

Actual behaviour

There is no way to configure any of the above

build cannot load bufio: malformed module path

When I install
$ go get github.com/mrtazz/checkmake
go: downloading github.com/docopt/docopt-go v0.0.0-20141128170934-854c423c8108
go: downloading github.com/olekukonko/tablewriter v0.0.0-20150822215231-b9346ac189c5
go: downloading github.com/go-ini/ini v1.11.0
go: extracting github.com/olekukonko/tablewriter v0.0.0-20150822215231-b9346ac189c5
go: extracting github.com/docopt/docopt-go v0.0.0-20141128170934-854c423c8108
go: extracting github.com/go-ini/ini v1.11.0
go: finding github.com/docopt/docopt-go v0.0.0-20141128170934-854c423c8108
go: finding github.com/olekukonko/tablewriter v0.0.0-20150822215231-b9346ac189c5
go: finding github.com/go-ini/ini v1.11.0
build github.com/mrtazz/checkmake: cannot load bufio: malformed module path "bufio": missing dot in first path element

Output of checkmake --version

Didn't get that far

Output of checkmake --debug <your makefile>

Output of make --version

GNU Make 3.81

No newlines in ALE output - side effect of 8838750?

Expected behaviour

ALE seems to expect each error/warning on its own line.

(finished - exit code 3) ['/bin/bash', '-c', 'checkmake ''/home/dan/projects/pandion/makefile'' --format="{{.LineNumber}}:{{.Rule}}:{{.Violation}}{{\"\n\"}}" < ''/tmp/vEQBFzm/31/makefile''']                                                                               
<<<OUTPUT STARTS>>>                                                                                                                                                                                                                                                          
4:phonydeclared:Target "another" should be declared PHONY.
0:minphony:Missing required phony target "all"                                                                                                                                                                                                                               
0:minphony:Missing required phony target "clean"                                                                                                                                                                                                                             
0:minphony:Missing required phony target "test"                                                                                                                                                                                                                              
<<<OUTPUT ENDS>>>

ALE marks each error line and shows the first error for that line, if more than one.

Actual behaviour

(finished - exit code 4) ['/bin/bash', '-c', 'checkmake ''/home/dan/projects/pandion/makefile'' --format="{{.LineNumber}}:{{.Rule}}:{{.Violation}}" < ''/tmp/vALBAMS/3/makefile''']                                                                                          
<<<OUTPUT STARTS>>>                                                                                                                                                                                                                                                          
4:phonydeclared:Target "another" should be declared PHONY.0:minphony:Missing required phony target "all"0:minphony:Missing required phony target "clean"0:minphony:Missing required phony target "test"                                                                      
<<<OUTPUT ENDS>>>

ALE marks only one error line, even when errors on more than one line, and displays the entire list on a single line of output.

Sample Makefile to reproduce issue

echo:
	@echo do nothing

another: another.c

Perhaps I'm missing some way to configure golang to insert newline for each template line? Otherwise, changing the format string to include the newline worked:

call ale#linter#Define('make', {
\   'name': 'checkmake',
\   'executable': 'checkmake',
\   'command': 'checkmake %s --format="{{.LineNumber}}:{{.Rule}}:{{.Violation}}{{\"\n\"}}"',
\   'callback': 'ale_linters#make#checkmake#Handle',
\})

refactor rule structure to use interfaces

right now we register a struct with a function reference and some values. The more golang idiomatic way would probably be to make it an interface with functions for Name(), Description(), and Run().

Please do not ouptut CR sign.

Expected behaviour

Weeell, do not output CR on Linux.

Actual behaviour

Weeell, outputs CR character on Linux.

$ LC_ALL=C checkmake --format={{.LineNumber}}:{{.Rule}}:{{.Violation}} /tmp/Makefile | head -n1 | hexdump -C
00000000  30 3a 6d 69 6e 70 68 6f  6e 79 3a 4d 69 73 73 69  |0:minphony:Missi|
00000010  6e 67 20 72 65 71 75 69  72 65 64 20 70 68 6f 6e  |ng required phon|
00000020  79 20 74 61 72 67 65 74  20 22 61 6c 6c 22 0d 0a  |y target "all"..|
#                                                    ^^ HERE

Output of checkmake --version

Compiled on archlinux today, installed from AUR.

$ checkmake --version
checkmake 0.1.0-47-g575315c built at 2021-09-29T09:02:23Z by Kamil Cukrowski <[email protected]> with go version go1.17.1 linux/amd64

Output of checkmake --debug <your makefile>

$ LC_ALL=C checkmake --format={{.LineNumber}}:{{.Rule}}:{{.Violation}} --debug /tmp/Makefile 
2021/09/29 12:07:30 Unable to match line '' to a Rule or Variable
2021/09/29 12:07:30 Unable to parse config file "checkmake.ini", running with defaults
2021/09/29 12:07:30 Running rule 'maxbodylength'...
2021/09/29 12:07:30 iniFile not initialized
2021/09/29 12:07:30 Running rule 'minphony'...
2021/09/29 12:07:30 iniFile not initialized
2021/09/29 12:07:30 Running rule 'phonydeclared'...
2021/09/29 12:07:30 iniFile not initialized
2021/09/29 12:07:30 Running rule 'timestampexpanded'...
2021/09/29 12:07:30 iniFile not initialized
0:minphony:Missing required phony target "all"
0:minphony:Missing required phony target "clean"
0:minphony:Missing required phony target "test"
1:phonydeclared:Target "all" should be declared PHONY.

Output of make --version

$ LC_ALL=C make --version
GNU Make 4.3
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Sample Makefile to reproduce issue

all:

So I was trying to integrate checkmake with https://github.com/iamcco/coc-diagnostic, spend good 2 hours figuring why it does not work. Seems like coc-diagnostic does not like CR characters (which I will tr -d '\'r fix on my config side) but I believe *unix tools shouldn't output CR characters anyway. I tried reading the source code, but I know nothing about go, so I do not know where to fix.

Thanks for this amazing project.

docker image build instructions are incorrect

Expected behaviour

Instructions are valid

Actual behaviour

❯ docker build -e BUILDER_NAME="Your Name" -e BUILDER_EMAIL="[email protected]" . -t checker
unknown shorthand flag: 'e' in -e

Need to swap -e with --build-arg.

❯ docker build --help | grep build-arg
      --build-arg list          Set build-time variables

Allow exceptions to timestampexpanded

Expected behaviour

A user should be able to configure a rule that whitelists a string in the timestampexpanded rule. For instance, update.

Output of checkmake --version

checkmake  built at  by  with

(Wow, that output wasn't expected!)

Windows documentation

Hi, there should be a minimal amount of documentation for Windows users who would like to make use of your package. At the moment, following README instructions using Windows results in the an error upon running go get github.com/mrtazz/checkmate. See below the suggested fix for details.

SUGGESTED FIX

Simply add the following alternate instruction for operating systems that do not support symlinks, such as Windows:

go get github.com/mrtazz/checkmake/cmd/checkmake

This installs the package successfully.

Expected behaviour

Successful install (no console output)

Actual behaviour

Installation error:

package github.com/mrtazz/checkmake:
Users\Paul.Benn-Darias\go\src\github.com\mrtazz\checkmake\checkmake.go:1:1: expected 'package', found '.'

Output of checkmake --version

checkmake built at by with

This does not seem to be printing the correct version, but I've used the latest tag.

Output of checkmake --debug <your makefile>

N/A as this is an installation problem.

Output of make --version

Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i386-pc-mingw32

Sample Makefile to reproduce issue

N/A as this is an installation issue.

Possibly add an argument for a cleaner error output

It'd be nice if there was a way to output a format that was better for vim's errorformat (more things than vim could leverage this), so, not having the Description be split onto two lines for example, i.e.:

    RULE              DESCRIPTION             LINE NUMBER

  minphony   Missing required phony target    0
             "test"

Could output with some argument, as:

miniphony|missing required phony target "test"|0

Ultimately I want to run this within vim, and capture the output by specifying the proper errorformat and display in a QuickFix list.

".PHONY<space>:" not judged as valid

Expected behaviour

The checkmake passes for the .PHONY : foo (.PHONY<space>: foo) in the Makefile.

$ checkmake Makefile 

$ echo $?
0

Actual behaviour

The checkmake complains for the .PHONY : foo (.PHONY<space>: foo) in the Makefile.
I used this Makefile https://github.com/junaruga/cpp-test/blob/report-checkmake/src/Makefile

$ checkmake Makefile 
    RULE              DESCRIPTION             LINE NUMBER  
                                                           
  minphony   Missing required phony target    0            
             "all"                                         
  minphony   Missing required phony target    0            
             "clean"                                       
  minphony   Missing required phony target    0            
             "test"

$ echo $?
3   

Seeing the GNU make PHONY document, there are 2 examples for both .PHONY: foo (without space) and .PHONY : foo (with space). So I assume both are valid.
https://www.gnu.org/software/make/manual/make.html#Phony-Targets

The checkmake passes the Makefile by applying the following patch. So, I assume that the .PHONY : foo (with space) is judged as invalid. But why?

diff --git a/src/Makefile b/src/Makefile
index 2ff0b4e..c0c1206 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -21,16 +21,16 @@ LIBS =
 .c.o :
        $(CC) -c $(CFLAGS) $(CPPFLAGS) $(INCLUDES) $< -o $@
 
-.PHONY : all
+.PHONY: all
 all : $(EXE)
 
 $(EXE) : $(OBJS) main.o
        $(CXX) $(CXXFLAGS) $^ -o $@ $(LIBS)
 
-.PHONY : clean
+.PHONY: clean
 clean :
        rm -f *.o $(EXE)
 
-.PHONY : test
+.PHONY: test
 test : all
        echo "Run the test"

Output of checkmake --version

There is no version info. The checkmake was installed today by the steps I wrote at #62 .

$ checkmake --version
checkmake  built at  by  with 

Output of checkmake --debug <your makefile>

$ checkmake --debug Makefile 
2021/12/03 18:56:56 Unable to match line '' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line '' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line '	$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $< -o $@' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line '' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line '	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(INCLUDES) $< -o $@' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line '' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line 'all : $(EXE)' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line '' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line '$(EXE) : $(OBJS) main.o' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line '	$(CXX) $(CXXFLAGS) $^ -o $@ $(LIBS)' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line '' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line 'clean :' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line '	rm -f *.o $(EXE)' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line '' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line 'test : all' to a Rule or Variable
2021/12/03 18:56:56 Unable to match line '	echo "Run the test"' to a Rule or Variable
2021/12/03 18:56:56 Unable to parse config file "checkmake.ini", running with defaults
2021/12/03 18:56:56 Running rule 'phonydeclared'...
2021/12/03 18:56:56 iniFile not initialized
2021/12/03 18:56:56 Running rule 'timestampexpanded'...
2021/12/03 18:56:56 iniFile not initialized
2021/12/03 18:56:56 Running rule 'maxbodylength'...
2021/12/03 18:56:56 iniFile not initialized
2021/12/03 18:56:56 Running rule 'minphony'...
2021/12/03 18:56:56 iniFile not initialized
2021/12/03 18:56:56 iniFile not initialized
    RULE              DESCRIPTION             LINE NUMBER  
                                                           
  minphony   Missing required phony target    0            
             "all"                                         
  minphony   Missing required phony target    0            
             "clean"                                       
  minphony   Missing required phony target    0            
             "test" 

Output of make --version

$ make --version
GNU Make 4.3
Built for x86_64-redhat-linux-gnu
Copyright (C) 1988-2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Sample Makefile to reproduce issue

(some of these things might not apply but the more you can provide the easier
it will be to fix this bug. Thanks!)

Here is the sample Makefile as I wrote above.
https://github.com/junaruga/cpp-test/blob/report-checkmake/src/Makefile

$ git clone --branch report-checkmake https://github.com/junaruga/cpp-test.git
$ cd cpp-test/src
$ checkmake Makefile

Thanks!

Not able to install

Hello. I'm not being able to install the tool.
Using docker commands from readme:

Sending build context to Docker daemon  867.8kB
Step 1/9 : FROM golang:1.13 as builder
 ---> d6f3656320fe
Step 2/9 : COPY . /checkmake
 ---> Using cache
 ---> f7365884b2fe
Step 3/9 : RUN cd /go/src/github.com/mrtazz/checkmake && GOOS=linux GOARCH=amd64 CGO_ENABLED=0 make binaries
 ---> Running in b28dad7a4ff7
/bin/sh: 1: cd: can't cd to /go/src/github.com/mrtazz/checkmake
The command '/bin/sh -c cd /go/src/github.com/mrtazz/checkmake && GOOS=linux GOARCH=amd64 CGO_ENABLED=0 make binaries' returned a non-zero code: 2

Using go get:

$ go get github.com/mrtazz/checkmake
$ checkmake
zsh: command not found: checkmake

How do I install it?

Support VAR:=value

Support:

VAR:=value

It currently treats VAR as a target:

Target "VAR" should be declared PHONY

Support Open Watcom C/C++'s wmake Makefiles

Output of checkmake --version

checkmake  built at  by  with

(Built from commit 03dd76b on 2019-11-02 using a freshly installed go version go1.13.4 linux/amd64 from the official site on Kubuntu Linux 16.04 LTS.)

Output of checkmake --debug <your makefile>

2019/11/02 06:17:37 Unable to match line '' to a Rule or Variable
2019/11/02 06:17:37 Unable to match line '' to a Rule or Variable
2019/11/02 06:17:37 Unable to match line 'test' to a Rule or Variable
2019/11/02 06:17:37 Unable to match line '      @echo ...and this is the shorthand form which I don't use because' to a Rule or Variable
2019/11/02 06:17:37 Unable to match line '      @echo it confuses Vim's syntax highlighting' to a Rule or Variable
2019/11/02 06:17:37 Unable to parse config file "checkmake.ini", running with defaults
2019/11/02 06:17:37 Running rule 'maxbodylength'...
2019/11/02 06:17:37 iniFile not initialized
2019/11/02 06:17:37 Running rule 'minphony'...
2019/11/02 06:17:37 iniFile not initialized
2019/11/02 06:17:37 Running rule 'phonydeclared'...
2019/11/02 06:17:37 iniFile not initialized
2019/11/02 06:17:37 Running rule 'timestampexpanded'...
2019/11/02 06:17:37 iniFile not initialized
2019/11/02 06:17:37 iniFile not initialized
                                                           
    RULE              DESCRIPTION             LINE NUMBER  
                                                           
  minphony   Missing required phony target    0            
             "all"                                         
  minphony   Missing required phony target    0            
             "clean"                                       
  minphony   Missing required phony target    0            
             "test"  

Output of make --version

As a cross-platform port of a tool originally for DOS and Windows, wmake doesn't implement --version, but I've confirmed the problem with the Linux versions of wmake included in OpenWatcom C/C++ 1.9 and one of the recent 2.0 builds.

(Note that the 1.9 installer for Linux and the 2.0 installer for Linux from 2015 have a known bug that'll cause them to crash if they can't find the terminal info database at an obsolete location. You need to either export TERMINFO=/lib/terminfo or export TERM=vt100 before running them... or just unzip them and write an owsetenv.sh by hand.)

Sample Makefile to reproduce issue

all: .SYMBOLIC
	@echo This is one way to write a .PHONY target in WMAKE

test
	@echo ...and this is the shorthand form which I don't use because
	@echo it confuses Vim's syntax highlighting

From this, the three differences should be pretty obvious:

  1. Instead of listing phony targets as dependencies of .PHONY, you list .SYMBOLIC as a dependency of each phony target in wmake.
  2. There's a shorthand form which has no colon or dependencies that I wouldn't expect anyone to support. I certainly don't use it.
  3. There's an echo builtin which follows the command-parsing semantics of the MS-DOS echo builtin. (ie. everything between echo and the end of the line is treated as a literal string. Hence the ' in don't is not an unbalanced quote.)

The dialect as a whole is described in chapter 10 of the "Open Watcom C/C++ Tools User’s Guide" (with .SYMBOLIC being described in section 10.32). That's available as ctools.pdf or ctools.html for 2.0 or tools.pdf for 1.9.

Now, to show how checkmake almost fits the bill in a real-world scenario, here's the non-debug output (because the debug output is long) from the much larger, more complex Makefile for my DOS hobby project (which supports both Linux and DOS as build environments):

      RULE                 DESCRIPTION             LINE NUMBER  
                                                                
  phonydeclared   Target "all" should be                   115  
                  declared PHONY.                               
  maxbodylength   Target body for "testrun"                153  
                  exceeds allowed length of 5                   
                  (9).                                          
  minphony        Missing required phony target    0            
                  "all"                                         
  minphony        Missing required phony target    0            
                  "clean"                                       
  minphony        Missing required phony target    0            
                  "test"                                        

I'll post more about that makefile on request.

Docker build fails

Expected behaviour

docker build succeeds

Actual behaviour

run 'docker build . -t checker` from root of dir

error:

 => ERROR [builder 3/4] RUN cd /go/src/github.com/mrtazz/checkmake && GOO  0.4s
------
 > [builder 3/4] RUN cd /go/src/github.com/mrtazz/checkmake && GOOS=linux GOARCH=amd64 CGO_ENABLED=0 make binaries:
#10 0.327 /bin/sh: 1: cd: can't cd to /go/src/github.com/mrtazz/checkmake
------
executor failed running [/bin/sh -c cd /go/src/github.com/mrtazz/checkmake && GOOS=linux GOARCH=amd64 CGO_ENABLED=0 make binaries]: exit code: 2

Output of checkmake --version

n/a

Output of checkmake --debug <your makefile>

n/a

Output of make --version

GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i386-apple-darwin11.3.0

Build failed

Running:
docker run --rm -v $(pwd):/data --workdir /data golang make
gives us the following error:

install -d .d
echo "checkmake: $(go list -f '{{ join .Deps "\n" }}' cmd/checkmake/main.go | awk '/github/ { gsub(/^github.com\/[a-z]*\/[a-z]*\//, ""); printf $0"/*.go " }')" > .d/checkmake.d
go build -ldflags "-X 'main.version=0.1.0-16-g03dd76b' -X 'main.buildTime=2019-12-23T14:56:04Z' -X 'main.builder= <>' -X 'main.goversion=go version go1.6.4 linux/amd64'" -o checkmake cmd/checkmake/main.go
cmd/checkmake/main.go:9:2: cannot find package "github.com/docopt/docopt-go" in any of:
        /usr/local/go/src/github.com/docopt/docopt-go (from $GOROOT)
        /go/src/github.com/docopt/docopt-go (from $GOPATH)
cmd/checkmake/main.go:10:2: cannot find package "github.com/mrtazz/checkmake/config" in any of:
        /usr/local/go/src/github.com/mrtazz/checkmake/config (from $GOROOT)
        /go/src/github.com/mrtazz/checkmake/config (from $GOPATH)
cmd/checkmake/main.go:11:2: cannot find package "github.com/mrtazz/checkmake/formatters" in any of:
        /usr/local/go/src/github.com/mrtazz/checkmake/formatters (from $GOROOT)
        /go/src/github.com/mrtazz/checkmake/formatters (from $GOPATH)
cmd/checkmake/main.go:12:2: cannot find package "github.com/mrtazz/checkmake/logger" in any of:
        /usr/local/go/src/github.com/mrtazz/checkmake/logger (from $GOROOT)
        /go/src/github.com/mrtazz/checkmake/logger (from $GOPATH)
cmd/checkmake/main.go:13:2: cannot find package "github.com/mrtazz/checkmake/parser" in any of:
        /usr/local/go/src/github.com/mrtazz/checkmake/parser (from $GOROOT)
        /go/src/github.com/mrtazz/checkmake/parser (from $GOPATH)
cmd/checkmake/main.go:14:2: cannot find package "github.com/mrtazz/checkmake/rules" in any of:
        /usr/local/go/src/github.com/mrtazz/checkmake/rules (from $GOROOT)
        /go/src/github.com/mrtazz/checkmake/rules (from $GOPATH)
cmd/checkmake/main.go:15:2: cannot find package "github.com/mrtazz/checkmake/validator" in any of:
        /usr/local/go/src/github.com/mrtazz/checkmake/validator (from $GOROOT)
        /go/src/github.com/mrtazz/checkmake/validator (from $GOPATH)
cmd/checkmake/main.go:16:2: cannot find package "github.com/olekukonko/tablewriter" in any of:
        /usr/local/go/src/github.com/olekukonko/tablewriter (from $GOROOT)
        /go/src/github.com/olekukonko/tablewriter (from $GOPATH)
make: *** [checkmake] Error 1
Makefile:47: recipe for target 'checkmake' failed

and on subsequent runs:

make: *** No rule to make target 'github.com/docopt/docopt-go/*.go', needed by 'checkmake'.  Stop.

As this specific line in the makefile had never changed since initial commit, i thought is maybe because of a to new golang environment. But i get the same results with older golang environments
docker run --rm -v $(pwd):/data --workdir /data golang:1.7.6 make
docker run --rm -v $(pwd):/data --workdir /data golang:1.6.4 make

checkmake --version . . . doesn't have a version

Expected behaviour

checkmake v1.0 built at 2017/12/17 by Joshua Nelson with Go v<something here>

Actual behaviour

checkmake built at by with

Output of checkmake --version

checkmake built at by with

Any updates?

Hi.
It's a good project! Thanks for that :)
But do you develop it or do you have some plans for the new version?

write rule for making date based variables simply expanded

Variables that look something like BUILDTIME := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") it's important to make them simply expanded. If they aren't multiple rules using the variable will re-eval them and end up with potentially different timestamps

'update' contains 'date' and so creates 'contains a timestamp' issue

Expected behaviour

Makefile

.PHONY: update_my_stuff
update_my_stuffv:

.PHONY: all
all:

.PHONY: clean
clean:

.PHONY: test
test:

fails with

  timestampexpanded   Variable "PHONY" possibly        2            
                      contains a timestamp and                      
                      should be simply expanded.                    

Actual behaviour

It should work.

The problem is that 'update' contains the word 'date', as in #38 and as fixed in #39. Notably, if you replace update_my_stuff by upda_te_my_stuff It works

Output of checkmake --version

checkmake 0.1.0-39-g1383019 built at 2020-10-27T22:53:40Z by <> with go version go1.15.3 linux/amd64

Output of checkmake --debug <your makefile>

2022/01/19 11:28:22 Unable to match line '' to a Rule or Variable
2022/01/19 11:28:22 Unable to match line 'update_my_stuffv:' to a Rule or Variable
2022/01/19 11:28:22 Unable to match line '' to a Rule or Variable
2022/01/19 11:28:22 Unable to match line '' to a Rule or Variable
2022/01/19 11:28:22 Unable to match line '' to a Rule or Variable
2022/01/19 11:28:22 Unable to match line '' to a Rule or Variable
2022/01/19 11:28:22 Unable to parse config file "checkmake.ini", running with defaults
2022/01/19 11:28:22 Running rule 'maxbodylength'...
2022/01/19 11:28:22 iniFile not initialized
2022/01/19 11:28:22 Running rule 'minphony'...
2022/01/19 11:28:22 iniFile not initialized
2022/01/19 11:28:22 Running rule 'phonydeclared'...
2022/01/19 11:28:22 iniFile not initialized
2022/01/19 11:28:22 Running rule 'timestampexpanded'...
2022/01/19 11:28:22 iniFile not initialized
2022/01/19 11:28:22 iniFile not initialized

    RULE                   DESCRIPTION             LINE NUMBER  

timestampexpanded Variable "PHONY" possibly 2
contains a timestamp and
should be simply expanded.

Output of make --version

I am in Docker so not sure it makes sense

Sample Makefile to reproduce issue

.PHONY: update_my_stuff
update_my_stuffv:

.PHONY: all
all:

.PHONY: clean
clean:

.PHONY: test
test:

Steps to build checkmake don't work on my environment

Expected behaviour

I am not really familiar with the golang. I expected the following steps to build the the checkmake works following the document.
https://github.com/mrtazz/checkmake#build

go get github.com/mrtazz/checkmake
cd $GOPATH/src/github.com/mrtazz/checkmake
make

Actual behaviour

I am using Fedora 34.

$ cat /etc/fedora-release 
Fedora release 34 (Thirty Four)

$ which go
/bin/go

$ go version
go version go1.16.8 linux/amd64

The go RPM package version is like this.

$ rpm -qf /bin/go
golang-bin-1.16.8-1.fc34.x86_64
$ echo "$GOPATH"
/home/jaruga/.go

$ go get github.com/mrtazz/checkmake
go: downloading github.com/docopt/docopt-go v0.0.0-20141128170934-854c423c8108
go: downloading github.com/olekukonko/tablewriter v0.0.0-20150822215231-b9346ac189c5
go: downloading github.com/go-ini/ini v1.11.0

$ cd $GOPATH/src/github.com/mrtazz/checkmake
bash: cd: /home/jaruga/.go/src/github.com/mrtazz/checkmake: No such file or directory

It seems that the "binary" is already installed into the /home/jaruga/.go/bin/checkmake. I am not sure if this is expected behavior.

$ ls /home/jaruga/.go/bin/checkmake
/home/jaruga/.go/bin/checkmake*

Output of checkmake --version

$ which checkmake
~/.go/bin/checkmake

$ checkmake --version
checkmake  built at  by  with 

Output of checkmake --debug <your makefile>

This item doesn't fit this issue, as this issue ticket is about the installation steps.

Output of make --version

$ make --version
GNU Make 4.3
Built for x86_64-redhat-linux-gnu
Copyright (C) 1988-2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Sample Makefile to reproduce issue

(some of these things might not apply but the more you can provide the easier
it will be to fix this bug. Thanks!)

This item doesn't fit this issue, as this issue ticket is about the installation steps.

False positive .PHONY violation on variables

reFindSimpleVariable = regexp.MustCompile("^([a-zA-Z]+) ?:=(.*)")
reFindExpandedVariable = regexp.MustCompile("^([a-zA-Z]+) ?=(.*)")

Those regex definitions don't recognize VAR=blah or VAR:=blahand flag such lines as needing.PHONY`.

    1 ifeq ($(OS), Windows_NT)
>>  2 MKDIR:=$(shell which mkdir.exe)
    3 else
~   4 MKDIR := mkdir
    5 endif

bug: Line number is not displayed correctly for minphony

image

Expected behaviour

Suggest correct line 155 for conflicting minphony

Actual behaviour

Conflicting line is 155 where line number 0 is suggested:

Output of checkmake --version

gitpod /workspace/Kreyrock $ checkmake --version
checkmake  built at  by  with 

Using commit 03dd76b

Output of checkmake --debug <your makefile>

https://gist.githubusercontent.com/Kreyren/03329ef4dd8c6b35152ca49cb93a27f7/raw/66f97f8c0acc21798a81b98f68f0e3a8e37ca4b2/gistfile1.txt

Output of make --version

gitpod /workspace/Kreyrock $ make --version
GNU Make 4.2.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redist

Sample Makefile to reproduce issue

https://gist.githubusercontent.com/Kreyren/788b99fc6a926fe1f7503b034c2b40f8/raw/3f8ebccd9557b348600a0987e8dc86292167157d/gistfile1.txt

make instructions on README have pandoc dependency installation requirement on macOS 10.14

Expected behaviour

Use of make according to installation instructions on repo README will complete without errors on macOS v10.14.1 where pandoc is not installed by default.

Actual behaviour

github.com/mrtazz/checkmake  master ✔                                    151d
▶ make
install -d .d
echo "checkmake: $(go list -f '{{ join .Deps "\n" }}' cmd/checkmake/main.go | awk '/github/ { gsub(/^github.com\/[a-z]*\/[a-z]*\//, ""); printf $0"/*.go " }')" > .d/checkmake.d
go build -ldflags "-X 'main.version=0.1.0-14-gff21564' -X 'main.buildTime=2018-11-30T16:50:39Z' -X 'main.builder=Chris Simpkins <[email protected]>' -X 'main.goversion=go version go1.11.2 darwin/amd64'" -o checkmake cmd/checkmake/main.go
sed "s/REPLACE_DATE/November 30, 2018/" man/man1/checkmake.1.md | pandoc -s -t man -o checkmake.1
/bin/sh: pandoc: command not found
make: *** [checkmake.1] Error 127

Output of checkmake --version

checkmake  built at  by  with

go get executed on commit ff21564

Output of make --version

GNU Make 3.81

When pandoc installed with brew install pandoc the make execution completes with exit status code 0; however, the version information is missing the build date/time and builder:

github.com/mrtazz/checkmake  master ✔                                    151d
▶ checkmake --version
checkmake  built at  by  with

Integration as a pre-commit hook

Hi.

Some devs at Yelp have written a CLI tool to register & run git pre-commit hooks easily : http://pre-commit.com

I've contributed a few hooks myself in Python, and they just added support for Go hooks: pre-commit/pre-commit#430

Hence I tried to add a checkmake-based hook : https://github.com/Lucas-C/pre-commit-hooks-go

However the fact that it requires a make invocation to build makes it "non standard".
At the moment, pre-commit only support go get ./... + the installation of additional dependencies: https://github.com/pre-commit/pre-commit/blob/master/pre_commit/languages/golang.py#L67

Do you think it would be possible to make some changes to the build process of checkmake in order to integrate it as a pre-commit hook ?

There are 2 options I think:

  • the simplest : make it installable with a simple go get ./...
  • use a common tool instead. I don't know much about the Go ecosystem : maybe gb or gom ? And then we would check with the pre-commit dev team if they are OK to support it.

Feature request: add option to ignore rules on a line basis

Most linters have an option to ignore rules in line as in some cases the rules are too strict. E.g. in the Makefile from this repo there is a rule, which IMHO is fine for reading purposes, but it does not follow the rules.

Adding the comment would seem logical to prevent checkmake to complain about rule violation:

# checkmake ignore: maxbodylength
coverage:
	@echo "mode: set" > cover.out
	@for package in $(PACKAGES); do \
		if ls $${package}/*.go &> /dev/null; then  \
		go test -coverprofile=$${package}/profile.out $${package}; fi; \
		if test -f $${package}/profile.out; then \
	 	cat $${package}/profile.out | grep -v "mode: set" >> cover.out; fi; \
	done
	@-go tool cover -html=cover.out -o cover.html

To prevent this output, which contains a bug as described in #29 :

$ docker run -v $(pwd)/Makefile:/Makefile checker
                                                                
      RULE                 DESCRIPTION             LINE NUMBER  
                                                                
  maxbodylength   Target body for "coverage"       70           

Call for maintainers

I am finding myself with less and less time to devote to this project. And it definitely shows on the issues page and the lack of implemented features.

If anyone is interested in taking up maintainership and become a collaborator on the repo, please chime in on this issue. Ideally you already have some contributions in the project. If not you can start now and help out with triaging issues and opening pull requests for bugs or features.

Support make check (the GNU conventions)

Expected behaviour

Instead of warning a missing .PHONY test, check if a check target exists instead.

Actual behaviour

With GNU Makefiles it warns about a missing make test target.
minphony Missing required phony target 1222
"test"

Output of checkmake --version

checkmake 0.2.1 built at 2022-08-15T10:00:27Z by Reinhard Urban [email protected] with go version go1.18.1 linux/amd64

Output of checkmake --debug <your makefile>

...
      RULE                 DESCRIPTION             LINE NUMBER  
                                                                
  maxbodylength   Target body for "Makefile"               578  
                  exceeds allowed length of 5                   
                  (8).                                          
  maxbodylength   Target body for "distcheck"              988  
                  exceeds allowed length of 5                   
                  (57).                                         
  maxbodylength   Target body for                         1046  
                  "distcleancheck" exceeds                      
                  allowed length of 5 (8).                      
  maxbodylength   Target body for "unknown"               1230  
                  exceeds allowed length of 5                   
                  (14).                                         
  minphony        Missing required phony target           1222  
                  "clean"                                       
  minphony        Missing required phony target           1222  
                  "test"                                        
  phonydeclared   Target "tags" should be                  711  
                  declared PHONY.                               
  phonydeclared   Target "ctags" should be                 742  
                  declared PHONY.                               
  phonydeclared   Target "cscopelist" should be            761  
                  declared PHONY.                               
  phonydeclared   Target "installdirs" should be          1060  
                  declared PHONY.                               
  phonydeclared   Target "uninstall" should be            1070  
                  declared PHONY.                               
  phonydeclared   Target "installcheck" should            1075  
                  be declared PHONY.                            
  phonydeclared   Target "clean" should be                1121  
                  declared PHONY.                               
  phonydeclared   Target "dvi" should be                  1131  
                  declared PHONY.                               
  phonydeclared   Target "html" should be                 1135  
                  declared PHONY.                               
  phonydeclared   Target "info" should be                 1139  
                  declared PHONY.                               
  phonydeclared   Target "mostlyclean" should be          1178  
                  declared PHONY.                               
  phonydeclared   Target "pdf" should be                  1182  
                  declared PHONY.                               
  phonydeclared   Target "ps" should be declared          1186  
                  PHONY.                                        

Output of make --version

GNU Make 4.3

Sample Makefile to reproduce issue

Any autotools generated GNU Makefile

(some of these things might not apply but the more you can provide the easier
it will be to fix this bug. Thanks!)

Build Error

I am getting this error while installation

$ go get github.com/mrtazz/checkmake
$ cd $GOPATH/src/github.com/mrtazz/checkmake
$ make
install -d .d
echo "checkmake: $(go list -f '{{ join .Deps "\n" }}' cmd/checkmake/main.go | awk '/github/ { gsub(/^github.com\/[a-z]*\/[a-z]*\//, ""); printf $0"/*.go " }')" > .d/checkmake.d
go build -ldflags "-X 'main.version=0.1.0-14-gff21564' -X 'main.buildTime=2018-12-29T10:48:02Z' -X 'main.builder=Nikhil Agarwal <[email protected]>'-X 'main.goversion=go version go1.10.3 gccgo (Ubuntu 8.2.0-1ubuntu2~18.04) 8.2.0 linux/amd64'" -o checkmake cmd/checkmake/main.go
go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags
sed "s/REPLACE_DATE/December 29, 2018/" man/man1/checkmake.1.md | pandoc -s -t man -o checkmake.1

Should I modify the makefile?

Support PHONY variable

Support:

PHONY += all
all:
   true
   
.PHONY: ${PHONY}

It currently gives the error:
Target "all" should be declared PHONY

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.