# -*- makefile-gmake -*-

# A spec template for a "minimal" package (can be used as a base for other pkgs):
# Do not set Epoch by default.
minimal_version ?= 1
minimal_release ?= alt1
# Do not set Disttag by default.
minimal_license ?= dummy license
minimal_group ?= Other
minimal_summary ?= dummy summy
minimal_arch ?= noarch
minimal_description ?= dummy desc
SIMPLE_FILE := /etc/rpminstall-tests/%name
minimal_files ?= $(SIMPLE_FILE)

define minimal_install

mkdir -p %buildroot`dirname $(SIMPLE_FILE)`
# Fill it with some unique value; each time new.
# (We rely on the fact that %%buildroot comes from mktemp.)
echo %buildroot >%buildroot$(SIMPLE_FILE)

endef

define minimal_preamble_etc :=

AutoReq: no
AutoProv: no

endef

ifeq (0,${MAKELEVEL})
TESTS_DEFAULT_ARCH := $(shell rpmbuild --eval %_arch 2>/dev/null ||:)
endif
export TESTS_DEFAULT_ARCH

# Params: 1 -- new pkg; 2 -- base spec template.
define mk_bin_rpm

$(1)_tmpl := $(or $(2),minimal)

# Set $(1)_name for genericity.
$(1)_name ?= $$(or $$($$($(1)_tmpl)_name),$(1))
# Empty Epoch will remain empty.
$(1)_epoch ?= $$($$($(1)_tmpl)_epoch)
$(1)_version ?= $$($$($(1)_tmpl)_version)
$(1)_release ?= $$($$($(1)_tmpl)_release)
# Empty Disttag will remain empty.
$(1)_disttag ?= $$($$($(1)_tmpl)_disttag)
$(1)_license ?= $$($$($(1)_tmpl)_license)
$(1)_group ?= $$($$($(1)_tmpl)_group)
$(1)_summary ?= $$($$($(1)_tmpl)_summary)
$(1)_arch ?= $$($$($(1)_tmpl)_arch)
$(1)_preamble_etc ?= $$($$($(1)_tmpl)_preamble_etc)
$(1)_description ?= $$($$($(1)_tmpl)_description)
$(1)_install ?= $$($$($(1)_tmpl)_install)
$(1)_files ?= $$($$($(1)_tmpl)_files)

clean::
	rm -f SPECS/$(1).spec

# A minimal RPM spec template extandable through Make vars.
# Without a %%files section, no RPM file would be made.
# So it must be here, if we have the RPM file as a target (see below).
SPECS/$(1).spec: $(MY)/HELPER
	mkdir -p SPECS
	cat >$$@ <<-'EOF'
		Name: $$($(1)_name)
		$$(if $$($(1)_epoch),Epoch: $$($(1)_epoch))
		Version: $$($(1)_version)
		Release: $$($(1)_release)
		License: $$($(1)_license)
		Group: $$($(1)_group)
		Summary: $$($(1)_summary)
		
		$$(if $$($(1)_arch),BuildArch: $$($(1)_arch))
		
		$$($(1)_preamble_etc)
		
		%description
		$$($(1)_description)
		
		$$(if $$($(1)_install),%install)
		$$($(1)_install)
		
		%files
		$$($(1)_files)
	EOF

######################################################################
# Shortcut vars with values to be used later
# (i.e., like some query results for the package and the path):
$(1)_VR = $$($(1)_version)-$$($(1)_release)
$(1)_EVR = $$(if $$($(1)_epoch),$$($(1)_epoch):)$$($(1)_VR)
$(1)_ARCH = $$(or $$($(1)_arch),$$(TESTS_TARGET),$$(TESTS_DEFAULT_ARCH))
$(1) = RPMS/$(1)/$$($(1)_ARCH)/$$($(1)_name)-$$($(1)_VR).$$($(1)_ARCH).rpm
######################################################################

clean::
	rm -rf RPMS/$(1)

# Different variables (like $(1)) may denote packages with the same name,
# therefore we must separate all the places used for building ($$$$TMPDIR)
# and saving them (RPMS/$(1)).
#
# We have to override the disttag value coming from ~/.rpmmacros;
# %nil seems to work for this purpose; at least,
# --qf='%{DISTTAG}\n' reports (none) then.
$$($(1)): SPECS/$(1).spec $(MY)/HELPER
	. tmpdir.sh
	rpmbuild $$(if $$(TESTS_TARGET),--target $$(TESTS_TARGET))\
	--define "_tmppath $$$$TMPDIR" \
	--define "_builddir $$$$TMPDIR/BUILD" \
	--define "_topdir $(PWD)" \
	--define '_sourcedir $(PWD)' --define '_specdir $(PWD)/SPECS' \
	--define '_srcrpmdir $(PWD)/SRPMS/$(1)' --define '_rpmdir $(PWD)/RPMS/$(1)' \
	\
	--define 'disttag $$(or $$($(1)_disttag),%nil)' \
	-bb $$<

# A target for anyone needing a later buildtime:
sleep_after_$(1): $$$$($(1))
	sleep 1
	touch $$@

clean::
	rm -f sleep_after_$(1)
endef

# In the rules below, the prerequisite packages might not yet be defined when
# the rules are inserted (because that depends on the order of inclusion of the files).
# Many $$$$ will help with .SECONDEXPANSION.
.SECONDEXPANSION:

define give_xfail_reason

export XFAIL_REASON_$(1) := $(2)
endef

installable_seq_tests = \
	$(addprefix installable_,\
		$(1)_with_$(2) \
		$(if $(SHORT),,\
			$(1)_before_$(2)))
