Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
## [2.2.7] - 2026-01-04

### Added
- **PHPStan module**: New standalone module for PHPStan static analysis
- `php/phpstan/analyse` - Run PHPStan analysis
- `php/phpstan/staged` - Run PHPStan on staged PHP files only
- Configuration options: `phpstan_level`, `phpstan_memory_limit`
- Runtime variables: `phpstan_files=` for paths, `phpstan_args=` for extra options
- Depends on `php` module
- **Psalm module**: New standalone module for Psalm static analysis
- `php/psalm/analyse` - Run Psalm analysis
- `php/psalm/staged` - Run Psalm on staged PHP files only
- Configuration options: `psalm_threads`
- Runtime variables: `psalm_files=` for paths, `psalm_args=` for extra options
- Depends on `php` module

### Changed
- **PHP module**: Removed old `php/phpstan` and `php/psalm` targets (now in separate modules)

## [2.2.6] - 2026-01-03

### Added
Expand Down
14 changes: 0 additions & 14 deletions modules/php/php/php.mk
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,6 @@ php/dc/logs: ## Show php container logs

endif

php/phpstan: mb/info-$$@ := Running PHPStan
php/phpstan: ## Run PHPStan to phpstan.output
$(call php_invoke,$(phpstan_bin) analyse \
--configuration=$(phpstan_config_file) \
$(if $(phpstan_send_to_file),--error-format=github > $(phpstan_output_file)) \
|| true \
)

php/psalm: ## Run Psalm to psalm.output
$(call php_invoke,$(psalm_bin) $(psalm_flags) \
$(if $(psalm_send_to_file),> $(psalm_output_file)) \
|| true \
)

endif # __MB_MODULES_PHP_TARGETS__

endif # __MB_MODULES_PHP__
Expand Down
17 changes: 17 additions & 0 deletions modules/php/phpstan/mod_config.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Path to PHPStan binary
phpstan_bin ?= vendor/bin/phpstan#

## Path to phpstan configuration file
phpstan_config ?= phpstan.neon#

## Analysis level (0-9, empty = use config file setting)
phpstan_level ?=#

## Memory limit (e.g., 512M, 1G)
phpstan_memory_limit ?=#

## If true, send output to file instead of stdout
phpstan_send_to_file ?= $(mb_true)#

## Output file for phpstan results
phpstan_output_file ?= phpstan.output#
6 changes: 6 additions & 0 deletions modules/php/phpstan/mod_info.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
mb_module_name := phpstan
mb_module_version := 1.0.0
mb_module_description := PHPStan static analysis module for MakeBind
mb_module_author := AntonioCS
mb_module_license := MIT
mb_module_depends := php
49 changes: 49 additions & 0 deletions modules/php/phpstan/phpstan.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#####################################################################################
# Project: MakeBind
# File: modules/php/phpstan/phpstan.mk
# Description: PHPStan static analysis module for MakeBind
# Author: AntonioCS
# License: MIT License
#####################################################################################
ifndef __MB_MODULES_PHP_PHPSTAN__
__MB_MODULES_PHP_PHPSTAN__ := 1

## Internal function to build phpstan command arguments
## @returns Common arguments for phpstan
define phpstan_build_args
$(strip
$(eval $0_args :=)
$(eval
$0_args += $(if $(wildcard $(phpstan_config)),--configuration=$(phpstan_config))
$0_args += $(if $(phpstan_level),--level=$(phpstan_level))
$0_args += $(if $(phpstan_memory_limit),--memory-limit=$(phpstan_memory_limit))
$0_args += $(if $(value phpstan_args),$(phpstan_args))
$0_args += $(if $(value phpstan_files),$(phpstan_files))
)
$(strip $($0_args))
)
endef

## Skip target definitions when loaded dynamically (e.g., during test discovery)
ifndef __MB_TEST_DISCOVERY__

## Verify php module is loaded (check once at module level)
$(if $(value php_invoke),,$(error phpstan module requires php module - please add php module first))

php/phpstan/analyse: ## Run PHPStan analysis (phpstan_files= for paths, phpstan_args= for extra options)
$(eval $@_cmd := $(phpstan_bin) analyse $(call phpstan_build_args))
$(if $(call mb_is_true,$(phpstan_send_to_file)),\
$(eval $@_cmd += > $(phpstan_output_file) 2>&1 || true)\
$(call mb_printf_info,Running phpstan and sending output to $(phpstan_output_file))\
)
$(call php_invoke,$($@_cmd))
$(if $(call mb_is_true,$(phpstan_send_to_file)),\
$(call mb_printf_info,Results saved to $(phpstan_output_file))\
)

php/phpstan/staged: ## Run PHPStan on staged PHP files only
$(call mb_run_on_staged,php,$(call php_invoke,$(phpstan_bin) analyse))

endif # __MB_TEST_DISCOVERY__

