Giter VIP home page Giter VIP logo

.makefiles's Introduction

.makefiles

Automate everything with Makefile

Makefile basics

Creating a Makefile

$ touch Makefile

Hello World

In your Makefile:

greet:
	echo hello world
$ make greet
> hello world

Chaining Commands

You can chain commands in Makefile:

greet: bid
	echo hello

bid:
	echo bye

This is especially useful when you have multiple steps involved, e.g. building and deploying a container:

deploy: build tag push
	echo deploying

build:
	echo building image

tag:
	echo tagging the image

push: 
	echo pushing to dockerhub

Suppressing command output

To suppress the command being executed, add @ before the command:

greet:
	@echo hello

Using environment variables

You can pass environment variables into Makefile when running the command:

greet:
	@echo Hi, $(NAME)!

Running the greet command:

$ NAME=john make greet
> Hi, john!

This is useful if you need to use Makefile to configure builds for certain environment, e.g. ENV=prod make build.

Loading environment variables from file

Makefile can also load environment variables from .env file

include .env
export

If you want to make it optional, add the minus sign before include. Otherwise, an error will occur:

-include .env
export

The export will export all available environment variables in the Makefile.

You can include as many .env files as you want, the order matters though:

.env.development
.env # This will overwrite any values that already existed in .env.development
export

Loading enviroment variables dynamically

You can also load environment variables dynamically:

ENV ?= development    # Defaults to development.
-include .env         # Include the base environment.
-include .env.$(ENV)  # Will load based on your current environment, and overrides the values in base environment file.
export

greet:
    echo Running in $(ENV)

Run:

$ make greet ENV=development
> Running in development

$ make greet ENV=production
> Running in production

Environment guards

Say if we only want to ensure that certain command can only be run in certain environment:

ENV ?= development
-include .env
-include .env.$(ENV)
export

deploy: prod-only
	@echo deploying to production

prod-only:
ifneq ($(ENV),production)
	$(error ENV must be production)
endif

Run:

$ make deploy
> Makefile:6: *** ENV must be production.  Stop.

$ make deploy ENV=production
> deploying to production

You can make a CLI with your Makefile

.PHONY: help
help:
	@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)

.DEFAULT_GOAL := help

vendor: ## Vendor the application
	@echo vendoring...

Just run make without any commands, it will print the command and the description.

Useful variables

PROJECTNAME := $(shell basename $(PWD))
COMMIT=$(shell git rev-parse HEAD)
BRANCH=$(shell git rev-parse --abbrev-ref HEAD)
BUILD_DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
CURRENT_DIR=$(shell pwd)
VERSION := $(shell git describe --tags --abbrev=0)

COLOR="\033[32;1m"
ENDCOLOR="\033[0m"

Using dynamic variables in command

# To override just a single environment variable inline.
deploy:
	@echo ${A}

# make deploy-staging
# make deploy-production
deploy-%: .env.%
	@$(MAKE) deploy ENV=$*

Modular Makefiles

You can separate your Makefiles into smaller Makefiles. This promote reusability, while keeping your Makefile small. Say you have the following Makefiles:

In database/Makefile:

start:
	@echo starting db
  
stop:
	@echo stopping db

In docker/Makefile:

IMG := alextanhongpin/api
build:
  @docker build -t $(IMG) .
  
up:
  @docker-compose up -d
  
down:
  @docker-compose down

You can now include them in your main Makefile at the root of your project directory:

include docker/Makefile
include database/Makefile

greet:
	echo greet

And you can run all the commands that are available in docker/Makefile and database/Makefile:

$ make up
$ make down
$ make start
$ make stop

The only disadvantage is that the naming of the command cannot be the same.

Read Input

You can read input in makefiles too. The example below copies an existing folder and rename all the variables/classes for code reuse:

service: # Clones the currency folder, and replaces all the name with given name.
	@read -p "Enter folder name: " folder; \
	read -p "Enter class name: " class; \
	read -p "Enter singular name: " singular; \
	read -p "Enter pluralize name: " plural; \
	cp -r src/currency src/$$folder; \
	sed -i "" "s/Currency/$$class/g" src/$$folder/**.ts; \
	sed -i "" "s/currency/$$singular/g" src/$$folder/**.ts; \
	sed -i "" "s/currencies/$$plural/g" src/$$folder/**.ts;

.makefiles's People

Contributors

alextanhongpin avatar

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.