Skip to content

Commit

Permalink
Make sure we use patched gen_smtp. Plus update erlang.mk
Browse files Browse the repository at this point in the history
  • Loading branch information
gotthardp committed Dec 22, 2015
1 parent 830411b commit e071abe
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 125 deletions.
18 changes: 6 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PROJECT = rabbitmq_email

DEPS = rabbit amqp_client gen_smtp
DEPS = amqp_client gen_smtp
ifeq ($(EICONV),1)
DEPS += eiconv
endif
Expand All @@ -11,17 +11,9 @@ DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk

NO_AUTOPATCH += gen_smtp eiconv

PACKAGES += gen_smtp
pkg_gen_smtp_name = gen_smtp
pkg_gen_smtp_fetch = git
pkg_gen_smtp_repo = https://github.com/gotthardp/gen_smtp.git
pkg_gen_smtp_commit = master

PACKAGES += eiconv
pkg_eiconv_name = eiconv
pkg_eiconv_fetch = git
pkg_eiconv_repo = https://github.com/zotonic/eiconv.git
pkg_eiconv_commit = master
# use the patched gen_smtp from my fork
dep_gen_smtp = git https://github.com/gotthardp/gen_smtp.git master
dep_eiconv = git https://github.com/zotonic/eiconv.git master

# FIXME: Use erlang.mk patched for RabbitMQ, while waiting for PRs to be
# reviewed and merged.
Expand All @@ -44,5 +36,7 @@ test/data/samples.zip:

WITH_BROKER_TEST_COMMANDS := \
eunit:test(rabbit_email_tests,[verbose,{report,{eunit_surefire,[{dir,\"test\"}]}}])
#WITH_BROKER_TEST_MAKEVARS := \
# RABBITMQ_CONFIG_FILE=$(CURDIR)/test/rabbit-test

# end of file
2 changes: 1 addition & 1 deletion build.config
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ core/index
core/deps

# Plugins that must run before Erlang code gets compiled.
plugins/erlydtl
plugins/protobuffs

# Core modules, continued.
Expand All @@ -28,7 +29,6 @@ plugins/ct
plugins/dialyzer
# plugins/edoc
plugins/elvis
plugins/erlydtl
plugins/escript
# plugins/eunit
plugins/relx
Expand Down
126 changes: 63 additions & 63 deletions erlang.mk
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

ERLANG_MK_FILENAME := $(realpath $(lastword $(MAKEFILE_LIST)))

ERLANG_MK_VERSION = 2.0.0-pre.2-16-ga6d6bfe-dirty
ERLANG_MK_VERSION = 2.0.0-pre.2-16-gb52203c-dirty

# Core configuration.

Expand Down Expand Up @@ -4656,6 +4656,67 @@ $(foreach p,$(DEP_PLUGINS),\
$(call core_dep_plugin,$p,$(firstword $(subst /, ,$p))),\
$(call core_dep_plugin,$p/plugins.mk,$p))))

# Copyright (c) 2013-2015, Loïc Hoguin <[email protected]>
# This file is part of erlang.mk and subject to the terms of the ISC License.

# Configuration.

DTL_FULL_PATH ?=
DTL_PATH ?= templates/
DTL_SUFFIX ?= _dtl

# Verbosity.

dtl_verbose_0 = @echo " DTL " $(filter %.dtl,$(?F));
dtl_verbose = $(dtl_verbose_$(V))

# Core targets.

define erlydtl_compile.erl
[begin
Module0 = case "$(strip $(DTL_FULL_PATH))" of
"" ->
filename:basename(F, ".dtl");
_ ->
"$(DTL_PATH)" ++ F2 = filename:rootname(F, ".dtl"),
re:replace(F2, "/", "_", [{return, list}, global])
end,
Module = list_to_atom(string:to_lower(Module0) ++ "$(DTL_SUFFIX)"),
case erlydtl:compile(F, Module, [{out_dir, "ebin/"}, return_errors, {doc_root, "templates"}]) of
ok -> ok;
{ok, _} -> ok
end
end || F <- string:tokens("$(1)", " ")],
halt().
endef

ifneq ($(wildcard src/),)

DTL_FILES = $(sort $(call core_find,$(DTL_PATH),*.dtl))

ifdef DTL_FULL_PATH
BEAM_FILES += $(addprefix ebin/,$(patsubst %.dtl,%_dtl.beam,$(subst /,_,$(DTL_FILES:$(DTL_PATH)%=%))))
else
BEAM_FILES += $(addprefix ebin/,$(patsubst %.dtl,%_dtl.beam,$(notdir $(DTL_FILES))))
endif

ifneq ($(words $(DTL_FILES)),0)
# Rebuild everything when the Makefile changes.
$(ERLANG_MK_TMP)/last-makefile-change-erlydtl: $(MAKEFILE_LIST)
@mkdir -p $(ERLANG_MK_TMP)
@if test -f $@; then \
touch $(DTL_FILES); \
fi
@touch $@

ebin/$(PROJECT).app:: $(ERLANG_MK_TMP)/last-makefile-change-erlydtl
endif

ebin/$(PROJECT).app:: $(DTL_FILES)
$(if $(strip $?),\
$(dtl_verbose) $(call erlang,$(call erlydtl_compile.erl,$?,-pa ebin/ $(DEPS_DIR)/erlydtl/ebin/)))
endif

# Copyright (c) 2015, Loïc Hoguin <[email protected]>
# This file is part of erlang.mk and subject to the terms of the ISC License.

Expand Down Expand Up @@ -5965,67 +6026,6 @@ elvis: $(ELVIS) $(ELVIS_CONFIG)
distclean-elvis:
$(gen_verbose) rm -rf $(ELVIS)

# Copyright (c) 2013-2015, Loïc Hoguin <[email protected]>
# This file is part of erlang.mk and subject to the terms of the ISC License.

# Configuration.

DTL_FULL_PATH ?=
DTL_PATH ?= templates/
DTL_SUFFIX ?= _dtl

# Verbosity.

dtl_verbose_0 = @echo " DTL " $(filter %.dtl,$(?F));
dtl_verbose = $(dtl_verbose_$(V))

# Core targets.

define erlydtl_compile.erl
[begin
Module0 = case "$(strip $(DTL_FULL_PATH))" of
"" ->
filename:basename(F, ".dtl");
_ ->
"$(DTL_PATH)" ++ F2 = filename:rootname(F, ".dtl"),
re:replace(F2, "/", "_", [{return, list}, global])
end,
Module = list_to_atom(string:to_lower(Module0) ++ "$(DTL_SUFFIX)"),
case erlydtl:compile(F, Module, [{out_dir, "ebin/"}, return_errors, {doc_root, "templates"}]) of
ok -> ok;
{ok, _} -> ok
end
end || F <- string:tokens("$(1)", " ")],
halt().
endef

ifneq ($(wildcard src/),)

DTL_FILES = $(sort $(call core_find,$(DTL_PATH),*.dtl))

ifdef DTL_FULL_PATH
BEAM_FILES += $(addprefix ebin/,$(patsubst %.dtl,%_dtl.beam,$(subst /,_,$(DTL_FILES:$(DTL_PATH)%=%))))
else
BEAM_FILES += $(addprefix ebin/,$(patsubst %.dtl,%_dtl.beam,$(notdir $(DTL_FILES))))
endif

ifneq ($(words $(DTL_FILES)),0)
# Rebuild everything when the Makefile changes.
$(ERLANG_MK_TMP)/last-makefile-change-erlydtl: $(MAKEFILE_LIST)
@mkdir -p $(ERLANG_MK_TMP)
@if test -f $@; then \
touch $(DTL_FILES); \
fi
@touch $@

ebin/$(PROJECT).app:: $(ERLANG_MK_TMP)/last-makefile-change-erlydtl
endif

ebin/$(PROJECT).app:: $(DTL_FILES)
$(if $(strip $?),\
$(dtl_verbose) $(call erlang,$(call erlydtl_compile.erl,$?,-pa ebin/ $(DEPS_DIR)/erlydtl/ebin/)))
endif

# Copyright (c) 2014 Dave Cottlehuber <[email protected]>
# This file is part of erlang.mk and subject to the terms of the ISC License.

Expand Down Expand Up @@ -6468,7 +6468,7 @@ $(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST):
$(verbose) :> $@
else
LIST_DIRS = $(ALL_DEPS_DIRS)
LIST_DEPS = $(DEPS)
LIST_DEPS = $(BUILD_DEPS) $(DEPS)

$(ERLANG_MK_RECURSIVE_DEPS_LIST): fetch-deps

Expand Down
109 changes: 60 additions & 49 deletions rabbitmq-components.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,54 +26,58 @@ endif
# topic branch or fallback to `stable` or `master` whichever was the
# base of the topic branch.

dep_amqp_client = git_rmq rabbitmq-erlang-client $(current_rmq_ref) $(base_rmq_ref)
dep_rabbit = git_rmq rabbitmq-server $(current_rmq_ref) $(base_rmq_ref)
dep_rabbit_common = git_rmq rabbitmq-common $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_amqp1_0 = git_rmq rabbitmq-amqp1.0 $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_auth_backend_amqp = git_rmq rabbitmq-auth-backend-amqp $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_auth_backend_http = git_rmq rabbitmq-auth-backend-http $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_auth_backend_ldap = git_rmq rabbitmq-auth-backend-ldap $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_auth_mechanism_ssl = git_rmq rabbitmq-auth-mechanism-ssl $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_clusterer = git_rmq rabbitmq-clusterer $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_codegen = git_rmq rabbitmq-codegen $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_consistent_hash_exchange = git_rmq rabbitmq-consistent-hash-exchange $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_delayed_message_exchange = git_rmq rabbitmq-delayed-message-exchange $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_dotnet_client = git_rmq rabbitmq-dotnet-client $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_event_exchange = git_rmq rabbitmq-event-exchange $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_federation = git_rmq rabbitmq-federation $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_federation_management = git_rmq rabbitmq-federation-management $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_java_client = git_rmq rabbitmq-java-client $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_lvc = git_rmq rabbitmq-lvc-plugin $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_management = git_rmq rabbitmq-management $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_management_agent = git_rmq rabbitmq-management-agent $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_management_exchange = git_rmq rabbitmq-management-exchange $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_management_visualiser = git_rmq rabbitmq-management-visualiser $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_message_timestamp = git_rmq rabbitmq-message-timestamp $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_metronome = git_rmq rabbitmq-metronome $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_mqtt = git_rmq rabbitmq-mqtt $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_sharding = git_rmq rabbitmq-sharding $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_shovel = git_rmq rabbitmq-shovel $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_shovel_management = git_rmq rabbitmq-shovel-management $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_stomp = git_rmq rabbitmq-stomp $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_toke = git_rmq rabbitmq-toke $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_top = git_rmq rabbitmq-top $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_tracing = git_rmq rabbitmq-tracing $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_test = git_rmq rabbitmq-test $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_web_dispatch = git_rmq rabbitmq-web-dispatch $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_web_stomp = git_rmq rabbitmq-web-stomp $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_web_stomp_examples = git_rmq rabbitmq-web-stomp-examples $(current_rmq_ref) $(base_rmq_ref)
dep_rabbitmq_website = git_rmq rabbitmq-website $(current_rmq_ref) $(base_rmq_ref) live
dep_sockjs = git_rmq sockjs-erlang $(current_rmq_ref) $(base_rmq_ref)
dep_toke = git_rmq toke $(current_rmq_ref) $(base_rmq_ref)

dep_rabbitmq_public_umbrella = git_rmq rabbitmq-public-umbrella $(current_rmq_ref) $(base_rmq_ref)

# FIXME: As of 2015-11-20, we depend on Ranch 1.2.0, but erlang.mk
dep_amqp_client = git_rmq rabbitmq-erlang-client $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbit = git_rmq rabbitmq-server $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbit_common = git_rmq rabbitmq-common $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_amqp1_0 = git_rmq rabbitmq-amqp1.0 $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_auth_backend_amqp = git_rmq rabbitmq-auth-backend-amqp $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_auth_backend_http = git_rmq rabbitmq-auth-backend-http $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_auth_backend_ldap = git_rmq rabbitmq-auth-backend-ldap $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_auth_mechanism_ssl = git_rmq rabbitmq-auth-mechanism-ssl $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_boot_steps_visualiser = git_rmq rabbitmq-boot-steps-visualiser $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_clusterer = git_rmq rabbitmq-clusterer $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_codegen = git_rmq rabbitmq-codegen $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_consistent_hash_exchange = git_rmq rabbitmq-consistent-hash-exchange $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_delayed_message_exchange = git_rmq rabbitmq-delayed-message-exchange $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_dotnet_client = git_rmq rabbitmq-dotnet-client $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_event_exchange = git_rmq rabbitmq-event-exchange $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_federation = git_rmq rabbitmq-federation $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_federation_management = git_rmq rabbitmq-federation-management $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_java_client = git_rmq rabbitmq-java-client $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_lvc = git_rmq rabbitmq-lvc-plugin $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_management = git_rmq rabbitmq-management $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_management_agent = git_rmq rabbitmq-management-agent $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_management_exchange = git_rmq rabbitmq-management-exchange $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_management_themes = git_rmq rabbitmq-management-themes $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_management_visualiser = git_rmq rabbitmq-management-visualiser $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_message_timestamp = git_rmq rabbitmq-message-timestamp $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_metronome = git_rmq rabbitmq-metronome $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_mqtt = git_rmq rabbitmq-mqtt $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_recent_history_exchange = git_rmq rabbitmq-recent-history-exchange $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_rtopic_exchange = git_rmq rabbitmq-rtopic-exchange $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_sharding = git_rmq rabbitmq-sharding $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_shovel = git_rmq rabbitmq-shovel $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_shovel_management = git_rmq rabbitmq-shovel-management $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_stomp = git_rmq rabbitmq-stomp $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_toke = git_rmq rabbitmq-toke $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_top = git_rmq rabbitmq-top $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_tracing = git_rmq rabbitmq-tracing $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_test = git_rmq rabbitmq-test $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_web_dispatch = git_rmq rabbitmq-web-dispatch $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_web_stomp = git_rmq rabbitmq-web-stomp $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_web_stomp_examples = git_rmq rabbitmq-web-stomp-examples $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_website = git_rmq rabbitmq-website $(current_rmq_ref) $(base_rmq_ref) live master
dep_sockjs = git_rmq sockjs-erlang $(current_rmq_ref) $(base_rmq_ref) master
dep_toke = git_rmq toke $(current_rmq_ref) $(base_rmq_ref) master

dep_rabbitmq_public_umbrella = git_rmq rabbitmq-public-umbrella $(current_rmq_ref) $(base_rmq_ref) master

# FIXME: As of 2015-11-20, we depend on Ranch 1.2.1, but erlang.mk
# defaults to Ranch 1.1.0. All projects depending indirectly on Ranch
# needs to add "ranch" as a BUILD_DEPS. The list of projects needing
# this workaround are:
# o rabbitmq-web-stomp
dep_ranch = git https://github.com/ninenines/ranch 1.2.0
dep_ranch = git https://github.com/ninenines/ranch 1.2.1

RABBITMQ_COMPONENTS = amqp_client \
rabbit \
Expand All @@ -83,6 +87,7 @@ RABBITMQ_COMPONENTS = amqp_client \
rabbitmq_auth_backend_http \
rabbitmq_auth_backend_ldap \
rabbitmq_auth_mechanism_ssl \
rabbitmq_boot_steps_visualiser \
rabbitmq_clusterer \
rabbitmq_codegen \
rabbitmq_consistent_hash_exchange \
Expand All @@ -96,10 +101,13 @@ RABBITMQ_COMPONENTS = amqp_client \
rabbitmq_management \
rabbitmq_management_agent \
rabbitmq_management_exchange \
rabbitmq_management_themes \
rabbitmq_management_visualiser \
rabbitmq_message_timestamp \
rabbitmq_metronome \
rabbitmq_mqtt \
rabbitmq_recent_history_exchange \
rabbitmq_rtopic_exchange \
rabbitmq_sharding \
rabbitmq_shovel \
rabbitmq_shovel_management \
Expand All @@ -120,9 +128,9 @@ NO_AUTOPATCH += $(RABBITMQ_COMPONENTS)

ifeq ($(origin current_rmq_ref),undefined)
ifneq ($(wildcard .git),)
current_rmq_ref := $(shell \
git describe --tags --exact-match 2>/dev/null || \
git symbolic-ref -q --short HEAD)
current_rmq_ref := $(shell (\
ref=$$(git branch --list | awk '/^\* \(.*detached / {ref=$$0; sub(/.*detached [^ ]+ /, "", ref); sub(/\)$$/, "", ref); print ref; exit;} /^\* / {ref=$$0; sub(/^\* /, "", ref); print ref; exit}');\
if test "$$(git rev-parse --short HEAD)" != "$$ref"; then echo "$$ref"; fi))
else
current_rmq_ref := master
endif
Expand Down Expand Up @@ -167,7 +175,7 @@ RABBITMQ_UPSTREAM_PUSH_URL ?= [email protected]:rabbitmq/$(RABBITMQ_COMPONENT_REPO_
# default to the upstream Git repository.
ifneq ($(wildcard .git),)
git_origin_fetch_url := $(shell git config remote.origin.url)
git_origin_push_url := $(shell git config remote.origin.pushurl)
git_origin_push_url := $(shell git config remote.origin.pushurl || git config remote.origin.url)
RABBITMQ_CURRENT_FETCH_URL ?= $(git_origin_fetch_url)
RABBITMQ_CURRENT_PUSH_URL ?= $(git_origin_push_url)
else
Expand Down Expand Up @@ -198,8 +206,10 @@ define dep_fetch_git_rmq
fetch_url2='$(call dep_rmq_repo,$(RABBITMQ_UPSTREAM_FETCH_URL),$(1))'; \
if test "$$$$fetch_url1" != '$(RABBITMQ_CURRENT_FETCH_URL)' && \
git clone -q -n -- "$$$$fetch_url1" $(DEPS_DIR)/$(call dep_name,$(1)); then \
fetch_url="$$$$fetch_url1"; \
push_url='$(call dep_rmq_repo,$(RABBITMQ_CURRENT_PUSH_URL),$(1))'; \
elif git clone -q -n -- "$$$$fetch_url2" $(DEPS_DIR)/$(call dep_name,$(1)); then \
fetch_url="$$$$fetch_url2"; \
push_url='$(call dep_rmq_repo,$(RABBITMQ_UPSTREAM_PUSH_URL),$(1))'; \
fi; \
cd $(DEPS_DIR)/$(call dep_name,$(1)) && ( \
Expand All @@ -208,7 +218,8 @@ define dep_fetch_git_rmq
) \
(echo "error: no valid pathspec among: $(call dep_rmq_commits,$(1))" \
1>&2 && false) ) && \
git remote set-url --push origin "$$$$push_url"
(test "$$$$fetch_url" = "$$$$push_url" || \
git remote set-url --push origin "$$$$push_url")
endef

# --------------------------------------------------------------------
Expand Down

0 comments on commit e071abe

Please sign in to comment.