endif # __MB_MODULES_PHP_PHPSTAN__
91 changes: 91 additions & 0 deletions modules/php/phpstan/phpstan_test.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#####################################################################################
# Project: MakeBind
# File: modules/php/phpstan/phpstan_test.mk
# Description: Tests for the phpstan module
# Author: AntonioCS
# License: MIT License
#####################################################################################

include $(mb_core_path)/util.mk
include $(mb_core_path)/functions.mk

## Load config to define variables
include $(mb_modules_path)/php/phpstan/mod_config.mk

######################################################################################
# Configuration tests
######################################################################################

define test_modules_phpstan_config_defaults
$(call mb_assert_eq,vendor/bin/phpstan,$(phpstan_bin),phpstan_bin should default to vendor/bin/phpstan)
$(call mb_assert_eq,phpstan.neon,$(phpstan_config),phpstan_config should default to phpstan.neon)
$(call mb_assert_eq,$(mb_true),$(phpstan_send_to_file),phpstan_send_to_file should default to mb_true)
$(call mb_assert_eq,phpstan.output,$(phpstan_output_file),phpstan_output_file should default to phpstan.output)
$(call mb_assert_empty,$(phpstan_level),phpstan_level should be empty by default)
$(call mb_assert_empty,$(phpstan_memory_limit),phpstan_memory_limit should be empty by default)
endef

######################################################################################
# phpstan_build_args tests
######################################################################################

## Need to include the main module for function tests
include $(mb_modules_path)/php/phpstan/phpstan.mk

define test_modules_phpstan_build_args_empty
$(eval phpstan_config := nonexistent.neon)
$(eval $0_result := $(call phpstan_build_args))
$(call mb_assert_empty,$($0_result),Should return empty when no config and no options)
$(eval phpstan_config := phpstan.neon)
endef

define test_modules_phpstan_build_args_with_level
$(eval phpstan_level := 8)
$(eval phpstan_config := nonexistent.neon)
$(eval $0_result := $(call phpstan_build_args))
$(call mb_assert_eq,--level=8,$($0_result),Should include level option)
$(eval phpstan_level :=)
$(eval phpstan_config := phpstan.neon)
endef

define test_modules_phpstan_build_args_with_memory_limit
$(eval phpstan_memory_limit := 512M)
$(eval phpstan_config := nonexistent.neon)
$(eval $0_result := $(call phpstan_build_args))
$(call mb_assert_eq,--memory-limit=512M,$($0_result),Should include memory-limit option)
$(eval phpstan_memory_limit :=)
$(eval phpstan_config := phpstan.neon)
endef

define test_modules_phpstan_build_args_with_files
$(eval phpstan_files := src/Controller/)
$(eval phpstan_config := nonexistent.neon)
$(eval $0_result := $(call phpstan_build_args))
$(call mb_assert_eq,src/Controller/,$($0_result),phpstan_files should be included)
$(eval phpstan_files :=)
$(eval phpstan_config := phpstan.neon)
endef

define test_modules_phpstan_build_args_runtime_args
$(eval phpstan_args := --no-progress --error-format=json)
$(eval phpstan_config := nonexistent.neon)
$(eval $0_result := $(call phpstan_build_args))
$(call mb_assert_eq,--no-progress --error-format=json,$($0_result),Runtime phpstan_args should be included)
$(eval phpstan_args :=)
$(eval phpstan_config := phpstan.neon)
endef

define test_modules_phpstan_build_args_all_options
$(eval phpstan_level := 5)
$(eval phpstan_memory_limit := 1G)
$(eval phpstan_args := --no-progress)
$(eval phpstan_files := src/)
$(eval phpstan_config := nonexistent.neon)
$(eval $0_result := $(call phpstan_build_args))
$(call mb_assert_eq,--level=5 --memory-limit=1G --no-progress src/,$($0_result),All options should be combined)
$(eval phpstan_level :=)
$(eval phpstan_memory_limit :=)
$(eval phpstan_args :=)
$(eval phpstan_files :=)
$(eval phpstan_config := phpstan.neon)
endef
14 changes: 14 additions & 0 deletions modules/php/psalm/mod_config.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Path to Psalm binary
psalm_bin ?= vendor/bin/psalm#

## Path to psalm configuration file
psalm_config ?= psalm.xml#

## Number of threads to use (empty = use default)
psalm_threads ?=#

## If true, send output to file instead of stdout
psalm_send_to_file ?= $(mb_true)#

## Output file for psalm results
psalm_output_file ?= psalm.output#
6 changes: 6 additions & 0 deletions modules/php/psalm/mod_info.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
mb_module_name := psalm
mb_module_version := 1.0.0
mb_module_description := Psalm static analysis module for MakeBind
mb_module_author := AntonioCS
mb_module_license := MIT
mb_module_depends := php
48 changes: 48 additions & 0 deletions modules/php/psalm/psalm.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#####################################################################################
# Project: MakeBind
# File: modules/php/psalm/psalm.mk
# Description: Psalm static analysis module for MakeBind
# Author: AntonioCS
# License: MIT License
#####################################################################################
ifndef __MB_MODULES_PHP_PSALM__
__MB_MODULES_PHP_PSALM__ := 1