define installable_seq

installable_$(1)_with_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -i $$($(1)) $$($(2))

installable_$(1)_before_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -i $$($(1))
	$$(RPM) -i $$($(2))

# Not defining the prerequisite pkgs is a way to skip these tests.
all_tests += $$(and $$($(1)),$$($(2)),\
		$(call installable_seq_tests,$(1),$(2)))
$(foreach t,$(call installable_seq_tests,$(1),$(2)),\
	$(call give_xfail_reason,$(t),$(3)))
endef

noninstallable_seq_tests = \
	$(addprefix noninstallable_,\
		$(1)_with_$(2) \
		$(if $(SHORT),,\
			$(1)_before_$(2)))
define noninstallable_seq

noninstallable_$(1)_with_$(2): $$$$($(1)) $$$$($(2))
	! $$(RPM) -i $$($(1)) $$($(2))

noninstallable_$(1)_before_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -i $$($(1))
	! $$(RPM) -i $$($(2))

# Not defining the prerequisite pkgs is a way to skip these tests.
all_tests += $$(and $$($(1)),$$($(2)),\
		$(call noninstallable_seq_tests,$(1),$(2)))
$(foreach t,$(call noninstallable_seq_tests,$(1),$(2)),\
	$(call give_xfail_reason,$(t),$(3)))
endef

installable_after_tests = \
	$(addprefix installable_,\
		$(if $(SHORT),,\
			$(1)_after_$(2)))
installable_tests = \
	$(call installable_seq_tests,$(1),$(2)) \
	$(call installable_after_tests,$(1),$(2))
define installable
$(call installable_seq,$(1),$(2),$(3))

installable_$(1)_after_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -i $$($(2))
	$$(RPM) -i $$($(1))

# Not defining the prerequisite pkgs is a way to skip these tests.
all_tests += $$(and $$($(1)),$$($(2)),\
		$(call installable_after_tests,$(1),$(2)))
$(foreach t,$(call installable_after_tests,$(1),$(2)),\
	$(call give_xfail_reason,$(t),$(3)))
endef

noninstallable_after_tests = \
	$(addprefix noninstallable_,\
		$(if $(SHORT),,\
			$(1)_after_$(2)))
noninstallable_tests = \
	$(call noninstallable_seq_tests,$(1),$(2)) \
	$(call noninstallable_after_tests,$(1),$(2))
define noninstallable
$(call noninstallable_seq,$(1),$(2),$(3))

noninstallable_$(1)_after_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -i $$($(2))
	! $$(RPM) -i $$($(1))

# Not defining the prerequisite pkgs is a way to skip these tests.
all_tests += $$(and $$($(1)),$$($(2)),\
		$(call noninstallable_after_tests,$(1),$(2)))
$(foreach t,$(call noninstallable_after_tests,$(1),$(2)),\
	$(call give_xfail_reason,$(t),$(3)))
endef

obsoleted_tests = \
	$(addprefix obsoleted_,\
	$(if $(SKIP_RPM_OBSOLETE_IN_TRANSACTION),\
			$(1)_before_$(2),\
		$(1)_with_$(2) \
		$(if $(SHORT),,\
			$(1)_updated_with_$(2) \
			$(1)_before_$(2) \
			$(1)_after_$(2))))
define obsoleted

obsoleted_$(1)_with_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -i $$($(1)) $$($(2))
	! $$(filter-out --justdb,$$(RPM)) -q $$($(1)_name)

obsoleted_$(1)_updated_with_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -U $$($(1)) $$($(2))
	! $$(filter-out --justdb,$$(RPM)) -q $$($(1)_name)

obsoleted_$(1)_before_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -i $$($(1))
	$$(RPM) -U $$($(2))
	! $$(filter-out --justdb,$$(RPM)) -q $$($(1)_name)

obsoleted_$(1)_after_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -i $$($(2))
	! $$(RPM) -i $$($(1))

# Not defining the prerequisite pkgs is a way to skip these tests.
all_tests += $$(and $$($(1)),$$($(2)),\
		$(call obsoleted_tests,$(1),$(2)))
$(foreach t,$(call obsoleted_tests,$(1),$(2)),\
	$(call give_xfail_reason,$(t),$(3)))
endef

nonobsoleted_tests = \
	$(addprefix nonobsoleted_,\
		$(1)_with_$(2) \
		$(if $(SHORT),,\
			$(1)_updated_with_$(2) \
			$(1)_before_$(2) \
			$(1)_after_$(2)))
define nonobsoleted

nonobsoleted_$(1)_with_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -i $$($(1)) $$($(2))
	$$(filter-out --justdb,$$(RPM)) -q $$($(1)_name)

nonobsoleted_$(1)_updated_with_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -U $$($(1)) $$($(2))
	$$(filter-out --justdb,$$(RPM)) -q $$($(1)_name)

nonobsoleted_$(1)_before_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -i $$($(1))
	$$(RPM) -U $$($(2))
	$$(filter-out --justdb,$$(RPM)) -q $$($(1)_name)

nonobsoleted_$(1)_after_$(2): $$$$($(1)) $$$$($(2))
	$$(RPM) -i $$($(2))
	$$(RPM) -i $$($(1))
	$$(filter-out --justdb,$$(RPM)) -q $$($(1)_name)

# Not defining the prerequisite pkgs is a way to skip these tests.
all_tests += $$(and $$($(1)),$$($(2)),\
		$(call nonobsoleted_tests,$(1),$(2)))
$(foreach t,$(call nonobsoleted_tests,$(1),$(2)),\
	$(call give_xfail_reason,$(t),$(3)))
endef
