Web Development Blog

Developer Remarks | Know & How

Makefile as an Operational Index in Laravel development

Created At: Updated At:

Introduction

Laravel already gives for web project several command surfaces: Artisan, Composer scripts, npm scripts, and even a small admin-facing interface for a restricted set of Artisan commands. So the obvious question is why this repository still keeps a top-level Makefile.

During development, many other commands are still needed, either as commands from the terminal or in the form of bash (zsh) scripts. The sum of all such commands and their structure brings problems:

  • with remembering their definition
  • with the length of the command line (requiring many keystrokes on the keyboard)
  • with executing the command in the right place (directory) in the application structure A very practical solution is to use "make" as a shell language to support development acting as a thin coordination layer over the commands the developer clearly runs often: route inspection, cache resets, log cleanup, grouped test execution, static analysis, and a few environment-specific checks.

It means the Makefile is the approved command surface for repetitive development work inside the editor.

This article walks through what the current Makefile actually does, why these targets exist, and what the file says about how this Laravel project is operated.

So the Makefile is not just convenience glue. It expresses which operations are considered normal for daily development, and which ones stay outside that surface.

Practical example of a Makefile used for development

The described Makefile is a shortened example of the most commonly used commands when developing Laravel applications using Docker or VirtualBox on Windows 11. The Makefile below is used in the Debian 13 environment for different workspaces (development, preparation for deployment, staging). For this reason, shared files tools.mk (common commands for all workspaces) and tools-special.mk are used.

Makefile for development workspace

## Makefile for usefull scripts in Laravel11 Blog project
## cmd:  make
.PHONY: help copy test module

CURRENT=$(shell date +'_%g%m%d')
export STAMP:=$(CURRENT)

# Include common targets from tools*.mk
include /var/www/tools.mk
include /var/www/tools-special.mk

checklinks: ## check for broken links in the project (install broken-link-checker globally with npm install -g broken-link-checker)
	npx broken-link-checker http://192.168.0.175:81 --recursive --ordered --filter-level 2

list: ## show routes (all - no param | filter - add param: name="crop")
	@if [ -n "$(name)" ]; then \
		php artisan route:list --name "$(name)"; \
	else \
		php artisan route:list; \
	fi

listv: ## show all routes incl. middleware (all - no param | filter - add param: name="crop")
	@if [ -n "$(name)" ]; then \
		php artisan route:list --name "$(name)" --verbose; \
	else \
		php artisan route:list --verbose; \
	fi

rlog: ## reset laravel log to empty content
	truncate -s 0 storage/logs/laravel.log

rc: ## reset all laravel caches
	php artisan optimize:clear

run: ## run phpunit tests for group run
	vendor/bin/phpunit --group run --testdox

runz: ## run phpunit tests for group runz (all - no param | filter - add param e.g. filter="unzip")
	@if [ -n "$(filter)" ]; then \
		vendor/bin/phpunit --group runz --filter "$(filter)" --testdox; \
	else \
		vendor/bin/phpunit --group runz --testdox; \
	fi  

stan: ## run phpstan
	./vendor/bin/phpstan analyse

tools.mk

## Unified Makefile — Common targets only
## Generated: 2026-04-03

.PHONY: help chown rc list listv run runz testm scomposer crm cpkg vscext stan

CURRENT=$(shell date +'_%g%m%d')
export STAMP:=$(CURRENT)

help: ## Tools makefile targets HELP
	@echo ""
	@echo "Makefile for useful scripts in Laravel11 Blog project"
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m<target>\033[0m\n\nTargets:\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf "  \033[36m%-10s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)

---: ## COMMON TARGETS

chown: ## set all project files for owner 'www-data:www-data' with 755
	chown -R www-data:www-data .
	chmod -R 755 .

chownacl: ## set all project files for owner 'www-data:www-data' with ACL
	setfacl -R -m u:www-data:rwx .
	setfacl -R -m d:u:www-data:rwx .
	setfacl -R -m u:vacal:rwx .
	setfacl -R -m d:u:vacal:rwx .

size: ## show disk usage of current folder in human readable format with depth 1
	du -ha -d 1 | sort -h

tools-special.mk

## Unified Makefile — Special targets (unique usage)
## Generated: 2026-04-04

---: ## SPECIAL TARGETS (development)

websnap: ## create web snapshot with mobile-check.mjs script
	node tests/web/scripts/mobile-check.mjs

webqa: ## run mobile-qa-report.mjs tests (Mobile QA Checklist)
	node tests/web/scripts/mobile-qa-report.mjs

webtap: ## run small tap target tests with check-tap-targets.js
	node tests/web/check-tap-targets.js

That structure tells you several things immediately:

  1. Only application-specific commands stay in the local Makefile.
  2. The file is designed to be read by humans, not just executed by CI.

The shared include layer is important here. The loaded common makefile provides the help target, so plain make functions more like an operational menu than a build step.

Here is terminal output for command make:

Makefile for useful scripts in Laravel11 Blog project

Usage:
  make <target>

Targets:
  checklinks  check for broken links in the project (install broken-link-checker globally with npm install -g broken-link-checker)
  list        show routes (all - no param | filter - add param: name="crop")
  listv       show all routes incl. middleware (all - no param | filter - add param: name="crop")
  rlog        reset laravel log to empty content
  rc          reset all laravel caches
  run         run phpunit tests for group run
  runz        run phpunit tests for group runz (all - no param | filter - add param e.g. filter="unzip")
  stan        run phpstan
  testm       create module (Feature) test with test="<TestName>" module="<ModuleName>"
  help        Tools makefile targets HELP
  ---         COMMON TARGETS
  chown       set all project files for owner 'www-data:www-data' with 755
  chownacl    set all project files for owner 'www-data:www-data' with ACL
  size        show disk usage of current folder in human readable format with depth 1
  vscext      create vscode-extensions.txt file with all installed extensions
  ---         SPECIAL TARGETS (development)
  scomposer   run composer as www-data user
  crm         remove existing package from composer
  cpkg        copy vendor package importobsidian to /packages/jotcomp
  websnap     create web snapshot with mobile-check.mjs script
  webqa       run mobile-qa-report.mjs tests (Mobile QA Checklist)
  webtap      run small tap target tests with check-tap-targets.js

Remarks to Testing Commands

The most revealing part of the Makefile is the testing split:

run: ## run phpunit tests for group run
	vendor/bin/phpunit --group run --testdox

runz: ## run phpunit tests for group runz (all - no param | filter - add param e.g. filter="unzip")
	@if [ -n "$(filter)" ]; then \
		vendor/bin/phpunit --group runz --filter "$(filter)" --testdox; \
	else \
		vendor/bin/phpunit --group runz --testdox; \
	fi

This is not generic Laravel practice. It is repository-specific and based on PHPUnit group attributes.

The existing suite contains many tests marked with Group('run') across controllers, services, models, security, and ZIP-import-related flows. That makes make run the stable test lane (for all approved tests).

The runz lane appears in repository prompt guidance for new feature developemnt work. New or modified tests are expected to carry Group('runz') so they can be validated quickly with make runz during active development. At the moment, the repository visibly contains many run tests but no current runz annotations in the inspected test tree. That suggests runz is intended as a fast-moving work-in-progress lane rather than a permanently populated bucket.

The two-lane setup gives the maintainer both a stable baseline and a place for focused current-work verification.

Summary

This project's Makefile is not an alternative interface to Laravel. It is a small operational index for the commands that matter most in this specific repository.

Its value comes from four things:

  1. It standardizes the commands the project actually uses.
  2. It encodes repository policy around testing and editor-safe workflows.
  3. It reflects the real shape of the application: admin-heavy, package-extended, and operationally maintained.
  4. It accepts environment-specific assumptions instead of hiding them behind fake portability.

A useful Makefile does not need to be universal. It needs to reduce friction in the environment where the work actually happens. In this repository, that is exactly what it does.

Random Posts

Migrating TinyMCE from v5.9 to v8.3 - Part 2

Published At:

The Migration Strategy: Self-Hosted TinyMCE with Static Copy

Instead of fighting Vite's module bundler, the solution uses a hybrid approach: TinyMCE is loaded as a traditional global script, while only the configuration runs through Vite.

Step 1: Remove TinyMCE from npm, Use Self-Hosted Distribution

Download TinyMCE 8 Community (GPL) from the official download page and place the full distribution...

Read More

Laravel - how to deploy code changes on hosted server

Published At: Updated At: 2025-07-24

It is recommended to do an initial installation on hosted server without all dev packages and tools. The best approach is to prepare a local docker installation where it is possible to run composer and NPM. For this purpose, we can use an intermediate server for clean code generation in PHP and css/js. The server is also used for final testing of the application before a transfer of cleaned code to the live server.

In order to have the closest possible conditions for running the...

Read More

Random Categories

Web Development - Web Development Blog
Web Development
Web blog development and deployment based on Laravel framework is not easy and requires other approach to applicationĀ  structure and development. Laravel is not best suited for web blogs but the application was chosen here for practical evaluation and comparision.
Web Design - Web Development Blog
Web Design
Blog category dealing with Web structure, Web templates, Navigation, Elements, Typography, Media, Icons, Components, Forms, Responsive design and Dynamic content.
Open Source Software - Web Development Blog
Open Source Software
Remarks and notes to a practical usage of OSS for web frontend and backend. Many years of experience with Joomla, Drupal, Wordpress, Laravel, javascript, Vue.js opens very interesting views on development and deployment details.