## Internal function to build psalm command arguments
## @returns Common arguments for psalm
define psalm_build_args
$(strip
$(eval $0_args :=)
$(eval
$0_args += $(if $(wildcard $(psalm_config)),--config=$(psalm_config))
$0_args += $(if $(psalm_threads),--threads=$(psalm_threads))
$0_args += $(if $(value psalm_args),$(psalm_args))
$0_args += $(if $(value psalm_files),$(psalm_files))
)
$(strip $($0_args))
)
endef

## Skip target definitions when loaded dynamically (e.g., during test discovery)
ifndef __MB_TEST_DISCOVERY__

## Verify php module is loaded (check once at module level)
$(if $(value php_invoke),,$(error psalm module requires php module - please add php module first))

php/psalm/analyse: ## Run Psalm analysis (psalm_files= for paths, psalm_args= for extra options)
$(eval $@_cmd := $(psalm_bin) $(call psalm_build_args))
$(if $(call mb_is_true,$(psalm_send_to_file)),\
$(eval $@_cmd += > $(psalm_output_file) 2>&1 || true)\
$(call mb_printf_info,Running psalm and sending output to $(psalm_output_file))\
)
$(call php_invoke,$($@_cmd))
$(if $(call mb_is_true,$(psalm_send_to_file)),\
$(call mb_printf_info,Results saved to $(psalm_output_file))\
)

php/psalm/staged: ## Run Psalm on staged PHP files only
$(call mb_run_on_staged,php,$(call php_invoke,$(psalm_bin)))

endif # __MB_TEST_DISCOVERY__

endif # __MB_MODULES_PHP_PSALM__
79 changes: 79 additions & 0 deletions modules/php/psalm/psalm_test.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#####################################################################################
# Project: MakeBind
# File: modules/php/psalm/psalm_test.mk
# Description: Tests for the psalm module
# Author: AntonioCS
# License: MIT License
#####################################################################################

include $(mb_core_path)/util.mk
include $(mb_core_path)/functions.mk

## Load config to define variables
include $(mb_modules_path)/php/psalm/mod_config.mk

######################################################################################
# Configuration tests
######################################################################################

define test_modules_psalm_config_defaults
$(call mb_assert_eq,vendor/bin/psalm,$(psalm_bin),psalm_bin should default to vendor/bin/psalm)
$(call mb_assert_eq,psalm.xml,$(psalm_config),psalm_config should default to psalm.xml)
$(call mb_assert_eq,$(mb_true),$(psalm_send_to_file),psalm_send_to_file should default to mb_true)
$(call mb_assert_eq,psalm.output,$(psalm_output_file),psalm_output_file should default to psalm.output)
$(call mb_assert_empty,$(psalm_threads),psalm_threads should be empty by default)
endef

######################################################################################
# psalm_build_args tests
######################################################################################

## Need to include the main module for function tests
include $(mb_modules_path)/php/psalm/psalm.mk

define test_modules_psalm_build_args_empty
$(eval psalm_config := nonexistent.xml)
$(eval $0_result := $(call psalm_build_args))
$(call mb_assert_empty,$($0_result),Should return empty when no config and no options)
$(eval psalm_config := psalm.xml)
endef

define test_modules_psalm_build_args_with_threads
$(eval psalm_threads := 4)
$(eval psalm_config := nonexistent.xml)
$(eval $0_result := $(call psalm_build_args))
$(call mb_assert_eq,--threads=4,$($0_result),Should include threads option)
$(eval psalm_threads :=)
$(eval psalm_config := psalm.xml)
endef

define test_modules_psalm_build_args_with_files
$(eval psalm_files := src/Controller/)
$(eval psalm_config := nonexistent.xml)
$(eval $0_result := $(call psalm_build_args))
$(call mb_assert_eq,src/Controller/,$($0_result),psalm_files should be included)
$(eval psalm_files :=)
$(eval psalm_config := psalm.xml)
endef

define test_modules_psalm_build_args_runtime_args
$(eval psalm_args := --no-progress --output-format=json)
$(eval psalm_config := nonexistent.xml)
$(eval $0_result := $(call psalm_build_args))
$(call mb_assert_eq,--no-progress --output-format=json,$($0_result),Runtime psalm_args should be included)
$(eval psalm_args :=)
$(eval psalm_config := psalm.xml)
endef

define test_modules_psalm_build_args_all_options
$(eval psalm_threads := 8)
$(eval psalm_args := --no-cache)
$(eval psalm_files := src/)
$(eval psalm_config := nonexistent.xml)
$(eval $0_result := $(call psalm_build_args))
$(call mb_assert_eq,--threads=8 --no-cache src/,$($0_result),All options should be combined)
$(eval psalm_threads :=)
$(eval psalm_args :=)
$(eval psalm_files :=)
$(eval psalm_config := psalm.xml)
endef