Skip to content

Instantly share code, notes, and snippets.

@Shuyib
Last active April 1, 2024 07:12
Show Gist options
  • Save Shuyib/ae87774fd82c69706803725db9a681dc to your computer and use it in GitHub Desktop.
Save Shuyib/ae87774fd82c69706803725db9a681dc to your computer and use it in GitHub Desktop.
Data science and Machine learning Makefile for Python projects or in general :)
# Thank you @Earthly https://www.youtube.com/watch?v=w2UeLF7EEwk
# Can be adapted to pipenv, and poetry
# Other languages coming soon especially R and Julia
# .ONESHELL tells make to run each recipe line in a single shell
.ONESHELL:
# .DEFAULT_GOAL tells make which target to run when no target is specified
.DEFAULT_GOAL := all
# Specify python location in virtual environment
# Specify pip location in virtual environment
PYTHON := .venv/bin/python3
PIP := .venv/bin/pip3
venv/bin/activate: requirements.txt
# create virtual environment
python3 -m venv .venv
# make command executable
chmod +x .venv/bin/activate
# activate virtual environment
. .venv/bin/activate
activate:
# activate virtual environment
. .venv/bin/activate
install: venv/bin/activate requirements.txt # prerequisite
# install commands
$(PIP) --no-cache-dir install --upgrade pip &&\
$(PIP) --no-cache-dir install -r requirements.txt
docstring: activate
# format docstring
pyment -w -o numpydoc *.py
format: activate
# format code
black *.py utils/*.py testing/*.py
clean:
# clean directory of cache
rm -rf __pycache__ &&\
rm -rf utils/__pycache__ &&\
rm -rf testing/__pycache__ &&\
rm -rf .pytest_cache &&\
rm -rf .venv
lint: activate install format
# flake8 or #pylint
pylint --disable=R,C --errors-only *.py utils/*.py testing/*.py
setup_readme: ## Create a README.md
@if [ ! -f README.md ]; then \
echo "# Project Name\n\
Description of the project.\n\n\
## Installation\n\
- Step 1\n\
- Step 2\n\n\
## Usage\n\
Explain how to use the project here.\n\n\
## Contributing\n\
Explain how to contribute to the project.\n\n\
## License\n\
License information." > README.md; \
echo "README.md created."; \
else \
test: activate install format
# test
$(PYTHON) -m pytest testing/*.py
run: activate install format lint
# run application
# example $(PYTHON) app.py
docker_build: Dockerfile
# build container
#docker build -t plot-timeseries-app:v0 .
docker_run_test: Dockerfile
# linting Dockerfile
docker run --rm -i hadolint/hadolint < Dockerfile
docker_clean: Dockerfile
# remove dangling images, containers, volumes and networks
docker system prune -a
docker_run: Dockerfile docker_build
# run docker
# docker run -e ENDPOINT_URL -e SECRET_KEY -e SPACES_ID -e SPACES_NAME plot-timeseries-app:v0
docker_push: docker_build
# push to registry
# docker tag <my-image> registry.digitalocean.com/<my-registry>/<my-image>
# docker push registry.digitalocean.com/<my-registry>/<my-image>
# .PHONY tells make that these targets do not represent actual files
.PHONY: activate format clean lint test build run docker_build docker_run docker_push docker_clean docker_run_test
all: install format lint test run docker_build docker_run docker_push
@Shuyib
Copy link
Author

Shuyib commented Apr 26, 2023

Template for R needs edits.

# Thank you @Earthly https://www.youtube.com/watch?v=w2UeLF7EEwk
# Can be adapted to pipenv, and poetry
# Other languages coming soon especially R and Julia

# .ONESHELL tells make to run each recipe line in a single shell
.ONESHELL:

# .DEFAULT_GOAL tells make which target to run when no target is specified
.DEFAULT_GOAL := all

initialize_packrat_R:
	# initialize packrat
	# run in R console: packrat init
	# Rscript -e "packrat::init(options = list(use.cache = TRUE, use.lockfile = TRUE, use.snapshot = TRUE))"
  
activate: 
	# activate packrat
	# Rscript -e "packrat::on()"

install: activate
	# Rscript -e "packrat::restore()"
    
docstring: activate
	# format docstring with docstring function in R
	# Rscript -e "docstring::docstring()"

  
format: activate 
	# format R code
	# Rscript -e "styler::style_dir(path = '.', filetype = 'R', recursive = TRUE, quiet = TRUE)"
  
clean:
	# clean directory of cache
	#rm -rf .Rproj.user/ .Rhistory .RData .Rapp.history .RData .RDataTmp .RDataTmp.lock .RDataTmp* .RDataTmp.lock* .RDataTmp* .RDataTmp.lock* .Rhistory .Rhistory.lock .Rhistory.lock* .Rhistory* .Rhistory.lock* .RDataTmp .RDataTmp.lock .RDataTmp* .RDataTmp.lock*
  
lint: activate install format
	# lint R code
	# Rscript -e "lintr::lint_dir(path = '.', format = 'stylish', linters = lintr::with_defaults(line_length_linter(120)))"
  
test: activate install format
	# test R code
	# Rscript -e "devtools::test()"
  
run: activate install format
	# run application in R console or shiny server
	# Rscript -e "source('app.R')"
	# shiny::runApp('app.R')
  
docker_build: Dockerfile
	# build container
	#docker build -t plot-timeseries-app:v0 .
  
docker_run_test: Dockerfile
	# linting Dockerfile
	docker run --rm -i hadolint/hadolint < Dockerfile

docker_clean: Dockerfile 
	# remove dangling images, containers, volumes and networks
	docker system prune -a

docker_run: docker_build
	# run docker
	# docker run -e ENDPOINT_URL -e SECRET_KEY -e SPACES_ID -e SPACES_NAME plot-timeseries-app:v0

docker_push: docker_build
  # push to registry
  # docker tag <my-image> registry.digitalocean.com/<my-registry>/<my-image>
  # docker push registry.digitalocean.com/<my-registry>/<my-image>  


# .PHONY tells make that these targets do not represent actual files
.PHONY: activate format clean lint test build run docker_build docker_run docker_push docker_clean docker_run_test
  
all: install format lint test run docker_build docker_run docker_push

@Shuyib
Copy link
Author

Shuyib commented Apr 26, 2023

Template for Julia needs edits

# Thank you @Earthly https://www.youtube.com/watch?v=w2UeLF7EEwk
# Can be adapted to pipenv, and poetry
# Other languages coming soon especially R and Julia

# .ONESHELL tells make to run each recipe line in a single shell
.ONESHELL:

# .DEFAULT_GOAL tells make which target to run when no target is specified
.DEFAULT_GOAL := all

# Specify julia version virtual environment
venv/bin/activate: 
	# create virtual environment
	julia -e 'using Pkg; Pkg.add("VirtualEnvironments"); using VirtualEnvironments; VirtualEnvironments.build()'
  
activate:
	# activate virtual environment
	julia -e 'using Pkg; Pkg.activate("."); Pkg.instantiate()'

install: venv/bin/activate  # prerequisite
	# install common packages
	julia -e 'using Pkg; Pkg.add("PyCall"); Pkg.add("PyPlot"); Pkg.add("Statistics")
    
docstring: activate
	# format docstrings
	julia -e 'using Pkg; Pkg.add("Documenter"); using Documenter; Documenter.generate("docs")'
  
format: activate 
	# format code
	julia -e 'using Pkg; Pkg.add("JuliaFormatter"); using JuliaFormatter; format("src")'
  
clean:
	# clean directory of cache files
	julia -e 'using Pkg; Pkg.gc()'

lint: activate install format
	# lint code
	julia -e 'using Pkg; Pkg.add("Lint"); using Lint; lint("src")'
  
test: activate install format
	# test code
	julia -e 'using Pkg; Pkg.add("Test"); using Test; include("test/runtests.jl")'
  
run: activate install format
	# run julia script
	julia src/main.jl
  
docker_build: Dockerfile
	# build julia container
	#docker build -t plot-timeseries-app:v0 .
  
docker_run_test: Dockerfile
	# linting Dockerfile
	docker run --rm -i hadolint/hadolint < Dockerfile

docker_clean: Dockerfile docker_build
	# remove dangling images, containers, volumes and networks
	docker system prune -a
  
docker_run: build
	# run docker
	# docker run -e ENDPOINT_URL -e SECRET_KEY -e SPACES_ID -e SPACES_NAME plot-timeseries-app:v0

docker_push: docker_build
  # push to registry
  # docker tag <my-image> registry.digitalocean.com/<my-registry>/<my-image>
  # docker push registry.digitalocean.com/<my-registry>/<my-image>  


# .PHONY tells make that these targets do not represent actual files
.PHONY: activate format clean lint test build run docker_build docker_run docker_push docker_clean docker_run_test
  
all: install format lint test run docker_build docker_run docker_push

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment