123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- # Copyright (c) 2020, Loïc Hoguin <essen@ninenines.eu>
- # This file is part of erlang.mk and subject to the terms of the ISC License.
- HEX_CORE_GIT ?= https://github.com/hexpm/hex_core
- HEX_CORE_COMMIT ?= v0.7.0
- PACKAGES += hex_core
- pkg_hex_core_name = hex_core
- pkg_hex_core_description = Reference implementation of Hex specifications
- pkg_hex_core_homepage = $(HEX_CORE_GIT)
- pkg_hex_core_fetch = git
- pkg_hex_core_repo = $(HEX_CORE_GIT)
- pkg_hex_core_commit = $(HEX_CORE_COMMIT)
- # We automatically depend on hex_core when the project isn't already.
- $(if $(filter hex_core,$(DEPS) $(BUILD_DEPS) $(DOC_DEPS) $(REL_DEPS) $(TEST_DEPS)),,\
- $(eval $(call dep_target,hex_core)))
- hex-core: $(DEPS_DIR)/hex_core
- $(verbose) if [ ! -e $(DEPS_DIR)/hex_core/ebin/dep_built ]; then \
- $(MAKE) -C $(DEPS_DIR)/hex_core IS_DEP=1; \
- touch $(DEPS_DIR)/hex_core/ebin/dep_built; \
- fi
- # @todo This must also apply to fetching.
- HEX_CONFIG ?=
- define hex_config.erl
- begin
- Config0 = hex_core:default_config(),
- Config0$(HEX_CONFIG)
- end
- endef
- define hex_user_create.erl
- {ok, _} = application:ensure_all_started(ssl),
- {ok, _} = application:ensure_all_started(inets),
- Config = $(hex_config.erl),
- case hex_api_user:create(Config, <<"$(strip $1)">>, <<"$(strip $2)">>, <<"$(strip $3)">>) of
- {ok, {201, _, #{<<"email">> := Email, <<"url">> := URL, <<"username">> := Username}}} ->
- io:format("User ~s (~s) created at ~s~n"
- "Please check your inbox for a confirmation email.~n"
- "You must confirm before you are allowed to publish packages.~n",
- [Username, Email, URL]),
- halt(0);
- {ok, {Status, _, Errors}} ->
- io:format("Error ~b: ~0p~n", [Status, Errors]),
- halt(80)
- end
- endef
- # The $(info ) call inserts a new line after the password prompt.
- hex-user-create: hex-core
- $(if $(HEX_USERNAME),,$(eval HEX_USERNAME := $(shell read -p "Username: " username; echo $$username)))
- $(if $(HEX_PASSWORD),,$(eval HEX_PASSWORD := $(shell stty -echo; read -p "Password: " password; stty echo; echo $$password) $(info )))
- $(if $(HEX_EMAIL),,$(eval HEX_EMAIL := $(shell read -p "Email: " email; echo $$email)))
- $(gen_verbose) $(call erlang,$(call hex_user_create.erl,$(HEX_USERNAME),$(HEX_PASSWORD),$(HEX_EMAIL)))
- define hex_key_add.erl
- {ok, _} = application:ensure_all_started(ssl),
- {ok, _} = application:ensure_all_started(inets),
- Config = $(hex_config.erl),
- ConfigF = Config#{api_key => iolist_to_binary([<<"Basic ">>, base64:encode(<<"$(strip $1):$(strip $2)">>)])},
- Permissions = [
- case string:split(P, <<":">>) of
- [D] -> #{domain => D};
- [D, R] -> #{domain => D, resource => R}
- end
- || P <- string:split(<<"$(strip $4)">>, <<",">>, all)],
- case hex_api_key:add(ConfigF, <<"$(strip $3)">>, Permissions) of
- {ok, {201, _, #{<<"secret">> := Secret}}} ->
- io:format("Key ~s created for user ~s~nSecret: ~s~n"
- "Please store the secret in a secure location, such as a password store.~n"
- "The secret will be requested for most Hex-related operations.~n",
- [<<"$(strip $3)">>, <<"$(strip $1)">>, Secret]),
- halt(0);
- {ok, {Status, _, Errors}} ->
- io:format("Error ~b: ~0p~n", [Status, Errors]),
- halt(81)
- end
- endef
- hex-key-add: hex-core
- $(if $(HEX_USERNAME),,$(eval HEX_USERNAME := $(shell read -p "Username: " username; echo $$username)))
- $(if $(HEX_PASSWORD),,$(eval HEX_PASSWORD := $(shell stty -echo; read -p "Password: " password; stty echo; echo $$password) $(info )))
- $(gen_verbose) $(call erlang,$(call hex_key_add.erl,$(HEX_USERNAME),$(HEX_PASSWORD),\
- $(if $(name),$(name),$(shell hostname)-erlang-mk),\
- $(if $(perm),$(perm),api)))
- HEX_TARBALL_EXTRA_METADATA ?=
- # @todo Check that we can += files
- HEX_TARBALL_FILES ?= \
- $(wildcard early-plugins.mk) \
- $(wildcard ebin/$(PROJECT).app) \
- $(wildcard ebin/$(PROJECT).appup) \
- $(wildcard $(notdir $(ERLANG_MK_FILENAME))) \
- $(sort $(call core_find,include/,*.hrl)) \
- $(wildcard LICENSE*) \
- $(wildcard Makefile) \
- $(wildcard plugins.mk) \
- $(sort $(call core_find,priv/,*)) \
- $(wildcard README*) \
- $(wildcard rebar.config) \
- $(sort $(call core_find,src/,*))
- HEX_TARBALL_OUTPUT_FILE ?= $(ERLANG_MK_TMP)/$(PROJECT).tar
- # @todo Need to check for rebar.config and/or the absence of DEPS to know
- # whether a project will work with Rebar.
- #
- # @todo contributors licenses links in HEX_TARBALL_EXTRA_METADATA
- # In order to build the requirements metadata we look into DEPS.
- # We do not require that the project use Hex dependencies, however
- # Hex.pm does require that the package name and version numbers
- # correspond to a real Hex package.
- define hex_tarball_create.erl
- Files0 = [$(call comma_list,$(patsubst %,"%",$(HEX_TARBALL_FILES)))],
- Requirements0 = #{
- $(foreach d,$(DEPS),
- <<"$(if $(subst hex,,$(call query_fetch_method,$d)),$d,$(if $(word 3,$(dep_$d)),$(word 3,$(dep_$d)),$d))">> => #{
- <<"app">> => <<"$d">>,
- <<"optional">> => false,
- <<"requirement">> => <<"$(call query_version,$d)">>
- },)
- $(if $(DEPS),dummy => dummy)
- },
- Requirements = maps:remove(dummy, Requirements0),
- Metadata0 = #{
- app => <<"$(strip $(PROJECT))">>,
- build_tools => [<<"make">>, <<"rebar3">>],
- description => <<"$(strip $(PROJECT_DESCRIPTION))">>,
- files => [unicode:characters_to_binary(F) || F <- Files0],
- name => <<"$(strip $(PROJECT))">>,
- requirements => Requirements,
- version => <<"$(strip $(PROJECT_VERSION))">>
- },
- Metadata = Metadata0$(HEX_TARBALL_EXTRA_METADATA),
- Files = [case file:read_file(F) of
- {ok, Bin} ->
- {F, Bin};
- {error, Reason} ->
- io:format("Error trying to open file ~0p: ~0p~n", [F, Reason]),
- halt(82)
- end || F <- Files0],
- case hex_tarball:create(Metadata, Files) of
- {ok, #{tarball := Tarball}} ->
- ok = file:write_file("$(strip $(HEX_TARBALL_OUTPUT_FILE))", Tarball),
- halt(0);
- {error, Reason} ->
- io:format("Error ~0p~n", [Reason]),
- halt(83)
- end
- endef
- hex_tar_verbose_0 = @echo " TAR $(notdir $(ERLANG_MK_TMP))/$(@F)";
- hex_tar_verbose_2 = set -x;
- hex_tar_verbose = $(hex_tar_verbose_$(V))
- $(HEX_TARBALL_OUTPUT_FILE): hex-core app
- $(hex_tar_verbose) $(call erlang,$(call hex_tarball_create.erl))
- hex-tarball-create: $(HEX_TARBALL_OUTPUT_FILE)
- define hex_release_publish_summary.erl
- {ok, Tarball} = erl_tar:open("$(strip $(HEX_TARBALL_OUTPUT_FILE))", [read]),
- ok = erl_tar:extract(Tarball, [{cwd, "$(ERLANG_MK_TMP)"}, {files, ["metadata.config"]}]),
- {ok, Metadata} = file:consult("$(ERLANG_MK_TMP)/metadata.config"),
- #{
- <<"name">> := Name,
- <<"version">> := Version,
- <<"files">> := Files,
- <<"requirements">> := Deps
- } = maps:from_list(Metadata),
- io:format("Publishing ~s ~s~n Dependencies:~n", [Name, Version]),
- case Deps of
- [] ->
- io:format(" (none)~n");
- _ ->
- [begin
- #{<<"app">> := DA, <<"requirement">> := DR} = maps:from_list(D),
- io:format(" ~s ~s~n", [DA, DR])
- end || {_, D} <- Deps]
- end,
- io:format(" Included files:~n"),
- [io:format(" ~s~n", [F]) || F <- Files],
- io:format("You may also review the contents of the tarball file.~n"
- "Please enter your secret key to proceed.~n"),
- halt(0)
- endef
- define hex_release_publish.erl
- {ok, _} = application:ensure_all_started(ssl),
- {ok, _} = application:ensure_all_started(inets),
- Config = $(hex_config.erl),
- ConfigF = Config#{api_key => <<"$(strip $1)">>},
- {ok, Tarball} = file:read_file("$(strip $(HEX_TARBALL_OUTPUT_FILE))"),
- case hex_api_release:publish(ConfigF, Tarball, [{replace, $2}]) of
- {ok, {200, _, #{}}} ->
- io:format("Release replaced~n"),
- halt(0);
- {ok, {201, _, #{}}} ->
- io:format("Release published~n"),
- halt(0);
- {ok, {Status, _, Errors}} ->
- io:format("Error ~b: ~0p~n", [Status, Errors]),
- halt(84)
- end
- endef
- hex-release-tarball: hex-core $(HEX_TARBALL_OUTPUT_FILE)
- $(verbose) $(call erlang,$(call hex_release_publish_summary.erl))
- hex-release-publish: hex-core hex-release-tarball
- $(if $(HEX_SECRET),,$(eval HEX_SECRET := $(shell stty -echo; read -p "Secret: " secret; stty echo; echo $$secret) $(info )))
- $(gen_verbose) $(call erlang,$(call hex_release_publish.erl,$(HEX_SECRET),false))
- hex-release-replace: hex-core hex-release-tarball
- $(if $(HEX_SECRET),,$(eval HEX_SECRET := $(shell stty -echo; read -p "Secret: " secret; stty echo; echo $$secret) $(info )))
- $(gen_verbose) $(call erlang,$(call hex_release_publish.erl,$(HEX_SECRET),true))
- define hex_release_delete.erl
- {ok, _} = application:ensure_all_started(ssl),
- {ok, _} = application:ensure_all_started(inets),
- Config = $(hex_config.erl),
- ConfigF = Config#{api_key => <<"$(strip $1)">>},
- case hex_api_release:delete(ConfigF, <<"$(strip $(PROJECT))">>, <<"$(strip $(PROJECT_VERSION))">>) of
- {ok, {204, _, _}} ->
- io:format("Release $(strip $(PROJECT_VERSION)) deleted~n"),
- halt(0);
- {ok, {Status, _, Errors}} ->
- io:format("Error ~b: ~0p~n", [Status, Errors]),
- halt(85)
- end
- endef
- hex-release-delete: hex-core
- $(if $(HEX_SECRET),,$(eval HEX_SECRET := $(shell stty -echo; read -p "Secret: " secret; stty echo; echo $$secret) $(info )))
- $(gen_verbose) $(call erlang,$(call hex_release_delete.erl,$(HEX_SECRET)))
- define hex_release_retire.erl
- {ok, _} = application:ensure_all_started(ssl),
- {ok, _} = application:ensure_all_started(inets),
- Config = $(hex_config.erl),
- ConfigF = Config#{api_key => <<"$(strip $1)">>},
- Params = #{<<"reason">> => <<"$(strip $3)">>, <<"message">> => <<"$(strip $4)">>},
- case hex_api_release:retire(ConfigF, <<"$(strip $(PROJECT))">>, <<"$(strip $2)">>, Params) of
- {ok, {204, _, _}} ->
- io:format("Release $(strip $2) has been retired~n"),
- halt(0);
- {ok, {Status, _, Errors}} ->
- io:format("Error ~b: ~0p~n", [Status, Errors]),
- halt(86)
- end
- endef
- hex-release-retire: hex-core
- $(if $(HEX_SECRET),,$(eval HEX_SECRET := $(shell stty -echo; read -p "Secret: " secret; stty echo; echo $$secret) $(info )))
- $(gen_verbose) $(call erlang,$(call hex_release_retire.erl,$(HEX_SECRET),\
- $(if $(HEX_VERSION),$(HEX_VERSION),$(PROJECT_VERSION)),\
- $(if $(HEX_REASON),$(HEX_REASON),invalid),\
- $(HEX_MESSAGE)))
- define hex_release_unretire.erl
- {ok, _} = application:ensure_all_started(ssl),
- {ok, _} = application:ensure_all_started(inets),
- Config = $(hex_config.erl),
- ConfigF = Config#{api_key => <<"$(strip $1)">>},
- case hex_api_release:unretire(ConfigF, <<"$(strip $(PROJECT))">>, <<"$(strip $2)">>) of
- {ok, {204, _, _}} ->
- io:format("Release $(strip $2) is not retired anymore~n"),
- halt(0);
- {ok, {Status, _, Errors}} ->
- io:format("Error ~b: ~0p~n", [Status, Errors]),
- halt(87)
- end
- endef
- hex-release-unretire: hex-core
- $(if $(HEX_SECRET),,$(eval HEX_SECRET := $(shell stty -echo; read -p "Secret: " secret; stty echo; echo $$secret) $(info )))
- $(gen_verbose) $(call erlang,$(call hex_release_unretire.erl,$(HEX_SECRET),\
- $(if $(HEX_VERSION),$(HEX_VERSION),$(PROJECT_VERSION))))
- HEX_DOCS_DOC_DIR ?= doc/
- HEX_DOCS_TARBALL_FILES ?= $(sort $(call core_find,$(HEX_DOCS_DOC_DIR),*))
- HEX_DOCS_TARBALL_OUTPUT_FILE ?= $(ERLANG_MK_TMP)/$(PROJECT)-docs.tar.gz
- $(HEX_DOCS_TARBALL_OUTPUT_FILE): hex-core app docs
- $(hex_tar_verbose) tar czf $(HEX_DOCS_TARBALL_OUTPUT_FILE) -C $(HEX_DOCS_DOC_DIR) \
- $(HEX_DOCS_TARBALL_FILES:$(HEX_DOCS_DOC_DIR)%=%)
- hex-docs-tarball-create: $(HEX_DOCS_TARBALL_OUTPUT_FILE)
- define hex_docs_publish.erl
- {ok, _} = application:ensure_all_started(ssl),
- {ok, _} = application:ensure_all_started(inets),
- Config = $(hex_config.erl),
- ConfigF = Config#{api_key => <<"$(strip $1)">>},
- {ok, Tarball} = file:read_file("$(strip $(HEX_DOCS_TARBALL_OUTPUT_FILE))"),
- case hex_api:post(ConfigF,
- ["packages", "$(strip $(PROJECT))", "releases", "$(strip $(PROJECT_VERSION))", "docs"],
- {"application/octet-stream", Tarball}) of
- {ok, {Status, _, _}} when Status >= 200, Status < 300 ->
- io:format("Docs published~n"),
- halt(0);
- {ok, {Status, _, Errors}} ->
- io:format("Error ~b: ~0p~n", [Status, Errors]),
- halt(88)
- end
- endef
- hex-docs-publish: hex-core hex-docs-tarball-create
- $(if $(HEX_SECRET),,$(eval HEX_SECRET := $(shell stty -echo; read -p "Secret: " secret; stty echo; echo $$secret) $(info )))
- $(gen_verbose) $(call erlang,$(call hex_docs_publish.erl,$(HEX_SECRET)))
- define hex_docs_delete.erl
- {ok, _} = application:ensure_all_started(ssl),
- {ok, _} = application:ensure_all_started(inets),
- Config = $(hex_config.erl),
- ConfigF = Config#{api_key => <<"$(strip $1)">>},
- case hex_api:delete(ConfigF,
- ["packages", "$(strip $(PROJECT))", "releases", "$(strip $2)", "docs"]) of
- {ok, {Status, _, _}} when Status >= 200, Status < 300 ->
- io:format("Docs removed~n"),
- halt(0);
- {ok, {Status, _, Errors}} ->
- io:format("Error ~b: ~0p~n", [Status, Errors]),
- halt(89)
- end
- endef
- hex-docs-delete: hex-core
- $(if $(HEX_SECRET),,$(eval HEX_SECRET := $(shell stty -echo; read -p "Secret: " secret; stty echo; echo $$secret) $(info )))
- $(gen_verbose) $(call erlang,$(call hex_docs_delete.erl,$(HEX_SECRET),\
- $(if $(HEX_VERSION),$(HEX_VERSION),$(PROJECT_VERSION))))
|