From d2c7f690db89e9930bbbc97875b15e3f2fc2d4dc Mon Sep 17 00:00:00 2001 From: Pankaj Soni Date: Thu, 23 Jul 2020 16:16:01 +0530 Subject: [PATCH 1/5] fix CSV parsing with Quotes --- .gitignore | 25 +- LICENSE | 22 - Makefile | 17 +- NOTICE | 9 - conf/sys.config | 3 + conf/vm.args | 20 + erlang.mk | 7808 +++++++++++++++++++++++++++++++++++++++++++ examples/10k.csv.gz | Bin 67353 -> 0 bytes examples/benchmark | 41 - examples/sample.csv | 3 - rebar | Bin 109352 -> 0 bytes rebar.config | 4 + relx.config | 9 + src/ecsv.app.src | 11 - src/ecsv.erl | 4 - src/ecsv_parser.erl | 119 +- 16 files changed, 7925 insertions(+), 170 deletions(-) delete mode 100644 LICENSE delete mode 100644 NOTICE create mode 100644 conf/sys.config create mode 100644 conf/vm.args create mode 100644 erlang.mk delete mode 100644 examples/10k.csv.gz delete mode 100755 examples/benchmark delete mode 100644 examples/sample.csv delete mode 100755 rebar create mode 100644 rebar.config create mode 100644 relx.config delete mode 100644 src/ecsv.app.src diff --git a/.gitignore b/.gitignore index c85682e..8f28411 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,25 @@ -ebin +.eunit +.erlang.mk/ +*.swp +*.swo +*.d +ebin/ +run.sh +*.o +*.beam +*.plt erl_crash.dump +.concrete/DEV_MODE + +# rebar 2.x +.rebar +rel/example_project +ebin/*.beam +deps + +# rebar 3 +.rebar3 +_build/ +_checkouts/ +_rel/ +deps/ diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 7347179..0000000 --- a/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -2011 (c) Nicolas R Dufour - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile index f7b2715..90fcf4e 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,9 @@ +PROJECT = ecsv +PROJECT_VERSION = $(shell git describe --tag --abbrev=0) -.PHONY: deps doc +app:: rebar.config -all: deps compile - -compile: - @./rebar compile - -deps: - @./rebar get-deps - -clean: - @./rebar clean +include $(if $(ERLANG_MK_FILENAME),$(ERLANG_MK_FILENAME), erlang.mk) +ERLC_OPTS += $(ERLC_COMPILE_OPTS) +TEST_ERLC_OPTS += $(ERLC_COMPILE_OPTS) diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 6d90d56..0000000 --- a/NOTICE +++ /dev/null @@ -1,9 +0,0 @@ -ecsv ----- - -ecsv is a CSV parser written in Erlang based on the code published on the blog -page http://andrewtill.blogspot.com/2009/12/erlang-csv-parser.html. - -So a big thank you to Andy Till for his original code. - -2011 (c) Nicolas R Dufour diff --git a/conf/sys.config b/conf/sys.config new file mode 100644 index 0000000..53d2057 --- /dev/null +++ b/conf/sys.config @@ -0,0 +1,3 @@ +[ + {ecsv, []} +]. diff --git a/conf/vm.args b/conf/vm.args new file mode 100644 index 0000000..9ab56cd --- /dev/null +++ b/conf/vm.args @@ -0,0 +1,20 @@ +-sname erlcsv + +## Enable kernel poll and a few async threads ++K true ++A 5 ++P 10000000 + +## Tweak GC to run more often +-env ERL_FULLSWEEP_AFTER 10 + +## Heartbeat management; auto-restarts VM if it dies or becomes unresponsive +## (Disabled by default..use with caution!) +##-heart + +## Increase number of concurrent ports/sockets +-env ERL_MAX_PORTS 4096 + +-kernel inet_dist_listen_min 5000 inet_dist_listen_max 5010 + +-sasl sasl_error_logger false diff --git a/erlang.mk b/erlang.mk new file mode 100644 index 0000000..da4fa4a --- /dev/null +++ b/erlang.mk @@ -0,0 +1,7808 @@ +# Copyright (c) 2013-2016, Loïc Hoguin +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +.PHONY: all app apps deps search rel relup docs install-docs check tests clean distclean help erlang-mk + +ERLANG_MK_FILENAME := $(realpath $(lastword $(MAKEFILE_LIST))) +export ERLANG_MK_FILENAME + +ERLANG_MK_VERSION = eb3e4b0 +ERLANG_MK_WITHOUT = + +# Make 3.81 and 3.82 are deprecated. + +ifeq ($(MAKELEVEL)$(MAKE_VERSION),03.81) +$(warning Please upgrade to GNU Make 4 or later: https://erlang.mk/guide/installation.html) +endif + +ifeq ($(MAKELEVEL)$(MAKE_VERSION),03.82) +$(warning Please upgrade to GNU Make 4 or later: https://erlang.mk/guide/installation.html) +endif + +# Core configuration. + +PROJECT ?= $(notdir $(CURDIR)) +PROJECT := $(strip $(PROJECT)) + +PROJECT_VERSION ?= rolling +PROJECT_MOD ?= $(PROJECT)_app +PROJECT_ENV ?= [] + +# Verbosity. + +V ?= 0 + +verbose_0 = @ +verbose_2 = set -x; +verbose = $(verbose_$(V)) + +ifeq ($(V),3) +SHELL := $(SHELL) -x +endif + +gen_verbose_0 = @echo " GEN " $@; +gen_verbose_2 = set -x; +gen_verbose = $(gen_verbose_$(V)) + +gen_verbose_esc_0 = @echo " GEN " $$@; +gen_verbose_esc_2 = set -x; +gen_verbose_esc = $(gen_verbose_esc_$(V)) + +# Temporary files directory. + +ERLANG_MK_TMP ?= $(CURDIR)/.erlang.mk +export ERLANG_MK_TMP + +# "erl" command. + +ERL = erl +A1 -noinput -boot no_dot_erlang + +# Platform detection. + +ifeq ($(PLATFORM),) +UNAME_S := $(shell uname -s) + +ifeq ($(UNAME_S),Linux) +PLATFORM = linux +else ifeq ($(UNAME_S),Darwin) +PLATFORM = darwin +else ifeq ($(UNAME_S),SunOS) +PLATFORM = solaris +else ifeq ($(UNAME_S),GNU) +PLATFORM = gnu +else ifeq ($(UNAME_S),FreeBSD) +PLATFORM = freebsd +else ifeq ($(UNAME_S),NetBSD) +PLATFORM = netbsd +else ifeq ($(UNAME_S),OpenBSD) +PLATFORM = openbsd +else ifeq ($(UNAME_S),DragonFly) +PLATFORM = dragonfly +else ifeq ($(shell uname -o),Msys) +PLATFORM = msys2 +else +$(error Unable to detect platform. Please open a ticket with the output of uname -a.) +endif + +export PLATFORM +endif + +# Core targets. + +all:: deps app rel + +# Noop to avoid a Make warning when there's nothing to do. +rel:: + $(verbose) : + +relup:: deps app + +check:: tests + +clean:: clean-crashdump + +clean-crashdump: +ifneq ($(wildcard erl_crash.dump),) + $(gen_verbose) rm -f erl_crash.dump +endif + +distclean:: clean distclean-tmp + +$(ERLANG_MK_TMP): + $(verbose) mkdir -p $(ERLANG_MK_TMP) + +distclean-tmp: + $(gen_verbose) rm -rf $(ERLANG_MK_TMP) + +help:: + $(verbose) printf "%s\n" \ + "erlang.mk (version $(ERLANG_MK_VERSION)) is distributed under the terms of the ISC License." \ + "Copyright (c) 2013-2016 Loïc Hoguin " \ + "" \ + "Usage: [V=1] $(MAKE) [target]..." \ + "" \ + "Core targets:" \ + " all Run deps, app and rel targets in that order" \ + " app Compile the project" \ + " deps Fetch dependencies (if needed) and compile them" \ + " fetch-deps Fetch dependencies recursively (if needed) without compiling them" \ + " list-deps List dependencies recursively on stdout" \ + " search q=... Search for a package in the built-in index" \ + " rel Build a release for this project, if applicable" \ + " docs Build the documentation for this project" \ + " install-docs Install the man pages for this project" \ + " check Compile and run all tests and analysis for this project" \ + " tests Run the tests for this project" \ + " clean Delete temporary and output files from most targets" \ + " distclean Delete all temporary and output files" \ + " help Display this help and exit" \ + " erlang-mk Update erlang.mk to the latest version" + +# Core functions. + +empty := +space := $(empty) $(empty) +tab := $(empty) $(empty) +comma := , + +define newline + + +endef + +define comma_list +$(subst $(space),$(comma),$(strip $(1))) +endef + +define escape_dquotes +$(subst ",\",$1) +endef + +# Adding erlang.mk to make Erlang scripts who call init:get_plain_arguments() happy. +define erlang +$(ERL) $2 -pz $(ERLANG_MK_TMP)/rebar/ebin -eval "$(subst $(newline),,$(call escape_dquotes,$1))" -- erlang.mk +endef + +ifeq ($(PLATFORM),msys2) +core_native_path = $(shell cygpath -m $1) +else +core_native_path = $1 +endif + +core_http_get = curl -Lf$(if $(filter-out 0,$(V)),,s)o $(call core_native_path,$1) $2 + +core_eq = $(and $(findstring $(1),$(2)),$(findstring $(2),$(1))) + +# We skip files that contain spaces because they end up causing issues. +core_find = $(if $(wildcard $1),$(shell find $(1:%/=%) \( -type l -o -type f \) -name $(subst *,\*,$2) | grep -v " ")) + +core_lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$(1))))))))))))))))))))))))))) + +core_ls = $(filter-out $(1),$(shell echo $(1))) + +# @todo Use a solution that does not require using perl. +core_relpath = $(shell perl -e 'use File::Spec; print File::Spec->abs2rel(@ARGV) . "\n"' $1 $2) + +define core_render + printf -- '$(subst $(newline),\n,$(subst %,%%,$(subst ','\'',$(subst $(tab),$(WS),$(call $(1))))))\n' > $(2) +endef + +# Automated update. + +ERLANG_MK_REPO ?= https://github.com/ninenines/erlang.mk +ERLANG_MK_COMMIT ?= +ERLANG_MK_BUILD_CONFIG ?= build.config +ERLANG_MK_BUILD_DIR ?= .erlang.mk.build + +erlang-mk: WITHOUT ?= $(ERLANG_MK_WITHOUT) +erlang-mk: +ifdef ERLANG_MK_COMMIT + $(verbose) git clone $(ERLANG_MK_REPO) $(ERLANG_MK_BUILD_DIR) + $(verbose) cd $(ERLANG_MK_BUILD_DIR) && git checkout $(ERLANG_MK_COMMIT) +else + $(verbose) git clone --depth 1 $(ERLANG_MK_REPO) $(ERLANG_MK_BUILD_DIR) +endif + $(verbose) if [ -f $(ERLANG_MK_BUILD_CONFIG) ]; then cp $(ERLANG_MK_BUILD_CONFIG) $(ERLANG_MK_BUILD_DIR)/build.config; fi + $(gen_verbose) $(MAKE) --no-print-directory -C $(ERLANG_MK_BUILD_DIR) WITHOUT='$(strip $(WITHOUT))' UPGRADE=1 + $(verbose) cp $(ERLANG_MK_BUILD_DIR)/erlang.mk ./erlang.mk + $(verbose) rm -rf $(ERLANG_MK_BUILD_DIR) + $(verbose) rm -rf $(ERLANG_MK_TMP) + +# The erlang.mk package index is bundled in the default erlang.mk build. +# Search for the string "copyright" to skip to the rest of the code. + +# Copyright (c) 2015-2017, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: distclean-kerl + +KERL_INSTALL_DIR ?= $(HOME)/erlang + +ifeq ($(strip $(KERL)),) +KERL := $(ERLANG_MK_TMP)/kerl/kerl +endif + +KERL_DIR = $(ERLANG_MK_TMP)/kerl + +export KERL + +KERL_GIT ?= https://github.com/kerl/kerl +KERL_COMMIT ?= master + +KERL_MAKEFLAGS ?= + +OTP_GIT ?= https://github.com/erlang/otp + +define kerl_otp_target +$(KERL_INSTALL_DIR)/$(1): $(KERL) + $(verbose) if [ ! -d $$@ ]; then \ + MAKEFLAGS="$(KERL_MAKEFLAGS)" $(KERL) build git $(OTP_GIT) $(1) $(1); \ + $(KERL) install $(1) $(KERL_INSTALL_DIR)/$(1); \ + fi +endef + +define kerl_hipe_target +$(KERL_INSTALL_DIR)/$1-native: $(KERL) + $(verbose) if [ ! -d $$@ ]; then \ + KERL_CONFIGURE_OPTIONS=--enable-native-libs \ + MAKEFLAGS="$(KERL_MAKEFLAGS)" $(KERL) build git $(OTP_GIT) $1 $1-native; \ + $(KERL) install $1-native $(KERL_INSTALL_DIR)/$1-native; \ + fi +endef + +$(KERL): $(KERL_DIR) + +$(KERL_DIR): | $(ERLANG_MK_TMP) + $(gen_verbose) git clone --depth 1 $(KERL_GIT) $(ERLANG_MK_TMP)/kerl + $(verbose) cd $(ERLANG_MK_TMP)/kerl && git checkout $(KERL_COMMIT) + $(verbose) chmod +x $(KERL) + +distclean:: distclean-kerl + +distclean-kerl: + $(gen_verbose) rm -rf $(KERL_DIR) + +# Allow users to select which version of Erlang/OTP to use for a project. + +ifneq ($(strip $(LATEST_ERLANG_OTP)),) +# In some environments it is necessary to filter out master. +ERLANG_OTP := $(notdir $(lastword $(sort\ + $(filter-out $(KERL_INSTALL_DIR)/master $(KERL_INSTALL_DIR)/OTP_R%,\ + $(filter-out %-rc1 %-rc2 %-rc3,$(wildcard $(KERL_INSTALL_DIR)/*[^-native])))))) +endif + +ERLANG_OTP ?= +ERLANG_HIPE ?= + +# Use kerl to enforce a specific Erlang/OTP version for a project. +ifneq ($(strip $(ERLANG_OTP)),) +export PATH := $(KERL_INSTALL_DIR)/$(ERLANG_OTP)/bin:$(PATH) +SHELL := env PATH=$(PATH) $(SHELL) +$(eval $(call kerl_otp_target,$(ERLANG_OTP))) + +# Build Erlang/OTP only if it doesn't already exist. +ifeq ($(wildcard $(KERL_INSTALL_DIR)/$(ERLANG_OTP))$(BUILD_ERLANG_OTP),) +$(info Building Erlang/OTP $(ERLANG_OTP)... Please wait...) +$(shell $(MAKE) $(KERL_INSTALL_DIR)/$(ERLANG_OTP) ERLANG_OTP=$(ERLANG_OTP) BUILD_ERLANG_OTP=1 >&2) +endif + +else +# Same for a HiPE enabled VM. +ifneq ($(strip $(ERLANG_HIPE)),) +export PATH := $(KERL_INSTALL_DIR)/$(ERLANG_HIPE)-native/bin:$(PATH) +SHELL := env PATH=$(PATH) $(SHELL) +$(eval $(call kerl_hipe_target,$(ERLANG_HIPE))) + +# Build Erlang/OTP only if it doesn't already exist. +ifeq ($(wildcard $(KERL_INSTALL_DIR)/$(ERLANG_HIPE)-native)$(BUILD_ERLANG_OTP),) +$(info Building HiPE-enabled Erlang/OTP $(ERLANG_OTP)... Please wait...) +$(shell $(MAKE) $(KERL_INSTALL_DIR)/$(ERLANG_HIPE)-native ERLANG_HIPE=$(ERLANG_HIPE) BUILD_ERLANG_OTP=1 >&2) +endif + +endif +endif + +PACKAGES += aberth +pkg_aberth_name = aberth +pkg_aberth_description = Generic BERT-RPC server in Erlang +pkg_aberth_homepage = https://github.com/a13x/aberth +pkg_aberth_fetch = git +pkg_aberth_repo = https://github.com/a13x/aberth +pkg_aberth_commit = master + +PACKAGES += active +pkg_active_name = active +pkg_active_description = Active development for Erlang: rebuild and reload source/binary files while the VM is running +pkg_active_homepage = https://github.com/proger/active +pkg_active_fetch = git +pkg_active_repo = https://github.com/proger/active +pkg_active_commit = master + +PACKAGES += actordb_core +pkg_actordb_core_name = actordb_core +pkg_actordb_core_description = ActorDB main source +pkg_actordb_core_homepage = http://www.actordb.com/ +pkg_actordb_core_fetch = git +pkg_actordb_core_repo = https://github.com/biokoda/actordb_core +pkg_actordb_core_commit = master + +PACKAGES += actordb_thrift +pkg_actordb_thrift_name = actordb_thrift +pkg_actordb_thrift_description = Thrift API for ActorDB +pkg_actordb_thrift_homepage = http://www.actordb.com/ +pkg_actordb_thrift_fetch = git +pkg_actordb_thrift_repo = https://github.com/biokoda/actordb_thrift +pkg_actordb_thrift_commit = master + +PACKAGES += aleppo +pkg_aleppo_name = aleppo +pkg_aleppo_description = Alternative Erlang Pre-Processor +pkg_aleppo_homepage = https://github.com/ErlyORM/aleppo +pkg_aleppo_fetch = git +pkg_aleppo_repo = https://github.com/ErlyORM/aleppo +pkg_aleppo_commit = master + +PACKAGES += alog +pkg_alog_name = alog +pkg_alog_description = Simply the best logging framework for Erlang +pkg_alog_homepage = https://github.com/siberian-fast-food/alogger +pkg_alog_fetch = git +pkg_alog_repo = https://github.com/siberian-fast-food/alogger +pkg_alog_commit = master + +PACKAGES += amqp_client +pkg_amqp_client_name = amqp_client +pkg_amqp_client_description = RabbitMQ Erlang AMQP client +pkg_amqp_client_homepage = https://www.rabbitmq.com/erlang-client-user-guide.html +pkg_amqp_client_fetch = git +pkg_amqp_client_repo = https://github.com/rabbitmq/rabbitmq-erlang-client.git +pkg_amqp_client_commit = master + +PACKAGES += annotations +pkg_annotations_name = annotations +pkg_annotations_description = Simple code instrumentation utilities +pkg_annotations_homepage = https://github.com/hyperthunk/annotations +pkg_annotations_fetch = git +pkg_annotations_repo = https://github.com/hyperthunk/annotations +pkg_annotations_commit = master + +PACKAGES += antidote +pkg_antidote_name = antidote +pkg_antidote_description = Large-scale computation without synchronisation +pkg_antidote_homepage = https://syncfree.lip6.fr/ +pkg_antidote_fetch = git +pkg_antidote_repo = https://github.com/SyncFree/antidote +pkg_antidote_commit = master + +PACKAGES += apns +pkg_apns_name = apns +pkg_apns_description = Apple Push Notification Server for Erlang +pkg_apns_homepage = http://inaka.github.com/apns4erl +pkg_apns_fetch = git +pkg_apns_repo = https://github.com/inaka/apns4erl +pkg_apns_commit = master + +PACKAGES += asciideck +pkg_asciideck_name = asciideck +pkg_asciideck_description = Asciidoc for Erlang. +pkg_asciideck_homepage = https://ninenines.eu +pkg_asciideck_fetch = git +pkg_asciideck_repo = https://github.com/ninenines/asciideck +pkg_asciideck_commit = master + +PACKAGES += azdht +pkg_azdht_name = azdht +pkg_azdht_description = Azureus Distributed Hash Table (DHT) in Erlang +pkg_azdht_homepage = https://github.com/arcusfelis/azdht +pkg_azdht_fetch = git +pkg_azdht_repo = https://github.com/arcusfelis/azdht +pkg_azdht_commit = master + +PACKAGES += backoff +pkg_backoff_name = backoff +pkg_backoff_description = Simple exponential backoffs in Erlang +pkg_backoff_homepage = https://github.com/ferd/backoff +pkg_backoff_fetch = git +pkg_backoff_repo = https://github.com/ferd/backoff +pkg_backoff_commit = master + +PACKAGES += barrel_tcp +pkg_barrel_tcp_name = barrel_tcp +pkg_barrel_tcp_description = barrel is a generic TCP acceptor pool with low latency in Erlang. +pkg_barrel_tcp_homepage = https://github.com/benoitc-attic/barrel_tcp +pkg_barrel_tcp_fetch = git +pkg_barrel_tcp_repo = https://github.com/benoitc-attic/barrel_tcp +pkg_barrel_tcp_commit = master + +PACKAGES += basho_bench +pkg_basho_bench_name = basho_bench +pkg_basho_bench_description = A load-generation and testing tool for basically whatever you can write a returning Erlang function for. +pkg_basho_bench_homepage = https://github.com/basho/basho_bench +pkg_basho_bench_fetch = git +pkg_basho_bench_repo = https://github.com/basho/basho_bench +pkg_basho_bench_commit = master + +PACKAGES += bcrypt +pkg_bcrypt_name = bcrypt +pkg_bcrypt_description = Bcrypt Erlang / C library +pkg_bcrypt_homepage = https://github.com/erlangpack/bcrypt +pkg_bcrypt_fetch = git +pkg_bcrypt_repo = https://github.com/erlangpack/bcrypt.git +pkg_bcrypt_commit = master + +PACKAGES += beam +pkg_beam_name = beam +pkg_beam_description = BEAM emulator written in Erlang +pkg_beam_homepage = https://github.com/tonyrog/beam +pkg_beam_fetch = git +pkg_beam_repo = https://github.com/tonyrog/beam +pkg_beam_commit = master + +PACKAGES += beanstalk +pkg_beanstalk_name = beanstalk +pkg_beanstalk_description = An Erlang client for beanstalkd +pkg_beanstalk_homepage = https://github.com/tim/erlang-beanstalk +pkg_beanstalk_fetch = git +pkg_beanstalk_repo = https://github.com/tim/erlang-beanstalk +pkg_beanstalk_commit = master + +PACKAGES += bear +pkg_bear_name = bear +pkg_bear_description = a set of statistics functions for erlang +pkg_bear_homepage = https://github.com/boundary/bear +pkg_bear_fetch = git +pkg_bear_repo = https://github.com/boundary/bear +pkg_bear_commit = master + +PACKAGES += bertconf +pkg_bertconf_name = bertconf +pkg_bertconf_description = Make ETS tables out of statc BERT files that are auto-reloaded +pkg_bertconf_homepage = https://github.com/ferd/bertconf +pkg_bertconf_fetch = git +pkg_bertconf_repo = https://github.com/ferd/bertconf +pkg_bertconf_commit = master + +PACKAGES += bifrost +pkg_bifrost_name = bifrost +pkg_bifrost_description = Erlang FTP Server Framework +pkg_bifrost_homepage = https://github.com/thorstadt/bifrost +pkg_bifrost_fetch = git +pkg_bifrost_repo = https://github.com/thorstadt/bifrost +pkg_bifrost_commit = master + +PACKAGES += binpp +pkg_binpp_name = binpp +pkg_binpp_description = Erlang Binary Pretty Printer +pkg_binpp_homepage = https://github.com/jtendo/binpp +pkg_binpp_fetch = git +pkg_binpp_repo = https://github.com/jtendo/binpp +pkg_binpp_commit = master + +PACKAGES += bisect +pkg_bisect_name = bisect +pkg_bisect_description = Ordered fixed-size binary dictionary in Erlang +pkg_bisect_homepage = https://github.com/knutin/bisect +pkg_bisect_fetch = git +pkg_bisect_repo = https://github.com/knutin/bisect +pkg_bisect_commit = master + +PACKAGES += bitcask +pkg_bitcask_name = bitcask +pkg_bitcask_description = because you need another a key/value storage engine +pkg_bitcask_homepage = https://github.com/basho/bitcask +pkg_bitcask_fetch = git +pkg_bitcask_repo = https://github.com/basho/bitcask +pkg_bitcask_commit = develop + +PACKAGES += bitstore +pkg_bitstore_name = bitstore +pkg_bitstore_description = A document based ontology development environment +pkg_bitstore_homepage = https://github.com/bdionne/bitstore +pkg_bitstore_fetch = git +pkg_bitstore_repo = https://github.com/bdionne/bitstore +pkg_bitstore_commit = master + +PACKAGES += bootstrap +pkg_bootstrap_name = bootstrap +pkg_bootstrap_description = A simple, yet powerful Erlang cluster bootstrapping application. +pkg_bootstrap_homepage = https://github.com/schlagert/bootstrap +pkg_bootstrap_fetch = git +pkg_bootstrap_repo = https://github.com/schlagert/bootstrap +pkg_bootstrap_commit = master + +PACKAGES += boss +pkg_boss_name = boss +pkg_boss_description = Erlang web MVC, now featuring Comet +pkg_boss_homepage = https://github.com/ChicagoBoss/ChicagoBoss +pkg_boss_fetch = git +pkg_boss_repo = https://github.com/ChicagoBoss/ChicagoBoss +pkg_boss_commit = master + +PACKAGES += boss_db +pkg_boss_db_name = boss_db +pkg_boss_db_description = BossDB: a sharded, caching, pooling, evented ORM for Erlang +pkg_boss_db_homepage = https://github.com/ErlyORM/boss_db +pkg_boss_db_fetch = git +pkg_boss_db_repo = https://github.com/ErlyORM/boss_db +pkg_boss_db_commit = master + +PACKAGES += brod +pkg_brod_name = brod +pkg_brod_description = Kafka client in Erlang +pkg_brod_homepage = https://github.com/klarna/brod +pkg_brod_fetch = git +pkg_brod_repo = https://github.com/klarna/brod.git +pkg_brod_commit = master + +PACKAGES += bson +pkg_bson_name = bson +pkg_bson_description = BSON documents in Erlang, see bsonspec.org +pkg_bson_homepage = https://github.com/comtihon/bson-erlang +pkg_bson_fetch = git +pkg_bson_repo = https://github.com/comtihon/bson-erlang +pkg_bson_commit = master + +PACKAGES += bullet +pkg_bullet_name = bullet +pkg_bullet_description = Simple, reliable, efficient streaming for Cowboy. +pkg_bullet_homepage = http://ninenines.eu +pkg_bullet_fetch = git +pkg_bullet_repo = https://github.com/ninenines/bullet +pkg_bullet_commit = master + +PACKAGES += cache +pkg_cache_name = cache +pkg_cache_description = Erlang in-memory cache +pkg_cache_homepage = https://github.com/fogfish/cache +pkg_cache_fetch = git +pkg_cache_repo = https://github.com/fogfish/cache +pkg_cache_commit = master + +PACKAGES += cake +pkg_cake_name = cake +pkg_cake_description = Really simple terminal colorization +pkg_cake_homepage = https://github.com/darach/cake-erl +pkg_cake_fetch = git +pkg_cake_repo = https://github.com/darach/cake-erl +pkg_cake_commit = master + +PACKAGES += carotene +pkg_carotene_name = carotene +pkg_carotene_description = Real-time server +pkg_carotene_homepage = https://github.com/carotene/carotene +pkg_carotene_fetch = git +pkg_carotene_repo = https://github.com/carotene/carotene +pkg_carotene_commit = master + +PACKAGES += cberl +pkg_cberl_name = cberl +pkg_cberl_description = NIF based Erlang bindings for Couchbase +pkg_cberl_homepage = https://github.com/chitika/cberl +pkg_cberl_fetch = git +pkg_cberl_repo = https://github.com/chitika/cberl +pkg_cberl_commit = master + +PACKAGES += cecho +pkg_cecho_name = cecho +pkg_cecho_description = An ncurses library for Erlang +pkg_cecho_homepage = https://github.com/mazenharake/cecho +pkg_cecho_fetch = git +pkg_cecho_repo = https://github.com/mazenharake/cecho +pkg_cecho_commit = master + +PACKAGES += cferl +pkg_cferl_name = cferl +pkg_cferl_description = Rackspace / Open Stack Cloud Files Erlang Client +pkg_cferl_homepage = https://github.com/ddossot/cferl +pkg_cferl_fetch = git +pkg_cferl_repo = https://github.com/ddossot/cferl +pkg_cferl_commit = master + +PACKAGES += chaos_monkey +pkg_chaos_monkey_name = chaos_monkey +pkg_chaos_monkey_description = This is The CHAOS MONKEY. It will kill your processes. +pkg_chaos_monkey_homepage = https://github.com/dLuna/chaos_monkey +pkg_chaos_monkey_fetch = git +pkg_chaos_monkey_repo = https://github.com/dLuna/chaos_monkey +pkg_chaos_monkey_commit = master + +PACKAGES += check_node +pkg_check_node_name = check_node +pkg_check_node_description = Nagios Scripts for monitoring Riak +pkg_check_node_homepage = https://github.com/basho-labs/riak_nagios +pkg_check_node_fetch = git +pkg_check_node_repo = https://github.com/basho-labs/riak_nagios +pkg_check_node_commit = master + +PACKAGES += chronos +pkg_chronos_name = chronos +pkg_chronos_description = Timer module for Erlang that makes it easy to abstact time out of the tests. +pkg_chronos_homepage = https://github.com/lehoff/chronos +pkg_chronos_fetch = git +pkg_chronos_repo = https://github.com/lehoff/chronos +pkg_chronos_commit = master + +PACKAGES += chumak +pkg_chumak_name = chumak +pkg_chumak_description = Pure Erlang implementation of ZeroMQ Message Transport Protocol. +pkg_chumak_homepage = http://choven.ca +pkg_chumak_fetch = git +pkg_chumak_repo = https://github.com/chovencorp/chumak +pkg_chumak_commit = master + +PACKAGES += cl +pkg_cl_name = cl +pkg_cl_description = OpenCL binding for Erlang +pkg_cl_homepage = https://github.com/tonyrog/cl +pkg_cl_fetch = git +pkg_cl_repo = https://github.com/tonyrog/cl +pkg_cl_commit = master + +PACKAGES += clique +pkg_clique_name = clique +pkg_clique_description = CLI Framework for Erlang +pkg_clique_homepage = https://github.com/basho/clique +pkg_clique_fetch = git +pkg_clique_repo = https://github.com/basho/clique +pkg_clique_commit = develop + +PACKAGES += cloudi_core +pkg_cloudi_core_name = cloudi_core +pkg_cloudi_core_description = CloudI internal service runtime +pkg_cloudi_core_homepage = http://cloudi.org/ +pkg_cloudi_core_fetch = git +pkg_cloudi_core_repo = https://github.com/CloudI/cloudi_core +pkg_cloudi_core_commit = master + +PACKAGES += cloudi_service_api_requests +pkg_cloudi_service_api_requests_name = cloudi_service_api_requests +pkg_cloudi_service_api_requests_description = CloudI Service API requests (JSON-RPC/Erlang-term support) +pkg_cloudi_service_api_requests_homepage = http://cloudi.org/ +pkg_cloudi_service_api_requests_fetch = git +pkg_cloudi_service_api_requests_repo = https://github.com/CloudI/cloudi_service_api_requests +pkg_cloudi_service_api_requests_commit = master + +PACKAGES += cloudi_service_db +pkg_cloudi_service_db_name = cloudi_service_db +pkg_cloudi_service_db_description = CloudI Database (in-memory/testing/generic) +pkg_cloudi_service_db_homepage = http://cloudi.org/ +pkg_cloudi_service_db_fetch = git +pkg_cloudi_service_db_repo = https://github.com/CloudI/cloudi_service_db +pkg_cloudi_service_db_commit = master + +PACKAGES += cloudi_service_db_cassandra +pkg_cloudi_service_db_cassandra_name = cloudi_service_db_cassandra +pkg_cloudi_service_db_cassandra_description = Cassandra CloudI Service +pkg_cloudi_service_db_cassandra_homepage = http://cloudi.org/ +pkg_cloudi_service_db_cassandra_fetch = git +pkg_cloudi_service_db_cassandra_repo = https://github.com/CloudI/cloudi_service_db_cassandra +pkg_cloudi_service_db_cassandra_commit = master + +PACKAGES += cloudi_service_db_cassandra_cql +pkg_cloudi_service_db_cassandra_cql_name = cloudi_service_db_cassandra_cql +pkg_cloudi_service_db_cassandra_cql_description = Cassandra CQL CloudI Service +pkg_cloudi_service_db_cassandra_cql_homepage = http://cloudi.org/ +pkg_cloudi_service_db_cassandra_cql_fetch = git +pkg_cloudi_service_db_cassandra_cql_repo = https://github.com/CloudI/cloudi_service_db_cassandra_cql +pkg_cloudi_service_db_cassandra_cql_commit = master + +PACKAGES += cloudi_service_db_couchdb +pkg_cloudi_service_db_couchdb_name = cloudi_service_db_couchdb +pkg_cloudi_service_db_couchdb_description = CouchDB CloudI Service +pkg_cloudi_service_db_couchdb_homepage = http://cloudi.org/ +pkg_cloudi_service_db_couchdb_fetch = git +pkg_cloudi_service_db_couchdb_repo = https://github.com/CloudI/cloudi_service_db_couchdb +pkg_cloudi_service_db_couchdb_commit = master + +PACKAGES += cloudi_service_db_elasticsearch +pkg_cloudi_service_db_elasticsearch_name = cloudi_service_db_elasticsearch +pkg_cloudi_service_db_elasticsearch_description = elasticsearch CloudI Service +pkg_cloudi_service_db_elasticsearch_homepage = http://cloudi.org/ +pkg_cloudi_service_db_elasticsearch_fetch = git +pkg_cloudi_service_db_elasticsearch_repo = https://github.com/CloudI/cloudi_service_db_elasticsearch +pkg_cloudi_service_db_elasticsearch_commit = master + +PACKAGES += cloudi_service_db_memcached +pkg_cloudi_service_db_memcached_name = cloudi_service_db_memcached +pkg_cloudi_service_db_memcached_description = memcached CloudI Service +pkg_cloudi_service_db_memcached_homepage = http://cloudi.org/ +pkg_cloudi_service_db_memcached_fetch = git +pkg_cloudi_service_db_memcached_repo = https://github.com/CloudI/cloudi_service_db_memcached +pkg_cloudi_service_db_memcached_commit = master + +PACKAGES += cloudi_service_db_mysql +pkg_cloudi_service_db_mysql_name = cloudi_service_db_mysql +pkg_cloudi_service_db_mysql_description = MySQL CloudI Service +pkg_cloudi_service_db_mysql_homepage = http://cloudi.org/ +pkg_cloudi_service_db_mysql_fetch = git +pkg_cloudi_service_db_mysql_repo = https://github.com/CloudI/cloudi_service_db_mysql +pkg_cloudi_service_db_mysql_commit = master + +PACKAGES += cloudi_service_db_pgsql +pkg_cloudi_service_db_pgsql_name = cloudi_service_db_pgsql +pkg_cloudi_service_db_pgsql_description = PostgreSQL CloudI Service +pkg_cloudi_service_db_pgsql_homepage = http://cloudi.org/ +pkg_cloudi_service_db_pgsql_fetch = git +pkg_cloudi_service_db_pgsql_repo = https://github.com/CloudI/cloudi_service_db_pgsql +pkg_cloudi_service_db_pgsql_commit = master + +PACKAGES += cloudi_service_db_riak +pkg_cloudi_service_db_riak_name = cloudi_service_db_riak +pkg_cloudi_service_db_riak_description = Riak CloudI Service +pkg_cloudi_service_db_riak_homepage = http://cloudi.org/ +pkg_cloudi_service_db_riak_fetch = git +pkg_cloudi_service_db_riak_repo = https://github.com/CloudI/cloudi_service_db_riak +pkg_cloudi_service_db_riak_commit = master + +PACKAGES += cloudi_service_db_tokyotyrant +pkg_cloudi_service_db_tokyotyrant_name = cloudi_service_db_tokyotyrant +pkg_cloudi_service_db_tokyotyrant_description = Tokyo Tyrant CloudI Service +pkg_cloudi_service_db_tokyotyrant_homepage = http://cloudi.org/ +pkg_cloudi_service_db_tokyotyrant_fetch = git +pkg_cloudi_service_db_tokyotyrant_repo = https://github.com/CloudI/cloudi_service_db_tokyotyrant +pkg_cloudi_service_db_tokyotyrant_commit = master + +PACKAGES += cloudi_service_filesystem +pkg_cloudi_service_filesystem_name = cloudi_service_filesystem +pkg_cloudi_service_filesystem_description = Filesystem CloudI Service +pkg_cloudi_service_filesystem_homepage = http://cloudi.org/ +pkg_cloudi_service_filesystem_fetch = git +pkg_cloudi_service_filesystem_repo = https://github.com/CloudI/cloudi_service_filesystem +pkg_cloudi_service_filesystem_commit = master + +PACKAGES += cloudi_service_http_client +pkg_cloudi_service_http_client_name = cloudi_service_http_client +pkg_cloudi_service_http_client_description = HTTP client CloudI Service +pkg_cloudi_service_http_client_homepage = http://cloudi.org/ +pkg_cloudi_service_http_client_fetch = git +pkg_cloudi_service_http_client_repo = https://github.com/CloudI/cloudi_service_http_client +pkg_cloudi_service_http_client_commit = master + +PACKAGES += cloudi_service_http_cowboy +pkg_cloudi_service_http_cowboy_name = cloudi_service_http_cowboy +pkg_cloudi_service_http_cowboy_description = cowboy HTTP/HTTPS CloudI Service +pkg_cloudi_service_http_cowboy_homepage = http://cloudi.org/ +pkg_cloudi_service_http_cowboy_fetch = git +pkg_cloudi_service_http_cowboy_repo = https://github.com/CloudI/cloudi_service_http_cowboy +pkg_cloudi_service_http_cowboy_commit = master + +PACKAGES += cloudi_service_http_elli +pkg_cloudi_service_http_elli_name = cloudi_service_http_elli +pkg_cloudi_service_http_elli_description = elli HTTP CloudI Service +pkg_cloudi_service_http_elli_homepage = http://cloudi.org/ +pkg_cloudi_service_http_elli_fetch = git +pkg_cloudi_service_http_elli_repo = https://github.com/CloudI/cloudi_service_http_elli +pkg_cloudi_service_http_elli_commit = master + +PACKAGES += cloudi_service_map_reduce +pkg_cloudi_service_map_reduce_name = cloudi_service_map_reduce +pkg_cloudi_service_map_reduce_description = Map/Reduce CloudI Service +pkg_cloudi_service_map_reduce_homepage = http://cloudi.org/ +pkg_cloudi_service_map_reduce_fetch = git +pkg_cloudi_service_map_reduce_repo = https://github.com/CloudI/cloudi_service_map_reduce +pkg_cloudi_service_map_reduce_commit = master + +PACKAGES += cloudi_service_oauth1 +pkg_cloudi_service_oauth1_name = cloudi_service_oauth1 +pkg_cloudi_service_oauth1_description = OAuth v1.0 CloudI Service +pkg_cloudi_service_oauth1_homepage = http://cloudi.org/ +pkg_cloudi_service_oauth1_fetch = git +pkg_cloudi_service_oauth1_repo = https://github.com/CloudI/cloudi_service_oauth1 +pkg_cloudi_service_oauth1_commit = master + +PACKAGES += cloudi_service_queue +pkg_cloudi_service_queue_name = cloudi_service_queue +pkg_cloudi_service_queue_description = Persistent Queue Service +pkg_cloudi_service_queue_homepage = http://cloudi.org/ +pkg_cloudi_service_queue_fetch = git +pkg_cloudi_service_queue_repo = https://github.com/CloudI/cloudi_service_queue +pkg_cloudi_service_queue_commit = master + +PACKAGES += cloudi_service_quorum +pkg_cloudi_service_quorum_name = cloudi_service_quorum +pkg_cloudi_service_quorum_description = CloudI Quorum Service +pkg_cloudi_service_quorum_homepage = http://cloudi.org/ +pkg_cloudi_service_quorum_fetch = git +pkg_cloudi_service_quorum_repo = https://github.com/CloudI/cloudi_service_quorum +pkg_cloudi_service_quorum_commit = master + +PACKAGES += cloudi_service_router +pkg_cloudi_service_router_name = cloudi_service_router +pkg_cloudi_service_router_description = CloudI Router Service +pkg_cloudi_service_router_homepage = http://cloudi.org/ +pkg_cloudi_service_router_fetch = git +pkg_cloudi_service_router_repo = https://github.com/CloudI/cloudi_service_router +pkg_cloudi_service_router_commit = master + +PACKAGES += cloudi_service_tcp +pkg_cloudi_service_tcp_name = cloudi_service_tcp +pkg_cloudi_service_tcp_description = TCP CloudI Service +pkg_cloudi_service_tcp_homepage = http://cloudi.org/ +pkg_cloudi_service_tcp_fetch = git +pkg_cloudi_service_tcp_repo = https://github.com/CloudI/cloudi_service_tcp +pkg_cloudi_service_tcp_commit = master + +PACKAGES += cloudi_service_timers +pkg_cloudi_service_timers_name = cloudi_service_timers +pkg_cloudi_service_timers_description = Timers CloudI Service +pkg_cloudi_service_timers_homepage = http://cloudi.org/ +pkg_cloudi_service_timers_fetch = git +pkg_cloudi_service_timers_repo = https://github.com/CloudI/cloudi_service_timers +pkg_cloudi_service_timers_commit = master + +PACKAGES += cloudi_service_udp +pkg_cloudi_service_udp_name = cloudi_service_udp +pkg_cloudi_service_udp_description = UDP CloudI Service +pkg_cloudi_service_udp_homepage = http://cloudi.org/ +pkg_cloudi_service_udp_fetch = git +pkg_cloudi_service_udp_repo = https://github.com/CloudI/cloudi_service_udp +pkg_cloudi_service_udp_commit = master + +PACKAGES += cloudi_service_validate +pkg_cloudi_service_validate_name = cloudi_service_validate +pkg_cloudi_service_validate_description = CloudI Validate Service +pkg_cloudi_service_validate_homepage = http://cloudi.org/ +pkg_cloudi_service_validate_fetch = git +pkg_cloudi_service_validate_repo = https://github.com/CloudI/cloudi_service_validate +pkg_cloudi_service_validate_commit = master + +PACKAGES += cloudi_service_zeromq +pkg_cloudi_service_zeromq_name = cloudi_service_zeromq +pkg_cloudi_service_zeromq_description = ZeroMQ CloudI Service +pkg_cloudi_service_zeromq_homepage = http://cloudi.org/ +pkg_cloudi_service_zeromq_fetch = git +pkg_cloudi_service_zeromq_repo = https://github.com/CloudI/cloudi_service_zeromq +pkg_cloudi_service_zeromq_commit = master + +PACKAGES += cluster_info +pkg_cluster_info_name = cluster_info +pkg_cluster_info_description = Fork of Hibari's nifty cluster_info OTP app +pkg_cluster_info_homepage = https://github.com/basho/cluster_info +pkg_cluster_info_fetch = git +pkg_cluster_info_repo = https://github.com/basho/cluster_info +pkg_cluster_info_commit = master + +PACKAGES += color +pkg_color_name = color +pkg_color_description = ANSI colors for your Erlang +pkg_color_homepage = https://github.com/julianduque/erlang-color +pkg_color_fetch = git +pkg_color_repo = https://github.com/julianduque/erlang-color +pkg_color_commit = master + +PACKAGES += confetti +pkg_confetti_name = confetti +pkg_confetti_description = Erlang configuration provider / application:get_env/2 on steroids +pkg_confetti_homepage = https://github.com/jtendo/confetti +pkg_confetti_fetch = git +pkg_confetti_repo = https://github.com/jtendo/confetti +pkg_confetti_commit = master + +PACKAGES += couchbeam +pkg_couchbeam_name = couchbeam +pkg_couchbeam_description = Apache CouchDB client in Erlang +pkg_couchbeam_homepage = https://github.com/benoitc/couchbeam +pkg_couchbeam_fetch = git +pkg_couchbeam_repo = https://github.com/benoitc/couchbeam +pkg_couchbeam_commit = master + +PACKAGES += covertool +pkg_covertool_name = covertool +pkg_covertool_description = Tool to convert Erlang cover data files into Cobertura XML reports +pkg_covertool_homepage = https://github.com/idubrov/covertool +pkg_covertool_fetch = git +pkg_covertool_repo = https://github.com/idubrov/covertool +pkg_covertool_commit = master + +PACKAGES += cowboy +pkg_cowboy_name = cowboy +pkg_cowboy_description = Small, fast and modular HTTP server. +pkg_cowboy_homepage = http://ninenines.eu +pkg_cowboy_fetch = git +pkg_cowboy_repo = https://github.com/ninenines/cowboy +pkg_cowboy_commit = 1.0.4 + +PACKAGES += cowdb +pkg_cowdb_name = cowdb +pkg_cowdb_description = Pure Key/Value database library for Erlang Applications +pkg_cowdb_homepage = https://github.com/refuge/cowdb +pkg_cowdb_fetch = git +pkg_cowdb_repo = https://github.com/refuge/cowdb +pkg_cowdb_commit = master + +PACKAGES += cowlib +pkg_cowlib_name = cowlib +pkg_cowlib_description = Support library for manipulating Web protocols. +pkg_cowlib_homepage = http://ninenines.eu +pkg_cowlib_fetch = git +pkg_cowlib_repo = https://github.com/ninenines/cowlib +pkg_cowlib_commit = 1.0.2 + +PACKAGES += cpg +pkg_cpg_name = cpg +pkg_cpg_description = CloudI Process Groups +pkg_cpg_homepage = https://github.com/okeuday/cpg +pkg_cpg_fetch = git +pkg_cpg_repo = https://github.com/okeuday/cpg +pkg_cpg_commit = master + +PACKAGES += cqerl +pkg_cqerl_name = cqerl +pkg_cqerl_description = Native Erlang CQL client for Cassandra +pkg_cqerl_homepage = https://matehat.github.io/cqerl/ +pkg_cqerl_fetch = git +pkg_cqerl_repo = https://github.com/matehat/cqerl +pkg_cqerl_commit = master + +PACKAGES += cr +pkg_cr_name = cr +pkg_cr_description = Chain Replication +pkg_cr_homepage = https://synrc.com/apps/cr/doc/cr.htm +pkg_cr_fetch = git +pkg_cr_repo = https://github.com/spawnproc/cr +pkg_cr_commit = master + +PACKAGES += cuttlefish +pkg_cuttlefish_name = cuttlefish +pkg_cuttlefish_description = never lose your childlike sense of wonder baby cuttlefish, promise me? +pkg_cuttlefish_homepage = https://github.com/basho/cuttlefish +pkg_cuttlefish_fetch = git +pkg_cuttlefish_repo = https://github.com/basho/cuttlefish +pkg_cuttlefish_commit = master + +PACKAGES += damocles +pkg_damocles_name = damocles +pkg_damocles_description = Erlang library for generating adversarial network conditions for QAing distributed applications/systems on a single Linux box. +pkg_damocles_homepage = https://github.com/lostcolony/damocles +pkg_damocles_fetch = git +pkg_damocles_repo = https://github.com/lostcolony/damocles +pkg_damocles_commit = master + +PACKAGES += debbie +pkg_debbie_name = debbie +pkg_debbie_description = .DEB Built In Erlang +pkg_debbie_homepage = https://github.com/crownedgrouse/debbie +pkg_debbie_fetch = git +pkg_debbie_repo = https://github.com/crownedgrouse/debbie +pkg_debbie_commit = master + +PACKAGES += decimal +pkg_decimal_name = decimal +pkg_decimal_description = An Erlang decimal arithmetic library +pkg_decimal_homepage = https://github.com/tim/erlang-decimal +pkg_decimal_fetch = git +pkg_decimal_repo = https://github.com/tim/erlang-decimal +pkg_decimal_commit = master + +PACKAGES += detergent +pkg_detergent_name = detergent +pkg_detergent_description = An emulsifying Erlang SOAP library +pkg_detergent_homepage = https://github.com/devinus/detergent +pkg_detergent_fetch = git +pkg_detergent_repo = https://github.com/devinus/detergent +pkg_detergent_commit = master + +PACKAGES += detest +pkg_detest_name = detest +pkg_detest_description = Tool for running tests on a cluster of erlang nodes +pkg_detest_homepage = https://github.com/biokoda/detest +pkg_detest_fetch = git +pkg_detest_repo = https://github.com/biokoda/detest +pkg_detest_commit = master + +PACKAGES += dh_date +pkg_dh_date_name = dh_date +pkg_dh_date_description = Date formatting / parsing library for erlang +pkg_dh_date_homepage = https://github.com/daleharvey/dh_date +pkg_dh_date_fetch = git +pkg_dh_date_repo = https://github.com/daleharvey/dh_date +pkg_dh_date_commit = master + +PACKAGES += dirbusterl +pkg_dirbusterl_name = dirbusterl +pkg_dirbusterl_description = DirBuster successor in Erlang +pkg_dirbusterl_homepage = https://github.com/silentsignal/DirBustErl +pkg_dirbusterl_fetch = git +pkg_dirbusterl_repo = https://github.com/silentsignal/DirBustErl +pkg_dirbusterl_commit = master + +PACKAGES += dispcount +pkg_dispcount_name = dispcount +pkg_dispcount_description = Erlang task dispatcher based on ETS counters. +pkg_dispcount_homepage = https://github.com/ferd/dispcount +pkg_dispcount_fetch = git +pkg_dispcount_repo = https://github.com/ferd/dispcount +pkg_dispcount_commit = master + +PACKAGES += dlhttpc +pkg_dlhttpc_name = dlhttpc +pkg_dlhttpc_description = dispcount-based lhttpc fork for massive amounts of requests to limited endpoints +pkg_dlhttpc_homepage = https://github.com/ferd/dlhttpc +pkg_dlhttpc_fetch = git +pkg_dlhttpc_repo = https://github.com/ferd/dlhttpc +pkg_dlhttpc_commit = master + +PACKAGES += dns +pkg_dns_name = dns +pkg_dns_description = Erlang DNS library +pkg_dns_homepage = https://github.com/aetrion/dns_erlang +pkg_dns_fetch = git +pkg_dns_repo = https://github.com/aetrion/dns_erlang +pkg_dns_commit = master + +PACKAGES += dnssd +pkg_dnssd_name = dnssd +pkg_dnssd_description = Erlang interface to Apple's Bonjour D NS Service Discovery implementation +pkg_dnssd_homepage = https://github.com/benoitc/dnssd_erlang +pkg_dnssd_fetch = git +pkg_dnssd_repo = https://github.com/benoitc/dnssd_erlang +pkg_dnssd_commit = master + +PACKAGES += dynamic_compile +pkg_dynamic_compile_name = dynamic_compile +pkg_dynamic_compile_description = compile and load erlang modules from string input +pkg_dynamic_compile_homepage = https://github.com/jkvor/dynamic_compile +pkg_dynamic_compile_fetch = git +pkg_dynamic_compile_repo = https://github.com/jkvor/dynamic_compile +pkg_dynamic_compile_commit = master + +PACKAGES += e2 +pkg_e2_name = e2 +pkg_e2_description = Library to simply writing correct OTP applications. +pkg_e2_homepage = http://e2project.org +pkg_e2_fetch = git +pkg_e2_repo = https://github.com/gar1t/e2 +pkg_e2_commit = master + +PACKAGES += eamf +pkg_eamf_name = eamf +pkg_eamf_description = eAMF provides Action Message Format (AMF) support for Erlang +pkg_eamf_homepage = https://github.com/mrinalwadhwa/eamf +pkg_eamf_fetch = git +pkg_eamf_repo = https://github.com/mrinalwadhwa/eamf +pkg_eamf_commit = master + +PACKAGES += eavro +pkg_eavro_name = eavro +pkg_eavro_description = Apache Avro encoder/decoder +pkg_eavro_homepage = https://github.com/SIfoxDevTeam/eavro +pkg_eavro_fetch = git +pkg_eavro_repo = https://github.com/SIfoxDevTeam/eavro +pkg_eavro_commit = master + +PACKAGES += ecapnp +pkg_ecapnp_name = ecapnp +pkg_ecapnp_description = Cap'n Proto library for Erlang +pkg_ecapnp_homepage = https://github.com/kaos/ecapnp +pkg_ecapnp_fetch = git +pkg_ecapnp_repo = https://github.com/kaos/ecapnp +pkg_ecapnp_commit = master + +PACKAGES += econfig +pkg_econfig_name = econfig +pkg_econfig_description = simple Erlang config handler using INI files +pkg_econfig_homepage = https://github.com/benoitc/econfig +pkg_econfig_fetch = git +pkg_econfig_repo = https://github.com/benoitc/econfig +pkg_econfig_commit = master + +PACKAGES += edate +pkg_edate_name = edate +pkg_edate_description = date manipulation library for erlang +pkg_edate_homepage = https://github.com/dweldon/edate +pkg_edate_fetch = git +pkg_edate_repo = https://github.com/dweldon/edate +pkg_edate_commit = master + +PACKAGES += edgar +pkg_edgar_name = edgar +pkg_edgar_description = Erlang Does GNU AR +pkg_edgar_homepage = https://github.com/crownedgrouse/edgar +pkg_edgar_fetch = git +pkg_edgar_repo = https://github.com/crownedgrouse/edgar +pkg_edgar_commit = master + +PACKAGES += edis +pkg_edis_name = edis +pkg_edis_description = An Erlang implementation of Redis KV Store +pkg_edis_homepage = http://inaka.github.com/edis/ +pkg_edis_fetch = git +pkg_edis_repo = https://github.com/inaka/edis +pkg_edis_commit = master + +PACKAGES += edns +pkg_edns_name = edns +pkg_edns_description = Erlang/OTP DNS server +pkg_edns_homepage = https://github.com/hcvst/erlang-dns +pkg_edns_fetch = git +pkg_edns_repo = https://github.com/hcvst/erlang-dns +pkg_edns_commit = master + +PACKAGES += edown +pkg_edown_name = edown +pkg_edown_description = EDoc extension for generating Github-flavored Markdown +pkg_edown_homepage = https://github.com/uwiger/edown +pkg_edown_fetch = git +pkg_edown_repo = https://github.com/uwiger/edown +pkg_edown_commit = master + +PACKAGES += eep +pkg_eep_name = eep +pkg_eep_description = Erlang Easy Profiling (eep) application provides a way to analyze application performance and call hierarchy +pkg_eep_homepage = https://github.com/virtan/eep +pkg_eep_fetch = git +pkg_eep_repo = https://github.com/virtan/eep +pkg_eep_commit = master + +PACKAGES += eep_app +pkg_eep_app_name = eep_app +pkg_eep_app_description = Embedded Event Processing +pkg_eep_app_homepage = https://github.com/darach/eep-erl +pkg_eep_app_fetch = git +pkg_eep_app_repo = https://github.com/darach/eep-erl +pkg_eep_app_commit = master + +PACKAGES += efene +pkg_efene_name = efene +pkg_efene_description = Alternative syntax for the Erlang Programming Language focusing on simplicity, ease of use and programmer UX +pkg_efene_homepage = https://github.com/efene/efene +pkg_efene_fetch = git +pkg_efene_repo = https://github.com/efene/efene +pkg_efene_commit = master + +PACKAGES += egeoip +pkg_egeoip_name = egeoip +pkg_egeoip_description = Erlang IP Geolocation module, currently supporting the MaxMind GeoLite City Database. +pkg_egeoip_homepage = https://github.com/mochi/egeoip +pkg_egeoip_fetch = git +pkg_egeoip_repo = https://github.com/mochi/egeoip +pkg_egeoip_commit = master + +PACKAGES += ehsa +pkg_ehsa_name = ehsa +pkg_ehsa_description = Erlang HTTP server basic and digest authentication modules +pkg_ehsa_homepage = https://bitbucket.org/a12n/ehsa +pkg_ehsa_fetch = hg +pkg_ehsa_repo = https://bitbucket.org/a12n/ehsa +pkg_ehsa_commit = default + +PACKAGES += ej +pkg_ej_name = ej +pkg_ej_description = Helper module for working with Erlang terms representing JSON +pkg_ej_homepage = https://github.com/seth/ej +pkg_ej_fetch = git +pkg_ej_repo = https://github.com/seth/ej +pkg_ej_commit = master + +PACKAGES += ejabberd +pkg_ejabberd_name = ejabberd +pkg_ejabberd_description = Robust, ubiquitous and massively scalable Jabber / XMPP Instant Messaging platform +pkg_ejabberd_homepage = https://github.com/processone/ejabberd +pkg_ejabberd_fetch = git +pkg_ejabberd_repo = https://github.com/processone/ejabberd +pkg_ejabberd_commit = master + +PACKAGES += ejwt +pkg_ejwt_name = ejwt +pkg_ejwt_description = erlang library for JSON Web Token +pkg_ejwt_homepage = https://github.com/artefactop/ejwt +pkg_ejwt_fetch = git +pkg_ejwt_repo = https://github.com/artefactop/ejwt +pkg_ejwt_commit = master + +PACKAGES += ekaf +pkg_ekaf_name = ekaf +pkg_ekaf_description = A minimal, high-performance Kafka client in Erlang. +pkg_ekaf_homepage = https://github.com/helpshift/ekaf +pkg_ekaf_fetch = git +pkg_ekaf_repo = https://github.com/helpshift/ekaf +pkg_ekaf_commit = master + +PACKAGES += elarm +pkg_elarm_name = elarm +pkg_elarm_description = Alarm Manager for Erlang. +pkg_elarm_homepage = https://github.com/esl/elarm +pkg_elarm_fetch = git +pkg_elarm_repo = https://github.com/esl/elarm +pkg_elarm_commit = master + +PACKAGES += eleveldb +pkg_eleveldb_name = eleveldb +pkg_eleveldb_description = Erlang LevelDB API +pkg_eleveldb_homepage = https://github.com/basho/eleveldb +pkg_eleveldb_fetch = git +pkg_eleveldb_repo = https://github.com/basho/eleveldb +pkg_eleveldb_commit = master + +PACKAGES += elixir +pkg_elixir_name = elixir +pkg_elixir_description = Elixir is a dynamic, functional language designed for building scalable and maintainable applications +pkg_elixir_homepage = https://elixir-lang.org/ +pkg_elixir_fetch = git +pkg_elixir_repo = https://github.com/elixir-lang/elixir +pkg_elixir_commit = master + +PACKAGES += elli +pkg_elli_name = elli +pkg_elli_description = Simple, robust and performant Erlang web server +pkg_elli_homepage = https://github.com/elli-lib/elli +pkg_elli_fetch = git +pkg_elli_repo = https://github.com/elli-lib/elli +pkg_elli_commit = master + +PACKAGES += elvis +pkg_elvis_name = elvis +pkg_elvis_description = Erlang Style Reviewer +pkg_elvis_homepage = https://github.com/inaka/elvis +pkg_elvis_fetch = git +pkg_elvis_repo = https://github.com/inaka/elvis +pkg_elvis_commit = master + +PACKAGES += emagick +pkg_emagick_name = emagick +pkg_emagick_description = Wrapper for Graphics/ImageMagick command line tool. +pkg_emagick_homepage = https://github.com/kivra/emagick +pkg_emagick_fetch = git +pkg_emagick_repo = https://github.com/kivra/emagick +pkg_emagick_commit = master + +PACKAGES += emysql +pkg_emysql_name = emysql +pkg_emysql_description = Stable, pure Erlang MySQL driver. +pkg_emysql_homepage = https://github.com/Eonblast/Emysql +pkg_emysql_fetch = git +pkg_emysql_repo = https://github.com/Eonblast/Emysql +pkg_emysql_commit = master + +PACKAGES += enm +pkg_enm_name = enm +pkg_enm_description = Erlang driver for nanomsg +pkg_enm_homepage = https://github.com/basho/enm +pkg_enm_fetch = git +pkg_enm_repo = https://github.com/basho/enm +pkg_enm_commit = master + +PACKAGES += entop +pkg_entop_name = entop +pkg_entop_description = A top-like tool for monitoring an Erlang node +pkg_entop_homepage = https://github.com/mazenharake/entop +pkg_entop_fetch = git +pkg_entop_repo = https://github.com/mazenharake/entop +pkg_entop_commit = master + +PACKAGES += epcap +pkg_epcap_name = epcap +pkg_epcap_description = Erlang packet capture interface using pcap +pkg_epcap_homepage = https://github.com/msantos/epcap +pkg_epcap_fetch = git +pkg_epcap_repo = https://github.com/msantos/epcap +pkg_epcap_commit = master + +PACKAGES += eper +pkg_eper_name = eper +pkg_eper_description = Erlang performance and debugging tools. +pkg_eper_homepage = https://github.com/massemanet/eper +pkg_eper_fetch = git +pkg_eper_repo = https://github.com/massemanet/eper +pkg_eper_commit = master + +PACKAGES += epgsql +pkg_epgsql_name = epgsql +pkg_epgsql_description = Erlang PostgreSQL client library. +pkg_epgsql_homepage = https://github.com/epgsql/epgsql +pkg_epgsql_fetch = git +pkg_epgsql_repo = https://github.com/epgsql/epgsql +pkg_epgsql_commit = master + +PACKAGES += episcina +pkg_episcina_name = episcina +pkg_episcina_description = A simple non intrusive resource pool for connections +pkg_episcina_homepage = https://github.com/erlware/episcina +pkg_episcina_fetch = git +pkg_episcina_repo = https://github.com/erlware/episcina +pkg_episcina_commit = master + +PACKAGES += eplot +pkg_eplot_name = eplot +pkg_eplot_description = A plot engine written in erlang. +pkg_eplot_homepage = https://github.com/psyeugenic/eplot +pkg_eplot_fetch = git +pkg_eplot_repo = https://github.com/psyeugenic/eplot +pkg_eplot_commit = master + +PACKAGES += epocxy +pkg_epocxy_name = epocxy +pkg_epocxy_description = Erlang Patterns of Concurrency +pkg_epocxy_homepage = https://github.com/duomark/epocxy +pkg_epocxy_fetch = git +pkg_epocxy_repo = https://github.com/duomark/epocxy +pkg_epocxy_commit = master + +PACKAGES += epubnub +pkg_epubnub_name = epubnub +pkg_epubnub_description = Erlang PubNub API +pkg_epubnub_homepage = https://github.com/tsloughter/epubnub +pkg_epubnub_fetch = git +pkg_epubnub_repo = https://github.com/tsloughter/epubnub +pkg_epubnub_commit = master + +PACKAGES += eqm +pkg_eqm_name = eqm +pkg_eqm_description = Erlang pub sub with supply-demand channels +pkg_eqm_homepage = https://github.com/loucash/eqm +pkg_eqm_fetch = git +pkg_eqm_repo = https://github.com/loucash/eqm +pkg_eqm_commit = master + +PACKAGES += eredis +pkg_eredis_name = eredis +pkg_eredis_description = Erlang Redis client +pkg_eredis_homepage = https://github.com/wooga/eredis +pkg_eredis_fetch = git +pkg_eredis_repo = https://github.com/wooga/eredis +pkg_eredis_commit = master + +PACKAGES += eredis_pool +pkg_eredis_pool_name = eredis_pool +pkg_eredis_pool_description = eredis_pool is Pool of Redis clients, using eredis and poolboy. +pkg_eredis_pool_homepage = https://github.com/hiroeorz/eredis_pool +pkg_eredis_pool_fetch = git +pkg_eredis_pool_repo = https://github.com/hiroeorz/eredis_pool +pkg_eredis_pool_commit = master + +PACKAGES += erl_streams +pkg_erl_streams_name = erl_streams +pkg_erl_streams_description = Streams in Erlang +pkg_erl_streams_homepage = https://github.com/epappas/erl_streams +pkg_erl_streams_fetch = git +pkg_erl_streams_repo = https://github.com/epappas/erl_streams +pkg_erl_streams_commit = master + +PACKAGES += erlang_cep +pkg_erlang_cep_name = erlang_cep +pkg_erlang_cep_description = A basic CEP package written in erlang +pkg_erlang_cep_homepage = https://github.com/danmacklin/erlang_cep +pkg_erlang_cep_fetch = git +pkg_erlang_cep_repo = https://github.com/danmacklin/erlang_cep +pkg_erlang_cep_commit = master + +PACKAGES += erlang_js +pkg_erlang_js_name = erlang_js +pkg_erlang_js_description = A linked-in driver for Erlang to Mozilla's Spidermonkey Javascript runtime. +pkg_erlang_js_homepage = https://github.com/basho/erlang_js +pkg_erlang_js_fetch = git +pkg_erlang_js_repo = https://github.com/basho/erlang_js +pkg_erlang_js_commit = master + +PACKAGES += erlang_localtime +pkg_erlang_localtime_name = erlang_localtime +pkg_erlang_localtime_description = Erlang library for conversion from one local time to another +pkg_erlang_localtime_homepage = https://github.com/dmitryme/erlang_localtime +pkg_erlang_localtime_fetch = git +pkg_erlang_localtime_repo = https://github.com/dmitryme/erlang_localtime +pkg_erlang_localtime_commit = master + +PACKAGES += erlang_smtp +pkg_erlang_smtp_name = erlang_smtp +pkg_erlang_smtp_description = Erlang SMTP and POP3 server code. +pkg_erlang_smtp_homepage = https://github.com/tonyg/erlang-smtp +pkg_erlang_smtp_fetch = git +pkg_erlang_smtp_repo = https://github.com/tonyg/erlang-smtp +pkg_erlang_smtp_commit = master + +PACKAGES += erlang_term +pkg_erlang_term_name = erlang_term +pkg_erlang_term_description = Erlang Term Info +pkg_erlang_term_homepage = https://github.com/okeuday/erlang_term +pkg_erlang_term_fetch = git +pkg_erlang_term_repo = https://github.com/okeuday/erlang_term +pkg_erlang_term_commit = master + +PACKAGES += erlastic_search +pkg_erlastic_search_name = erlastic_search +pkg_erlastic_search_description = An Erlang app for communicating with Elastic Search's rest interface. +pkg_erlastic_search_homepage = https://github.com/tsloughter/erlastic_search +pkg_erlastic_search_fetch = git +pkg_erlastic_search_repo = https://github.com/tsloughter/erlastic_search +pkg_erlastic_search_commit = master + +PACKAGES += erlasticsearch +pkg_erlasticsearch_name = erlasticsearch +pkg_erlasticsearch_description = Erlang thrift interface to elastic_search +pkg_erlasticsearch_homepage = https://github.com/dieswaytoofast/erlasticsearch +pkg_erlasticsearch_fetch = git +pkg_erlasticsearch_repo = https://github.com/dieswaytoofast/erlasticsearch +pkg_erlasticsearch_commit = master + +PACKAGES += erlbrake +pkg_erlbrake_name = erlbrake +pkg_erlbrake_description = Erlang Airbrake notification client +pkg_erlbrake_homepage = https://github.com/kenpratt/erlbrake +pkg_erlbrake_fetch = git +pkg_erlbrake_repo = https://github.com/kenpratt/erlbrake +pkg_erlbrake_commit = master + +PACKAGES += erlcloud +pkg_erlcloud_name = erlcloud +pkg_erlcloud_description = Cloud Computing library for erlang (Amazon EC2, S3, SQS, SimpleDB, Mechanical Turk, ELB) +pkg_erlcloud_homepage = https://github.com/gleber/erlcloud +pkg_erlcloud_fetch = git +pkg_erlcloud_repo = https://github.com/gleber/erlcloud +pkg_erlcloud_commit = master + +PACKAGES += erlcron +pkg_erlcron_name = erlcron +pkg_erlcron_description = Erlang cronish system +pkg_erlcron_homepage = https://github.com/erlware/erlcron +pkg_erlcron_fetch = git +pkg_erlcron_repo = https://github.com/erlware/erlcron +pkg_erlcron_commit = master + +PACKAGES += erldb +pkg_erldb_name = erldb +pkg_erldb_description = ORM (Object-relational mapping) application implemented in Erlang +pkg_erldb_homepage = http://erldb.org +pkg_erldb_fetch = git +pkg_erldb_repo = https://github.com/erldb/erldb +pkg_erldb_commit = master + +PACKAGES += erldis +pkg_erldis_name = erldis +pkg_erldis_description = redis erlang client library +pkg_erldis_homepage = https://github.com/cstar/erldis +pkg_erldis_fetch = git +pkg_erldis_repo = https://github.com/cstar/erldis +pkg_erldis_commit = master + +PACKAGES += erldns +pkg_erldns_name = erldns +pkg_erldns_description = DNS server, in erlang. +pkg_erldns_homepage = https://github.com/aetrion/erl-dns +pkg_erldns_fetch = git +pkg_erldns_repo = https://github.com/aetrion/erl-dns +pkg_erldns_commit = master + +PACKAGES += erldocker +pkg_erldocker_name = erldocker +pkg_erldocker_description = Docker Remote API client for Erlang +pkg_erldocker_homepage = https://github.com/proger/erldocker +pkg_erldocker_fetch = git +pkg_erldocker_repo = https://github.com/proger/erldocker +pkg_erldocker_commit = master + +PACKAGES += erlfsmon +pkg_erlfsmon_name = erlfsmon +pkg_erlfsmon_description = Erlang filesystem event watcher for Linux and OSX +pkg_erlfsmon_homepage = https://github.com/proger/erlfsmon +pkg_erlfsmon_fetch = git +pkg_erlfsmon_repo = https://github.com/proger/erlfsmon +pkg_erlfsmon_commit = master + +PACKAGES += erlgit +pkg_erlgit_name = erlgit +pkg_erlgit_description = Erlang convenience wrapper around git executable +pkg_erlgit_homepage = https://github.com/gleber/erlgit +pkg_erlgit_fetch = git +pkg_erlgit_repo = https://github.com/gleber/erlgit +pkg_erlgit_commit = master + +PACKAGES += erlguten +pkg_erlguten_name = erlguten +pkg_erlguten_description = ErlGuten is a system for high-quality typesetting, written purely in Erlang. +pkg_erlguten_homepage = https://github.com/richcarl/erlguten +pkg_erlguten_fetch = git +pkg_erlguten_repo = https://github.com/richcarl/erlguten +pkg_erlguten_commit = master + +PACKAGES += erlmc +pkg_erlmc_name = erlmc +pkg_erlmc_description = Erlang memcached binary protocol client +pkg_erlmc_homepage = https://github.com/jkvor/erlmc +pkg_erlmc_fetch = git +pkg_erlmc_repo = https://github.com/jkvor/erlmc +pkg_erlmc_commit = master + +PACKAGES += erlmongo +pkg_erlmongo_name = erlmongo +pkg_erlmongo_description = Record based Erlang driver for MongoDB with gridfs support +pkg_erlmongo_homepage = https://github.com/SergejJurecko/erlmongo +pkg_erlmongo_fetch = git +pkg_erlmongo_repo = https://github.com/SergejJurecko/erlmongo +pkg_erlmongo_commit = master + +PACKAGES += erlog +pkg_erlog_name = erlog +pkg_erlog_description = Prolog interpreter in and for Erlang +pkg_erlog_homepage = https://github.com/rvirding/erlog +pkg_erlog_fetch = git +pkg_erlog_repo = https://github.com/rvirding/erlog +pkg_erlog_commit = master + +PACKAGES += erlpass +pkg_erlpass_name = erlpass +pkg_erlpass_description = A library to handle password hashing and changing in a safe manner, independent from any kind of storage whatsoever. +pkg_erlpass_homepage = https://github.com/ferd/erlpass +pkg_erlpass_fetch = git +pkg_erlpass_repo = https://github.com/ferd/erlpass +pkg_erlpass_commit = master + +PACKAGES += erlport +pkg_erlport_name = erlport +pkg_erlport_description = ErlPort - connect Erlang to other languages +pkg_erlport_homepage = https://github.com/hdima/erlport +pkg_erlport_fetch = git +pkg_erlport_repo = https://github.com/hdima/erlport +pkg_erlport_commit = master + +PACKAGES += erlsh +pkg_erlsh_name = erlsh +pkg_erlsh_description = Erlang shell tools +pkg_erlsh_homepage = https://github.com/proger/erlsh +pkg_erlsh_fetch = git +pkg_erlsh_repo = https://github.com/proger/erlsh +pkg_erlsh_commit = master + +PACKAGES += erlsha2 +pkg_erlsha2_name = erlsha2 +pkg_erlsha2_description = SHA-224, SHA-256, SHA-384, SHA-512 implemented in Erlang NIFs. +pkg_erlsha2_homepage = https://github.com/vinoski/erlsha2 +pkg_erlsha2_fetch = git +pkg_erlsha2_repo = https://github.com/vinoski/erlsha2 +pkg_erlsha2_commit = master + +PACKAGES += erlsom +pkg_erlsom_name = erlsom +pkg_erlsom_description = XML parser for Erlang +pkg_erlsom_homepage = https://github.com/willemdj/erlsom +pkg_erlsom_fetch = git +pkg_erlsom_repo = https://github.com/willemdj/erlsom +pkg_erlsom_commit = master + +PACKAGES += erlubi +pkg_erlubi_name = erlubi +pkg_erlubi_description = Ubigraph Erlang Client (and Process Visualizer) +pkg_erlubi_homepage = https://github.com/krestenkrab/erlubi +pkg_erlubi_fetch = git +pkg_erlubi_repo = https://github.com/krestenkrab/erlubi +pkg_erlubi_commit = master + +PACKAGES += erlvolt +pkg_erlvolt_name = erlvolt +pkg_erlvolt_description = VoltDB Erlang Client Driver +pkg_erlvolt_homepage = https://github.com/VoltDB/voltdb-client-erlang +pkg_erlvolt_fetch = git +pkg_erlvolt_repo = https://github.com/VoltDB/voltdb-client-erlang +pkg_erlvolt_commit = master + +PACKAGES += erlware_commons +pkg_erlware_commons_name = erlware_commons +pkg_erlware_commons_description = Erlware Commons is an Erlware project focused on all aspects of reusable Erlang components. +pkg_erlware_commons_homepage = https://github.com/erlware/erlware_commons +pkg_erlware_commons_fetch = git +pkg_erlware_commons_repo = https://github.com/erlware/erlware_commons +pkg_erlware_commons_commit = master + +PACKAGES += erlydtl +pkg_erlydtl_name = erlydtl +pkg_erlydtl_description = Django Template Language for Erlang. +pkg_erlydtl_homepage = https://github.com/erlydtl/erlydtl +pkg_erlydtl_fetch = git +pkg_erlydtl_repo = https://github.com/erlydtl/erlydtl +pkg_erlydtl_commit = master + +PACKAGES += errd +pkg_errd_name = errd +pkg_errd_description = Erlang RRDTool library +pkg_errd_homepage = https://github.com/archaelus/errd +pkg_errd_fetch = git +pkg_errd_repo = https://github.com/archaelus/errd +pkg_errd_commit = master + +PACKAGES += erserve +pkg_erserve_name = erserve +pkg_erserve_description = Erlang/Rserve communication interface +pkg_erserve_homepage = https://github.com/del/erserve +pkg_erserve_fetch = git +pkg_erserve_repo = https://github.com/del/erserve +pkg_erserve_commit = master + +PACKAGES += erwa +pkg_erwa_name = erwa +pkg_erwa_description = A WAMP router and client written in Erlang. +pkg_erwa_homepage = https://github.com/bwegh/erwa +pkg_erwa_fetch = git +pkg_erwa_repo = https://github.com/bwegh/erwa +pkg_erwa_commit = master + +PACKAGES += escalus +pkg_escalus_name = escalus +pkg_escalus_description = An XMPP client library in Erlang for conveniently testing XMPP servers +pkg_escalus_homepage = https://github.com/esl/escalus +pkg_escalus_fetch = git +pkg_escalus_repo = https://github.com/esl/escalus +pkg_escalus_commit = master + +PACKAGES += esh_mk +pkg_esh_mk_name = esh_mk +pkg_esh_mk_description = esh template engine plugin for erlang.mk +pkg_esh_mk_homepage = https://github.com/crownedgrouse/esh.mk +pkg_esh_mk_fetch = git +pkg_esh_mk_repo = https://github.com/crownedgrouse/esh.mk.git +pkg_esh_mk_commit = master + +PACKAGES += espec +pkg_espec_name = espec +pkg_espec_description = ESpec: Behaviour driven development framework for Erlang +pkg_espec_homepage = https://github.com/lucaspiller/espec +pkg_espec_fetch = git +pkg_espec_repo = https://github.com/lucaspiller/espec +pkg_espec_commit = master + +PACKAGES += estatsd +pkg_estatsd_name = estatsd +pkg_estatsd_description = Erlang stats aggregation app that periodically flushes data to graphite +pkg_estatsd_homepage = https://github.com/RJ/estatsd +pkg_estatsd_fetch = git +pkg_estatsd_repo = https://github.com/RJ/estatsd +pkg_estatsd_commit = master + +PACKAGES += etap +pkg_etap_name = etap +pkg_etap_description = etap is a simple erlang testing library that provides TAP compliant output. +pkg_etap_homepage = https://github.com/ngerakines/etap +pkg_etap_fetch = git +pkg_etap_repo = https://github.com/ngerakines/etap +pkg_etap_commit = master + +PACKAGES += etest +pkg_etest_name = etest +pkg_etest_description = A lightweight, convention over configuration test framework for Erlang +pkg_etest_homepage = https://github.com/wooga/etest +pkg_etest_fetch = git +pkg_etest_repo = https://github.com/wooga/etest +pkg_etest_commit = master + +PACKAGES += etest_http +pkg_etest_http_name = etest_http +pkg_etest_http_description = etest Assertions around HTTP (client-side) +pkg_etest_http_homepage = https://github.com/wooga/etest_http +pkg_etest_http_fetch = git +pkg_etest_http_repo = https://github.com/wooga/etest_http +pkg_etest_http_commit = master + +PACKAGES += etoml +pkg_etoml_name = etoml +pkg_etoml_description = TOML language erlang parser +pkg_etoml_homepage = https://github.com/kalta/etoml +pkg_etoml_fetch = git +pkg_etoml_repo = https://github.com/kalta/etoml +pkg_etoml_commit = master + +PACKAGES += eunit +pkg_eunit_name = eunit +pkg_eunit_description = The EUnit lightweight unit testing framework for Erlang - this is the canonical development repository. +pkg_eunit_homepage = https://github.com/richcarl/eunit +pkg_eunit_fetch = git +pkg_eunit_repo = https://github.com/richcarl/eunit +pkg_eunit_commit = master + +PACKAGES += eunit_formatters +pkg_eunit_formatters_name = eunit_formatters +pkg_eunit_formatters_description = Because eunit's output sucks. Let's make it better. +pkg_eunit_formatters_homepage = https://github.com/seancribbs/eunit_formatters +pkg_eunit_formatters_fetch = git +pkg_eunit_formatters_repo = https://github.com/seancribbs/eunit_formatters +pkg_eunit_formatters_commit = master + +PACKAGES += euthanasia +pkg_euthanasia_name = euthanasia +pkg_euthanasia_description = Merciful killer for your Erlang processes +pkg_euthanasia_homepage = https://github.com/doubleyou/euthanasia +pkg_euthanasia_fetch = git +pkg_euthanasia_repo = https://github.com/doubleyou/euthanasia +pkg_euthanasia_commit = master + +PACKAGES += evum +pkg_evum_name = evum +pkg_evum_description = Spawn Linux VMs as Erlang processes in the Erlang VM +pkg_evum_homepage = https://github.com/msantos/evum +pkg_evum_fetch = git +pkg_evum_repo = https://github.com/msantos/evum +pkg_evum_commit = master + +PACKAGES += exec +pkg_exec_name = erlexec +pkg_exec_description = Execute and control OS processes from Erlang/OTP. +pkg_exec_homepage = http://saleyn.github.com/erlexec +pkg_exec_fetch = git +pkg_exec_repo = https://github.com/saleyn/erlexec +pkg_exec_commit = master + +PACKAGES += exml +pkg_exml_name = exml +pkg_exml_description = XML parsing library in Erlang +pkg_exml_homepage = https://github.com/paulgray/exml +pkg_exml_fetch = git +pkg_exml_repo = https://github.com/paulgray/exml +pkg_exml_commit = master + +PACKAGES += exometer +pkg_exometer_name = exometer +pkg_exometer_description = Basic measurement objects and probe behavior +pkg_exometer_homepage = https://github.com/Feuerlabs/exometer +pkg_exometer_fetch = git +pkg_exometer_repo = https://github.com/Feuerlabs/exometer +pkg_exometer_commit = master + +PACKAGES += exs1024 +pkg_exs1024_name = exs1024 +pkg_exs1024_description = Xorshift1024star pseudo random number generator for Erlang. +pkg_exs1024_homepage = https://github.com/jj1bdx/exs1024 +pkg_exs1024_fetch = git +pkg_exs1024_repo = https://github.com/jj1bdx/exs1024 +pkg_exs1024_commit = master + +PACKAGES += exs64 +pkg_exs64_name = exs64 +pkg_exs64_description = Xorshift64star pseudo random number generator for Erlang. +pkg_exs64_homepage = https://github.com/jj1bdx/exs64 +pkg_exs64_fetch = git +pkg_exs64_repo = https://github.com/jj1bdx/exs64 +pkg_exs64_commit = master + +PACKAGES += exsplus116 +pkg_exsplus116_name = exsplus116 +pkg_exsplus116_description = Xorshift116plus for Erlang +pkg_exsplus116_homepage = https://github.com/jj1bdx/exsplus116 +pkg_exsplus116_fetch = git +pkg_exsplus116_repo = https://github.com/jj1bdx/exsplus116 +pkg_exsplus116_commit = master + +PACKAGES += exsplus128 +pkg_exsplus128_name = exsplus128 +pkg_exsplus128_description = Xorshift128plus pseudo random number generator for Erlang. +pkg_exsplus128_homepage = https://github.com/jj1bdx/exsplus128 +pkg_exsplus128_fetch = git +pkg_exsplus128_repo = https://github.com/jj1bdx/exsplus128 +pkg_exsplus128_commit = master + +PACKAGES += ezmq +pkg_ezmq_name = ezmq +pkg_ezmq_description = zMQ implemented in Erlang +pkg_ezmq_homepage = https://github.com/RoadRunnr/ezmq +pkg_ezmq_fetch = git +pkg_ezmq_repo = https://github.com/RoadRunnr/ezmq +pkg_ezmq_commit = master + +PACKAGES += ezmtp +pkg_ezmtp_name = ezmtp +pkg_ezmtp_description = ZMTP protocol in pure Erlang. +pkg_ezmtp_homepage = https://github.com/a13x/ezmtp +pkg_ezmtp_fetch = git +pkg_ezmtp_repo = https://github.com/a13x/ezmtp +pkg_ezmtp_commit = master + +PACKAGES += fast_disk_log +pkg_fast_disk_log_name = fast_disk_log +pkg_fast_disk_log_description = Pool-based asynchronous Erlang disk logger +pkg_fast_disk_log_homepage = https://github.com/lpgauth/fast_disk_log +pkg_fast_disk_log_fetch = git +pkg_fast_disk_log_repo = https://github.com/lpgauth/fast_disk_log +pkg_fast_disk_log_commit = master + +PACKAGES += feeder +pkg_feeder_name = feeder +pkg_feeder_description = Stream parse RSS and Atom formatted XML feeds. +pkg_feeder_homepage = https://github.com/michaelnisi/feeder +pkg_feeder_fetch = git +pkg_feeder_repo = https://github.com/michaelnisi/feeder +pkg_feeder_commit = master + +PACKAGES += find_crate +pkg_find_crate_name = find_crate +pkg_find_crate_description = Find Rust libs and exes in Erlang application priv directory +pkg_find_crate_homepage = https://github.com/goertzenator/find_crate +pkg_find_crate_fetch = git +pkg_find_crate_repo = https://github.com/goertzenator/find_crate +pkg_find_crate_commit = master + +PACKAGES += fix +pkg_fix_name = fix +pkg_fix_description = http://fixprotocol.org/ implementation. +pkg_fix_homepage = https://github.com/maxlapshin/fix +pkg_fix_fetch = git +pkg_fix_repo = https://github.com/maxlapshin/fix +pkg_fix_commit = master + +PACKAGES += flower +pkg_flower_name = flower +pkg_flower_description = FlowER - a Erlang OpenFlow development platform +pkg_flower_homepage = https://github.com/travelping/flower +pkg_flower_fetch = git +pkg_flower_repo = https://github.com/travelping/flower +pkg_flower_commit = master + +PACKAGES += fn +pkg_fn_name = fn +pkg_fn_description = Function utilities for Erlang +pkg_fn_homepage = https://github.com/reiddraper/fn +pkg_fn_fetch = git +pkg_fn_repo = https://github.com/reiddraper/fn +pkg_fn_commit = master + +PACKAGES += folsom +pkg_folsom_name = folsom +pkg_folsom_description = Expose Erlang Events and Metrics +pkg_folsom_homepage = https://github.com/boundary/folsom +pkg_folsom_fetch = git +pkg_folsom_repo = https://github.com/boundary/folsom +pkg_folsom_commit = master + +PACKAGES += folsom_cowboy +pkg_folsom_cowboy_name = folsom_cowboy +pkg_folsom_cowboy_description = A Cowboy based Folsom HTTP Wrapper. +pkg_folsom_cowboy_homepage = https://github.com/boundary/folsom_cowboy +pkg_folsom_cowboy_fetch = git +pkg_folsom_cowboy_repo = https://github.com/boundary/folsom_cowboy +pkg_folsom_cowboy_commit = master + +PACKAGES += folsomite +pkg_folsomite_name = folsomite +pkg_folsomite_description = blow up your graphite / riemann server with folsom metrics +pkg_folsomite_homepage = https://github.com/campanja/folsomite +pkg_folsomite_fetch = git +pkg_folsomite_repo = https://github.com/campanja/folsomite +pkg_folsomite_commit = master + +PACKAGES += fs +pkg_fs_name = fs +pkg_fs_description = Erlang FileSystem Listener +pkg_fs_homepage = https://github.com/synrc/fs +pkg_fs_fetch = git +pkg_fs_repo = https://github.com/synrc/fs +pkg_fs_commit = master + +PACKAGES += fuse +pkg_fuse_name = fuse +pkg_fuse_description = A Circuit Breaker for Erlang +pkg_fuse_homepage = https://github.com/jlouis/fuse +pkg_fuse_fetch = git +pkg_fuse_repo = https://github.com/jlouis/fuse +pkg_fuse_commit = master + +PACKAGES += gcm +pkg_gcm_name = gcm +pkg_gcm_description = An Erlang application for Google Cloud Messaging +pkg_gcm_homepage = https://github.com/pdincau/gcm-erlang +pkg_gcm_fetch = git +pkg_gcm_repo = https://github.com/pdincau/gcm-erlang +pkg_gcm_commit = master + +PACKAGES += gcprof +pkg_gcprof_name = gcprof +pkg_gcprof_description = Garbage Collection profiler for Erlang +pkg_gcprof_homepage = https://github.com/knutin/gcprof +pkg_gcprof_fetch = git +pkg_gcprof_repo = https://github.com/knutin/gcprof +pkg_gcprof_commit = master + +PACKAGES += geas +pkg_geas_name = geas +pkg_geas_description = Guess Erlang Application Scattering +pkg_geas_homepage = https://github.com/crownedgrouse/geas +pkg_geas_fetch = git +pkg_geas_repo = https://github.com/crownedgrouse/geas +pkg_geas_commit = master + +PACKAGES += geef +pkg_geef_name = geef +pkg_geef_description = Git NEEEEF (Erlang NIF) +pkg_geef_homepage = https://github.com/carlosmn/geef +pkg_geef_fetch = git +pkg_geef_repo = https://github.com/carlosmn/geef +pkg_geef_commit = master + +PACKAGES += gen_coap +pkg_gen_coap_name = gen_coap +pkg_gen_coap_description = Generic Erlang CoAP Client/Server +pkg_gen_coap_homepage = https://github.com/gotthardp/gen_coap +pkg_gen_coap_fetch = git +pkg_gen_coap_repo = https://github.com/gotthardp/gen_coap +pkg_gen_coap_commit = master + +PACKAGES += gen_cycle +pkg_gen_cycle_name = gen_cycle +pkg_gen_cycle_description = Simple, generic OTP behaviour for recurring tasks +pkg_gen_cycle_homepage = https://github.com/aerosol/gen_cycle +pkg_gen_cycle_fetch = git +pkg_gen_cycle_repo = https://github.com/aerosol/gen_cycle +pkg_gen_cycle_commit = develop + +PACKAGES += gen_icmp +pkg_gen_icmp_name = gen_icmp +pkg_gen_icmp_description = Erlang interface to ICMP sockets +pkg_gen_icmp_homepage = https://github.com/msantos/gen_icmp +pkg_gen_icmp_fetch = git +pkg_gen_icmp_repo = https://github.com/msantos/gen_icmp +pkg_gen_icmp_commit = master + +PACKAGES += gen_leader +pkg_gen_leader_name = gen_leader +pkg_gen_leader_description = leader election behavior +pkg_gen_leader_homepage = https://github.com/garret-smith/gen_leader_revival +pkg_gen_leader_fetch = git +pkg_gen_leader_repo = https://github.com/garret-smith/gen_leader_revival +pkg_gen_leader_commit = master + +PACKAGES += gen_nb_server +pkg_gen_nb_server_name = gen_nb_server +pkg_gen_nb_server_description = OTP behavior for writing non-blocking servers +pkg_gen_nb_server_homepage = https://github.com/kevsmith/gen_nb_server +pkg_gen_nb_server_fetch = git +pkg_gen_nb_server_repo = https://github.com/kevsmith/gen_nb_server +pkg_gen_nb_server_commit = master + +PACKAGES += gen_paxos +pkg_gen_paxos_name = gen_paxos +pkg_gen_paxos_description = An Erlang/OTP-style implementation of the PAXOS distributed consensus protocol +pkg_gen_paxos_homepage = https://github.com/gburd/gen_paxos +pkg_gen_paxos_fetch = git +pkg_gen_paxos_repo = https://github.com/gburd/gen_paxos +pkg_gen_paxos_commit = master + +PACKAGES += gen_rpc +pkg_gen_rpc_name = gen_rpc +pkg_gen_rpc_description = A scalable RPC library for Erlang-VM based languages +pkg_gen_rpc_homepage = https://github.com/priestjim/gen_rpc.git +pkg_gen_rpc_fetch = git +pkg_gen_rpc_repo = https://github.com/priestjim/gen_rpc.git +pkg_gen_rpc_commit = master + +PACKAGES += gen_smtp +pkg_gen_smtp_name = gen_smtp +pkg_gen_smtp_description = A generic Erlang SMTP server and client that can be extended via callback modules +pkg_gen_smtp_homepage = https://github.com/Vagabond/gen_smtp +pkg_gen_smtp_fetch = git +pkg_gen_smtp_repo = https://github.com/Vagabond/gen_smtp +pkg_gen_smtp_commit = master + +PACKAGES += gen_tracker +pkg_gen_tracker_name = gen_tracker +pkg_gen_tracker_description = supervisor with ets handling of children and their metadata +pkg_gen_tracker_homepage = https://github.com/erlyvideo/gen_tracker +pkg_gen_tracker_fetch = git +pkg_gen_tracker_repo = https://github.com/erlyvideo/gen_tracker +pkg_gen_tracker_commit = master + +PACKAGES += gen_unix +pkg_gen_unix_name = gen_unix +pkg_gen_unix_description = Erlang Unix socket interface +pkg_gen_unix_homepage = https://github.com/msantos/gen_unix +pkg_gen_unix_fetch = git +pkg_gen_unix_repo = https://github.com/msantos/gen_unix +pkg_gen_unix_commit = master + +PACKAGES += geode +pkg_geode_name = geode +pkg_geode_description = geohash/proximity lookup in pure, uncut erlang. +pkg_geode_homepage = https://github.com/bradfordw/geode +pkg_geode_fetch = git +pkg_geode_repo = https://github.com/bradfordw/geode +pkg_geode_commit = master + +PACKAGES += getopt +pkg_getopt_name = getopt +pkg_getopt_description = Module to parse command line arguments using the GNU getopt syntax +pkg_getopt_homepage = https://github.com/jcomellas/getopt +pkg_getopt_fetch = git +pkg_getopt_repo = https://github.com/jcomellas/getopt +pkg_getopt_commit = master + +PACKAGES += gettext +pkg_gettext_name = gettext +pkg_gettext_description = Erlang internationalization library. +pkg_gettext_homepage = https://github.com/etnt/gettext +pkg_gettext_fetch = git +pkg_gettext_repo = https://github.com/etnt/gettext +pkg_gettext_commit = master + +PACKAGES += giallo +pkg_giallo_name = giallo +pkg_giallo_description = Small and flexible web framework on top of Cowboy +pkg_giallo_homepage = https://github.com/kivra/giallo +pkg_giallo_fetch = git +pkg_giallo_repo = https://github.com/kivra/giallo +pkg_giallo_commit = master + +PACKAGES += gin +pkg_gin_name = gin +pkg_gin_description = The guards and for Erlang parse_transform +pkg_gin_homepage = https://github.com/mad-cocktail/gin +pkg_gin_fetch = git +pkg_gin_repo = https://github.com/mad-cocktail/gin +pkg_gin_commit = master + +PACKAGES += gitty +pkg_gitty_name = gitty +pkg_gitty_description = Git access in erlang +pkg_gitty_homepage = https://github.com/maxlapshin/gitty +pkg_gitty_fetch = git +pkg_gitty_repo = https://github.com/maxlapshin/gitty +pkg_gitty_commit = master + +PACKAGES += gold_fever +pkg_gold_fever_name = gold_fever +pkg_gold_fever_description = A Treasure Hunt for Erlangers +pkg_gold_fever_homepage = https://github.com/inaka/gold_fever +pkg_gold_fever_fetch = git +pkg_gold_fever_repo = https://github.com/inaka/gold_fever +pkg_gold_fever_commit = master + +PACKAGES += gpb +pkg_gpb_name = gpb +pkg_gpb_description = A Google Protobuf implementation for Erlang +pkg_gpb_homepage = https://github.com/tomas-abrahamsson/gpb +pkg_gpb_fetch = git +pkg_gpb_repo = https://github.com/tomas-abrahamsson/gpb +pkg_gpb_commit = master + +PACKAGES += gproc +pkg_gproc_name = gproc +pkg_gproc_description = Extended process registry for Erlang +pkg_gproc_homepage = https://github.com/uwiger/gproc +pkg_gproc_fetch = git +pkg_gproc_repo = https://github.com/uwiger/gproc +pkg_gproc_commit = master + +PACKAGES += grapherl +pkg_grapherl_name = grapherl +pkg_grapherl_description = Create graphs of Erlang systems and programs +pkg_grapherl_homepage = https://github.com/eproxus/grapherl +pkg_grapherl_fetch = git +pkg_grapherl_repo = https://github.com/eproxus/grapherl +pkg_grapherl_commit = master + +PACKAGES += grpc +pkg_grpc_name = grpc +pkg_grpc_description = gRPC server in Erlang +pkg_grpc_homepage = https://github.com/Bluehouse-Technology/grpc +pkg_grpc_fetch = git +pkg_grpc_repo = https://github.com/Bluehouse-Technology/grpc +pkg_grpc_commit = master + +PACKAGES += grpc_client +pkg_grpc_client_name = grpc_client +pkg_grpc_client_description = gRPC client in Erlang +pkg_grpc_client_homepage = https://github.com/Bluehouse-Technology/grpc_client +pkg_grpc_client_fetch = git +pkg_grpc_client_repo = https://github.com/Bluehouse-Technology/grpc_client +pkg_grpc_client_commit = master + +PACKAGES += gun +pkg_gun_name = gun +pkg_gun_description = Asynchronous SPDY, HTTP and Websocket client written in Erlang. +pkg_gun_homepage = http//ninenines.eu +pkg_gun_fetch = git +pkg_gun_repo = https://github.com/ninenines/gun +pkg_gun_commit = master + +PACKAGES += gut +pkg_gut_name = gut +pkg_gut_description = gut is a template printing, aka scaffolding, tool for Erlang. Like rails generate or yeoman +pkg_gut_homepage = https://github.com/unbalancedparentheses/gut +pkg_gut_fetch = git +pkg_gut_repo = https://github.com/unbalancedparentheses/gut +pkg_gut_commit = master + +PACKAGES += hackney +pkg_hackney_name = hackney +pkg_hackney_description = simple HTTP client in Erlang +pkg_hackney_homepage = https://github.com/benoitc/hackney +pkg_hackney_fetch = git +pkg_hackney_repo = https://github.com/benoitc/hackney +pkg_hackney_commit = master + +PACKAGES += hamcrest +pkg_hamcrest_name = hamcrest +pkg_hamcrest_description = Erlang port of Hamcrest +pkg_hamcrest_homepage = https://github.com/hyperthunk/hamcrest-erlang +pkg_hamcrest_fetch = git +pkg_hamcrest_repo = https://github.com/hyperthunk/hamcrest-erlang +pkg_hamcrest_commit = master + +PACKAGES += hanoidb +pkg_hanoidb_name = hanoidb +pkg_hanoidb_description = Erlang LSM BTree Storage +pkg_hanoidb_homepage = https://github.com/krestenkrab/hanoidb +pkg_hanoidb_fetch = git +pkg_hanoidb_repo = https://github.com/krestenkrab/hanoidb +pkg_hanoidb_commit = master + +PACKAGES += hottub +pkg_hottub_name = hottub +pkg_hottub_description = Permanent Erlang Worker Pool +pkg_hottub_homepage = https://github.com/bfrog/hottub +pkg_hottub_fetch = git +pkg_hottub_repo = https://github.com/bfrog/hottub +pkg_hottub_commit = master + +PACKAGES += hpack +pkg_hpack_name = hpack +pkg_hpack_description = HPACK Implementation for Erlang +pkg_hpack_homepage = https://github.com/joedevivo/hpack +pkg_hpack_fetch = git +pkg_hpack_repo = https://github.com/joedevivo/hpack +pkg_hpack_commit = master + +PACKAGES += hyper +pkg_hyper_name = hyper +pkg_hyper_description = Erlang implementation of HyperLogLog +pkg_hyper_homepage = https://github.com/GameAnalytics/hyper +pkg_hyper_fetch = git +pkg_hyper_repo = https://github.com/GameAnalytics/hyper +pkg_hyper_commit = master + +PACKAGES += i18n +pkg_i18n_name = i18n +pkg_i18n_description = International components for unicode from Erlang (unicode, date, string, number, format, locale, localization, transliteration, icu4e) +pkg_i18n_homepage = https://github.com/erlang-unicode/i18n +pkg_i18n_fetch = git +pkg_i18n_repo = https://github.com/erlang-unicode/i18n +pkg_i18n_commit = master + +PACKAGES += ibrowse +pkg_ibrowse_name = ibrowse +pkg_ibrowse_description = Erlang HTTP client +pkg_ibrowse_homepage = https://github.com/cmullaparthi/ibrowse +pkg_ibrowse_fetch = git +pkg_ibrowse_repo = https://github.com/cmullaparthi/ibrowse +pkg_ibrowse_commit = master + +PACKAGES += idna +pkg_idna_name = idna +pkg_idna_description = Erlang IDNA lib +pkg_idna_homepage = https://github.com/benoitc/erlang-idna +pkg_idna_fetch = git +pkg_idna_repo = https://github.com/benoitc/erlang-idna +pkg_idna_commit = master + +PACKAGES += ierlang +pkg_ierlang_name = ierlang +pkg_ierlang_description = An Erlang language kernel for IPython. +pkg_ierlang_homepage = https://github.com/robbielynch/ierlang +pkg_ierlang_fetch = git +pkg_ierlang_repo = https://github.com/robbielynch/ierlang +pkg_ierlang_commit = master + +PACKAGES += iota +pkg_iota_name = iota +pkg_iota_description = iota (Inter-dependency Objective Testing Apparatus) - a tool to enforce clean separation of responsibilities in Erlang code +pkg_iota_homepage = https://github.com/jpgneves/iota +pkg_iota_fetch = git +pkg_iota_repo = https://github.com/jpgneves/iota +pkg_iota_commit = master + +PACKAGES += irc_lib +pkg_irc_lib_name = irc_lib +pkg_irc_lib_description = Erlang irc client library +pkg_irc_lib_homepage = https://github.com/OtpChatBot/irc_lib +pkg_irc_lib_fetch = git +pkg_irc_lib_repo = https://github.com/OtpChatBot/irc_lib +pkg_irc_lib_commit = master + +PACKAGES += ircd +pkg_ircd_name = ircd +pkg_ircd_description = A pluggable IRC daemon application/library for Erlang. +pkg_ircd_homepage = https://github.com/tonyg/erlang-ircd +pkg_ircd_fetch = git +pkg_ircd_repo = https://github.com/tonyg/erlang-ircd +pkg_ircd_commit = master + +PACKAGES += iris +pkg_iris_name = iris +pkg_iris_description = Iris Erlang binding +pkg_iris_homepage = https://github.com/project-iris/iris-erl +pkg_iris_fetch = git +pkg_iris_repo = https://github.com/project-iris/iris-erl +pkg_iris_commit = master + +PACKAGES += iso8601 +pkg_iso8601_name = iso8601 +pkg_iso8601_description = Erlang ISO 8601 date formatter/parser +pkg_iso8601_homepage = https://github.com/seansawyer/erlang_iso8601 +pkg_iso8601_fetch = git +pkg_iso8601_repo = https://github.com/seansawyer/erlang_iso8601 +pkg_iso8601_commit = master + +PACKAGES += jamdb_sybase +pkg_jamdb_sybase_name = jamdb_sybase +pkg_jamdb_sybase_description = Erlang driver for SAP Sybase ASE +pkg_jamdb_sybase_homepage = https://github.com/erlangbureau/jamdb_sybase +pkg_jamdb_sybase_fetch = git +pkg_jamdb_sybase_repo = https://github.com/erlangbureau/jamdb_sybase +pkg_jamdb_sybase_commit = master + +PACKAGES += jerg +pkg_jerg_name = jerg +pkg_jerg_description = JSON Schema to Erlang Records Generator +pkg_jerg_homepage = https://github.com/ddossot/jerg +pkg_jerg_fetch = git +pkg_jerg_repo = https://github.com/ddossot/jerg +pkg_jerg_commit = master + +PACKAGES += jesse +pkg_jesse_name = jesse +pkg_jesse_description = jesse (JSon Schema Erlang) is an implementation of a json schema validator for Erlang. +pkg_jesse_homepage = https://github.com/for-GET/jesse +pkg_jesse_fetch = git +pkg_jesse_repo = https://github.com/for-GET/jesse +pkg_jesse_commit = master + +PACKAGES += jiffy +pkg_jiffy_name = jiffy +pkg_jiffy_description = JSON NIFs for Erlang. +pkg_jiffy_homepage = https://github.com/davisp/jiffy +pkg_jiffy_fetch = git +pkg_jiffy_repo = https://github.com/davisp/jiffy +pkg_jiffy_commit = master + +PACKAGES += jiffy_v +pkg_jiffy_v_name = jiffy_v +pkg_jiffy_v_description = JSON validation utility +pkg_jiffy_v_homepage = https://github.com/shizzard/jiffy-v +pkg_jiffy_v_fetch = git +pkg_jiffy_v_repo = https://github.com/shizzard/jiffy-v +pkg_jiffy_v_commit = master + +PACKAGES += jobs +pkg_jobs_name = jobs +pkg_jobs_description = a Job scheduler for load regulation +pkg_jobs_homepage = https://github.com/esl/jobs +pkg_jobs_fetch = git +pkg_jobs_repo = https://github.com/esl/jobs +pkg_jobs_commit = master + +PACKAGES += joxa +pkg_joxa_name = joxa +pkg_joxa_description = A Modern Lisp for the Erlang VM +pkg_joxa_homepage = https://github.com/joxa/joxa +pkg_joxa_fetch = git +pkg_joxa_repo = https://github.com/joxa/joxa +pkg_joxa_commit = master + +PACKAGES += json +pkg_json_name = json +pkg_json_description = a high level json library for erlang (17.0+) +pkg_json_homepage = https://github.com/talentdeficit/json +pkg_json_fetch = git +pkg_json_repo = https://github.com/talentdeficit/json +pkg_json_commit = master + +PACKAGES += json_rec +pkg_json_rec_name = json_rec +pkg_json_rec_description = JSON to erlang record +pkg_json_rec_homepage = https://github.com/justinkirby/json_rec +pkg_json_rec_fetch = git +pkg_json_rec_repo = https://github.com/justinkirby/json_rec +pkg_json_rec_commit = master + +PACKAGES += jsone +pkg_jsone_name = jsone +pkg_jsone_description = An Erlang library for encoding, decoding JSON data. +pkg_jsone_homepage = https://github.com/sile/jsone.git +pkg_jsone_fetch = git +pkg_jsone_repo = https://github.com/sile/jsone.git +pkg_jsone_commit = master + +PACKAGES += jsonerl +pkg_jsonerl_name = jsonerl +pkg_jsonerl_description = yet another but slightly different erlang <-> json encoder/decoder +pkg_jsonerl_homepage = https://github.com/lambder/jsonerl +pkg_jsonerl_fetch = git +pkg_jsonerl_repo = https://github.com/lambder/jsonerl +pkg_jsonerl_commit = master + +PACKAGES += jsonpath +pkg_jsonpath_name = jsonpath +pkg_jsonpath_description = Fast Erlang JSON data retrieval and updates via javascript-like notation +pkg_jsonpath_homepage = https://github.com/GeneStevens/jsonpath +pkg_jsonpath_fetch = git +pkg_jsonpath_repo = https://github.com/GeneStevens/jsonpath +pkg_jsonpath_commit = master + +PACKAGES += jsonx +pkg_jsonx_name = jsonx +pkg_jsonx_description = JSONX is an Erlang library for efficient decode and encode JSON, written in C. +pkg_jsonx_homepage = https://github.com/iskra/jsonx +pkg_jsonx_fetch = git +pkg_jsonx_repo = https://github.com/iskra/jsonx +pkg_jsonx_commit = master + +PACKAGES += jsx +pkg_jsx_name = jsx +pkg_jsx_description = An Erlang application for consuming, producing and manipulating JSON. +pkg_jsx_homepage = https://github.com/talentdeficit/jsx +pkg_jsx_fetch = git +pkg_jsx_repo = https://github.com/talentdeficit/jsx +pkg_jsx_commit = master + +PACKAGES += kafka +pkg_kafka_name = kafka +pkg_kafka_description = Kafka consumer and producer in Erlang +pkg_kafka_homepage = https://github.com/wooga/kafka-erlang +pkg_kafka_fetch = git +pkg_kafka_repo = https://github.com/wooga/kafka-erlang +pkg_kafka_commit = master + +PACKAGES += kafka_protocol +pkg_kafka_protocol_name = kafka_protocol +pkg_kafka_protocol_description = Kafka protocol Erlang library +pkg_kafka_protocol_homepage = https://github.com/klarna/kafka_protocol +pkg_kafka_protocol_fetch = git +pkg_kafka_protocol_repo = https://github.com/klarna/kafka_protocol.git +pkg_kafka_protocol_commit = master + +PACKAGES += kai +pkg_kai_name = kai +pkg_kai_description = DHT storage by Takeshi Inoue +pkg_kai_homepage = https://github.com/synrc/kai +pkg_kai_fetch = git +pkg_kai_repo = https://github.com/synrc/kai +pkg_kai_commit = master + +PACKAGES += katja +pkg_katja_name = katja +pkg_katja_description = A simple Riemann client written in Erlang. +pkg_katja_homepage = https://github.com/nifoc/katja +pkg_katja_fetch = git +pkg_katja_repo = https://github.com/nifoc/katja +pkg_katja_commit = master + +PACKAGES += kdht +pkg_kdht_name = kdht +pkg_kdht_description = kdht is an erlang DHT implementation +pkg_kdht_homepage = https://github.com/kevinlynx/kdht +pkg_kdht_fetch = git +pkg_kdht_repo = https://github.com/kevinlynx/kdht +pkg_kdht_commit = master + +PACKAGES += key2value +pkg_key2value_name = key2value +pkg_key2value_description = Erlang 2-way map +pkg_key2value_homepage = https://github.com/okeuday/key2value +pkg_key2value_fetch = git +pkg_key2value_repo = https://github.com/okeuday/key2value +pkg_key2value_commit = master + +PACKAGES += keys1value +pkg_keys1value_name = keys1value +pkg_keys1value_description = Erlang set associative map for key lists +pkg_keys1value_homepage = https://github.com/okeuday/keys1value +pkg_keys1value_fetch = git +pkg_keys1value_repo = https://github.com/okeuday/keys1value +pkg_keys1value_commit = master + +PACKAGES += kinetic +pkg_kinetic_name = kinetic +pkg_kinetic_description = Erlang Kinesis Client +pkg_kinetic_homepage = https://github.com/AdRoll/kinetic +pkg_kinetic_fetch = git +pkg_kinetic_repo = https://github.com/AdRoll/kinetic +pkg_kinetic_commit = master + +PACKAGES += kjell +pkg_kjell_name = kjell +pkg_kjell_description = Erlang Shell +pkg_kjell_homepage = https://github.com/karlll/kjell +pkg_kjell_fetch = git +pkg_kjell_repo = https://github.com/karlll/kjell +pkg_kjell_commit = master + +PACKAGES += kraken +pkg_kraken_name = kraken +pkg_kraken_description = Distributed Pubsub Server for Realtime Apps +pkg_kraken_homepage = https://github.com/Asana/kraken +pkg_kraken_fetch = git +pkg_kraken_repo = https://github.com/Asana/kraken +pkg_kraken_commit = master + +PACKAGES += kucumberl +pkg_kucumberl_name = kucumberl +pkg_kucumberl_description = A pure-erlang, open-source, implementation of Cucumber +pkg_kucumberl_homepage = https://github.com/openshine/kucumberl +pkg_kucumberl_fetch = git +pkg_kucumberl_repo = https://github.com/openshine/kucumberl +pkg_kucumberl_commit = master + +PACKAGES += kvc +pkg_kvc_name = kvc +pkg_kvc_description = KVC - Key Value Coding for Erlang data structures +pkg_kvc_homepage = https://github.com/etrepum/kvc +pkg_kvc_fetch = git +pkg_kvc_repo = https://github.com/etrepum/kvc +pkg_kvc_commit = master + +PACKAGES += kvlists +pkg_kvlists_name = kvlists +pkg_kvlists_description = Lists of key-value pairs (decoded JSON) in Erlang +pkg_kvlists_homepage = https://github.com/jcomellas/kvlists +pkg_kvlists_fetch = git +pkg_kvlists_repo = https://github.com/jcomellas/kvlists +pkg_kvlists_commit = master + +PACKAGES += kvs +pkg_kvs_name = kvs +pkg_kvs_description = Container and Iterator +pkg_kvs_homepage = https://github.com/synrc/kvs +pkg_kvs_fetch = git +pkg_kvs_repo = https://github.com/synrc/kvs +pkg_kvs_commit = master + +PACKAGES += lager +pkg_lager_name = lager +pkg_lager_description = A logging framework for Erlang/OTP. +pkg_lager_homepage = https://github.com/erlang-lager/lager +pkg_lager_fetch = git +pkg_lager_repo = https://github.com/erlang-lager/lager +pkg_lager_commit = master + +PACKAGES += lager_amqp_backend +pkg_lager_amqp_backend_name = lager_amqp_backend +pkg_lager_amqp_backend_description = AMQP RabbitMQ Lager backend +pkg_lager_amqp_backend_homepage = https://github.com/jbrisbin/lager_amqp_backend +pkg_lager_amqp_backend_fetch = git +pkg_lager_amqp_backend_repo = https://github.com/jbrisbin/lager_amqp_backend +pkg_lager_amqp_backend_commit = master + +PACKAGES += lager_syslog +pkg_lager_syslog_name = lager_syslog +pkg_lager_syslog_description = Syslog backend for lager +pkg_lager_syslog_homepage = https://github.com/erlang-lager/lager_syslog +pkg_lager_syslog_fetch = git +pkg_lager_syslog_repo = https://github.com/erlang-lager/lager_syslog +pkg_lager_syslog_commit = master + +PACKAGES += lambdapad +pkg_lambdapad_name = lambdapad +pkg_lambdapad_description = Static site generator using Erlang. Yes, Erlang. +pkg_lambdapad_homepage = https://github.com/gar1t/lambdapad +pkg_lambdapad_fetch = git +pkg_lambdapad_repo = https://github.com/gar1t/lambdapad +pkg_lambdapad_commit = master + +PACKAGES += lasp +pkg_lasp_name = lasp +pkg_lasp_description = A Language for Distributed, Eventually Consistent Computations +pkg_lasp_homepage = http://lasp-lang.org/ +pkg_lasp_fetch = git +pkg_lasp_repo = https://github.com/lasp-lang/lasp +pkg_lasp_commit = master + +PACKAGES += lasse +pkg_lasse_name = lasse +pkg_lasse_description = SSE handler for Cowboy +pkg_lasse_homepage = https://github.com/inaka/lasse +pkg_lasse_fetch = git +pkg_lasse_repo = https://github.com/inaka/lasse +pkg_lasse_commit = master + +PACKAGES += ldap +pkg_ldap_name = ldap +pkg_ldap_description = LDAP server written in Erlang +pkg_ldap_homepage = https://github.com/spawnproc/ldap +pkg_ldap_fetch = git +pkg_ldap_repo = https://github.com/spawnproc/ldap +pkg_ldap_commit = master + +PACKAGES += lethink +pkg_lethink_name = lethink +pkg_lethink_description = erlang driver for rethinkdb +pkg_lethink_homepage = https://github.com/taybin/lethink +pkg_lethink_fetch = git +pkg_lethink_repo = https://github.com/taybin/lethink +pkg_lethink_commit = master + +PACKAGES += lfe +pkg_lfe_name = lfe +pkg_lfe_description = Lisp Flavoured Erlang (LFE) +pkg_lfe_homepage = https://github.com/rvirding/lfe +pkg_lfe_fetch = git +pkg_lfe_repo = https://github.com/rvirding/lfe +pkg_lfe_commit = master + +PACKAGES += ling +pkg_ling_name = ling +pkg_ling_description = Erlang on Xen +pkg_ling_homepage = https://github.com/cloudozer/ling +pkg_ling_fetch = git +pkg_ling_repo = https://github.com/cloudozer/ling +pkg_ling_commit = master + +PACKAGES += live +pkg_live_name = live +pkg_live_description = Automated module and configuration reloader. +pkg_live_homepage = http://ninenines.eu +pkg_live_fetch = git +pkg_live_repo = https://github.com/ninenines/live +pkg_live_commit = master + +PACKAGES += lmq +pkg_lmq_name = lmq +pkg_lmq_description = Lightweight Message Queue +pkg_lmq_homepage = https://github.com/iij/lmq +pkg_lmq_fetch = git +pkg_lmq_repo = https://github.com/iij/lmq +pkg_lmq_commit = master + +PACKAGES += locker +pkg_locker_name = locker +pkg_locker_description = Atomic distributed 'check and set' for short-lived keys +pkg_locker_homepage = https://github.com/wooga/locker +pkg_locker_fetch = git +pkg_locker_repo = https://github.com/wooga/locker +pkg_locker_commit = master + +PACKAGES += locks +pkg_locks_name = locks +pkg_locks_description = A scalable, deadlock-resolving resource locker +pkg_locks_homepage = https://github.com/uwiger/locks +pkg_locks_fetch = git +pkg_locks_repo = https://github.com/uwiger/locks +pkg_locks_commit = master + +PACKAGES += log4erl +pkg_log4erl_name = log4erl +pkg_log4erl_description = A logger for erlang in the spirit of Log4J. +pkg_log4erl_homepage = https://github.com/ahmednawras/log4erl +pkg_log4erl_fetch = git +pkg_log4erl_repo = https://github.com/ahmednawras/log4erl +pkg_log4erl_commit = master + +PACKAGES += lol +pkg_lol_name = lol +pkg_lol_description = Lisp on erLang, and programming is fun again +pkg_lol_homepage = https://github.com/b0oh/lol +pkg_lol_fetch = git +pkg_lol_repo = https://github.com/b0oh/lol +pkg_lol_commit = master + +PACKAGES += lucid +pkg_lucid_name = lucid +pkg_lucid_description = HTTP/2 server written in Erlang +pkg_lucid_homepage = https://github.com/tatsuhiro-t/lucid +pkg_lucid_fetch = git +pkg_lucid_repo = https://github.com/tatsuhiro-t/lucid +pkg_lucid_commit = master + +PACKAGES += luerl +pkg_luerl_name = luerl +pkg_luerl_description = Lua in Erlang +pkg_luerl_homepage = https://github.com/rvirding/luerl +pkg_luerl_fetch = git +pkg_luerl_repo = https://github.com/rvirding/luerl +pkg_luerl_commit = develop + +PACKAGES += luwak +pkg_luwak_name = luwak +pkg_luwak_description = Large-object storage interface for Riak +pkg_luwak_homepage = https://github.com/basho/luwak +pkg_luwak_fetch = git +pkg_luwak_repo = https://github.com/basho/luwak +pkg_luwak_commit = master + +PACKAGES += lux +pkg_lux_name = lux +pkg_lux_description = Lux (LUcid eXpect scripting) simplifies test automation and provides an Expect-style execution of commands +pkg_lux_homepage = https://github.com/hawk/lux +pkg_lux_fetch = git +pkg_lux_repo = https://github.com/hawk/lux +pkg_lux_commit = master + +PACKAGES += machi +pkg_machi_name = machi +pkg_machi_description = Machi file store +pkg_machi_homepage = https://github.com/basho/machi +pkg_machi_fetch = git +pkg_machi_repo = https://github.com/basho/machi +pkg_machi_commit = master + +PACKAGES += mad +pkg_mad_name = mad +pkg_mad_description = Small and Fast Rebar Replacement +pkg_mad_homepage = https://github.com/synrc/mad +pkg_mad_fetch = git +pkg_mad_repo = https://github.com/synrc/mad +pkg_mad_commit = master + +PACKAGES += marina +pkg_marina_name = marina +pkg_marina_description = Non-blocking Erlang Cassandra CQL3 client +pkg_marina_homepage = https://github.com/lpgauth/marina +pkg_marina_fetch = git +pkg_marina_repo = https://github.com/lpgauth/marina +pkg_marina_commit = master + +PACKAGES += mavg +pkg_mavg_name = mavg +pkg_mavg_description = Erlang :: Exponential moving average library +pkg_mavg_homepage = https://github.com/EchoTeam/mavg +pkg_mavg_fetch = git +pkg_mavg_repo = https://github.com/EchoTeam/mavg +pkg_mavg_commit = master + +PACKAGES += mc_erl +pkg_mc_erl_name = mc_erl +pkg_mc_erl_description = mc-erl is a server for Minecraft 1.4.7 written in Erlang. +pkg_mc_erl_homepage = https://github.com/clonejo/mc-erl +pkg_mc_erl_fetch = git +pkg_mc_erl_repo = https://github.com/clonejo/mc-erl +pkg_mc_erl_commit = master + +PACKAGES += mcd +pkg_mcd_name = mcd +pkg_mcd_description = Fast memcached protocol client in pure Erlang +pkg_mcd_homepage = https://github.com/EchoTeam/mcd +pkg_mcd_fetch = git +pkg_mcd_repo = https://github.com/EchoTeam/mcd +pkg_mcd_commit = master + +PACKAGES += mcerlang +pkg_mcerlang_name = mcerlang +pkg_mcerlang_description = The McErlang model checker for Erlang +pkg_mcerlang_homepage = https://github.com/fredlund/McErlang +pkg_mcerlang_fetch = git +pkg_mcerlang_repo = https://github.com/fredlund/McErlang +pkg_mcerlang_commit = master + +PACKAGES += meck +pkg_meck_name = meck +pkg_meck_description = A mocking library for Erlang +pkg_meck_homepage = https://github.com/eproxus/meck +pkg_meck_fetch = git +pkg_meck_repo = https://github.com/eproxus/meck +pkg_meck_commit = master + +PACKAGES += mekao +pkg_mekao_name = mekao +pkg_mekao_description = SQL constructor +pkg_mekao_homepage = https://github.com/ddosia/mekao +pkg_mekao_fetch = git +pkg_mekao_repo = https://github.com/ddosia/mekao +pkg_mekao_commit = master + +PACKAGES += memo +pkg_memo_name = memo +pkg_memo_description = Erlang memoization server +pkg_memo_homepage = https://github.com/tuncer/memo +pkg_memo_fetch = git +pkg_memo_repo = https://github.com/tuncer/memo +pkg_memo_commit = master + +PACKAGES += merge_index +pkg_merge_index_name = merge_index +pkg_merge_index_description = MergeIndex is an Erlang library for storing ordered sets on disk. It is very similar to an SSTable (in Google's Bigtable) or an HFile (in Hadoop). +pkg_merge_index_homepage = https://github.com/basho/merge_index +pkg_merge_index_fetch = git +pkg_merge_index_repo = https://github.com/basho/merge_index +pkg_merge_index_commit = master + +PACKAGES += merl +pkg_merl_name = merl +pkg_merl_description = Metaprogramming in Erlang +pkg_merl_homepage = https://github.com/richcarl/merl +pkg_merl_fetch = git +pkg_merl_repo = https://github.com/richcarl/merl +pkg_merl_commit = master + +PACKAGES += mimerl +pkg_mimerl_name = mimerl +pkg_mimerl_description = library to handle mimetypes +pkg_mimerl_homepage = https://github.com/benoitc/mimerl +pkg_mimerl_fetch = git +pkg_mimerl_repo = https://github.com/benoitc/mimerl +pkg_mimerl_commit = master + +PACKAGES += mimetypes +pkg_mimetypes_name = mimetypes +pkg_mimetypes_description = Erlang MIME types library +pkg_mimetypes_homepage = https://github.com/spawngrid/mimetypes +pkg_mimetypes_fetch = git +pkg_mimetypes_repo = https://github.com/spawngrid/mimetypes +pkg_mimetypes_commit = master + +PACKAGES += mixer +pkg_mixer_name = mixer +pkg_mixer_description = Mix in functions from other modules +pkg_mixer_homepage = https://github.com/chef/mixer +pkg_mixer_fetch = git +pkg_mixer_repo = https://github.com/chef/mixer +pkg_mixer_commit = master + +PACKAGES += mochiweb +pkg_mochiweb_name = mochiweb +pkg_mochiweb_description = MochiWeb is an Erlang library for building lightweight HTTP servers. +pkg_mochiweb_homepage = https://github.com/mochi/mochiweb +pkg_mochiweb_fetch = git +pkg_mochiweb_repo = https://github.com/mochi/mochiweb +pkg_mochiweb_commit = master + +PACKAGES += mochiweb_xpath +pkg_mochiweb_xpath_name = mochiweb_xpath +pkg_mochiweb_xpath_description = XPath support for mochiweb's html parser +pkg_mochiweb_xpath_homepage = https://github.com/retnuh/mochiweb_xpath +pkg_mochiweb_xpath_fetch = git +pkg_mochiweb_xpath_repo = https://github.com/retnuh/mochiweb_xpath +pkg_mochiweb_xpath_commit = master + +PACKAGES += mockgyver +pkg_mockgyver_name = mockgyver +pkg_mockgyver_description = A mocking library for Erlang +pkg_mockgyver_homepage = https://github.com/klajo/mockgyver +pkg_mockgyver_fetch = git +pkg_mockgyver_repo = https://github.com/klajo/mockgyver +pkg_mockgyver_commit = master + +PACKAGES += modlib +pkg_modlib_name = modlib +pkg_modlib_description = Web framework based on Erlang's inets httpd +pkg_modlib_homepage = https://github.com/gar1t/modlib +pkg_modlib_fetch = git +pkg_modlib_repo = https://github.com/gar1t/modlib +pkg_modlib_commit = master + +PACKAGES += mongodb +pkg_mongodb_name = mongodb +pkg_mongodb_description = MongoDB driver for Erlang +pkg_mongodb_homepage = https://github.com/comtihon/mongodb-erlang +pkg_mongodb_fetch = git +pkg_mongodb_repo = https://github.com/comtihon/mongodb-erlang +pkg_mongodb_commit = master + +PACKAGES += mongooseim +pkg_mongooseim_name = mongooseim +pkg_mongooseim_description = Jabber / XMPP server with focus on performance and scalability, by Erlang Solutions +pkg_mongooseim_homepage = https://www.erlang-solutions.com/products/mongooseim-massively-scalable-ejabberd-platform +pkg_mongooseim_fetch = git +pkg_mongooseim_repo = https://github.com/esl/MongooseIM +pkg_mongooseim_commit = master + +PACKAGES += moyo +pkg_moyo_name = moyo +pkg_moyo_description = Erlang utility functions library +pkg_moyo_homepage = https://github.com/dwango/moyo +pkg_moyo_fetch = git +pkg_moyo_repo = https://github.com/dwango/moyo +pkg_moyo_commit = master + +PACKAGES += msgpack +pkg_msgpack_name = msgpack +pkg_msgpack_description = MessagePack (de)serializer implementation for Erlang +pkg_msgpack_homepage = https://github.com/msgpack/msgpack-erlang +pkg_msgpack_fetch = git +pkg_msgpack_repo = https://github.com/msgpack/msgpack-erlang +pkg_msgpack_commit = master + +PACKAGES += mu2 +pkg_mu2_name = mu2 +pkg_mu2_description = Erlang mutation testing tool +pkg_mu2_homepage = https://github.com/ramsay-t/mu2 +pkg_mu2_fetch = git +pkg_mu2_repo = https://github.com/ramsay-t/mu2 +pkg_mu2_commit = master + +PACKAGES += mustache +pkg_mustache_name = mustache +pkg_mustache_description = Mustache template engine for Erlang. +pkg_mustache_homepage = https://github.com/mojombo/mustache.erl +pkg_mustache_fetch = git +pkg_mustache_repo = https://github.com/mojombo/mustache.erl +pkg_mustache_commit = master + +PACKAGES += myproto +pkg_myproto_name = myproto +pkg_myproto_description = MySQL Server Protocol in Erlang +pkg_myproto_homepage = https://github.com/altenwald/myproto +pkg_myproto_fetch = git +pkg_myproto_repo = https://github.com/altenwald/myproto +pkg_myproto_commit = master + +PACKAGES += mysql +pkg_mysql_name = mysql +pkg_mysql_description = MySQL client library for Erlang/OTP +pkg_mysql_homepage = https://github.com/mysql-otp/mysql-otp +pkg_mysql_fetch = git +pkg_mysql_repo = https://github.com/mysql-otp/mysql-otp +pkg_mysql_commit = 1.5.1 + +PACKAGES += n2o +pkg_n2o_name = n2o +pkg_n2o_description = WebSocket Application Server +pkg_n2o_homepage = https://github.com/5HT/n2o +pkg_n2o_fetch = git +pkg_n2o_repo = https://github.com/5HT/n2o +pkg_n2o_commit = master + +PACKAGES += nat_upnp +pkg_nat_upnp_name = nat_upnp +pkg_nat_upnp_description = Erlang library to map your internal port to an external using UNP IGD +pkg_nat_upnp_homepage = https://github.com/benoitc/nat_upnp +pkg_nat_upnp_fetch = git +pkg_nat_upnp_repo = https://github.com/benoitc/nat_upnp +pkg_nat_upnp_commit = master + +PACKAGES += neo4j +pkg_neo4j_name = neo4j +pkg_neo4j_description = Erlang client library for Neo4J. +pkg_neo4j_homepage = https://github.com/dmitriid/neo4j-erlang +pkg_neo4j_fetch = git +pkg_neo4j_repo = https://github.com/dmitriid/neo4j-erlang +pkg_neo4j_commit = master + +PACKAGES += neotoma +pkg_neotoma_name = neotoma +pkg_neotoma_description = Erlang library and packrat parser-generator for parsing expression grammars. +pkg_neotoma_homepage = https://github.com/seancribbs/neotoma +pkg_neotoma_fetch = git +pkg_neotoma_repo = https://github.com/seancribbs/neotoma +pkg_neotoma_commit = master + +PACKAGES += newrelic +pkg_newrelic_name = newrelic +pkg_newrelic_description = Erlang library for sending metrics to New Relic +pkg_newrelic_homepage = https://github.com/wooga/newrelic-erlang +pkg_newrelic_fetch = git +pkg_newrelic_repo = https://github.com/wooga/newrelic-erlang +pkg_newrelic_commit = master + +PACKAGES += nifty +pkg_nifty_name = nifty +pkg_nifty_description = Erlang NIF wrapper generator +pkg_nifty_homepage = https://github.com/parapluu/nifty +pkg_nifty_fetch = git +pkg_nifty_repo = https://github.com/parapluu/nifty +pkg_nifty_commit = master + +PACKAGES += nitrogen_core +pkg_nitrogen_core_name = nitrogen_core +pkg_nitrogen_core_description = The core Nitrogen library. +pkg_nitrogen_core_homepage = http://nitrogenproject.com/ +pkg_nitrogen_core_fetch = git +pkg_nitrogen_core_repo = https://github.com/nitrogen/nitrogen_core +pkg_nitrogen_core_commit = master + +PACKAGES += nkbase +pkg_nkbase_name = nkbase +pkg_nkbase_description = NkBASE distributed database +pkg_nkbase_homepage = https://github.com/Nekso/nkbase +pkg_nkbase_fetch = git +pkg_nkbase_repo = https://github.com/Nekso/nkbase +pkg_nkbase_commit = develop + +PACKAGES += nkdocker +pkg_nkdocker_name = nkdocker +pkg_nkdocker_description = Erlang Docker client +pkg_nkdocker_homepage = https://github.com/Nekso/nkdocker +pkg_nkdocker_fetch = git +pkg_nkdocker_repo = https://github.com/Nekso/nkdocker +pkg_nkdocker_commit = master + +PACKAGES += nkpacket +pkg_nkpacket_name = nkpacket +pkg_nkpacket_description = Generic Erlang transport layer +pkg_nkpacket_homepage = https://github.com/Nekso/nkpacket +pkg_nkpacket_fetch = git +pkg_nkpacket_repo = https://github.com/Nekso/nkpacket +pkg_nkpacket_commit = master + +PACKAGES += nksip +pkg_nksip_name = nksip +pkg_nksip_description = Erlang SIP application server +pkg_nksip_homepage = https://github.com/kalta/nksip +pkg_nksip_fetch = git +pkg_nksip_repo = https://github.com/kalta/nksip +pkg_nksip_commit = master + +PACKAGES += nodefinder +pkg_nodefinder_name = nodefinder +pkg_nodefinder_description = automatic node discovery via UDP multicast +pkg_nodefinder_homepage = https://github.com/erlanger/nodefinder +pkg_nodefinder_fetch = git +pkg_nodefinder_repo = https://github.com/okeuday/nodefinder +pkg_nodefinder_commit = master + +PACKAGES += nprocreg +pkg_nprocreg_name = nprocreg +pkg_nprocreg_description = Minimal Distributed Erlang Process Registry +pkg_nprocreg_homepage = http://nitrogenproject.com/ +pkg_nprocreg_fetch = git +pkg_nprocreg_repo = https://github.com/nitrogen/nprocreg +pkg_nprocreg_commit = master + +PACKAGES += oauth +pkg_oauth_name = oauth +pkg_oauth_description = An Erlang OAuth 1.0 implementation +pkg_oauth_homepage = https://github.com/tim/erlang-oauth +pkg_oauth_fetch = git +pkg_oauth_repo = https://github.com/tim/erlang-oauth +pkg_oauth_commit = master + +PACKAGES += oauth2 +pkg_oauth2_name = oauth2 +pkg_oauth2_description = Erlang Oauth2 implementation +pkg_oauth2_homepage = https://github.com/kivra/oauth2 +pkg_oauth2_fetch = git +pkg_oauth2_repo = https://github.com/kivra/oauth2 +pkg_oauth2_commit = master + +PACKAGES += observer_cli +pkg_observer_cli_name = observer_cli +pkg_observer_cli_description = Visualize Erlang/Elixir Nodes On The Command Line +pkg_observer_cli_homepage = http://zhongwencool.github.io/observer_cli +pkg_observer_cli_fetch = git +pkg_observer_cli_repo = https://github.com/zhongwencool/observer_cli +pkg_observer_cli_commit = master + +PACKAGES += octopus +pkg_octopus_name = octopus +pkg_octopus_description = Small and flexible pool manager written in Erlang +pkg_octopus_homepage = https://github.com/erlangbureau/octopus +pkg_octopus_fetch = git +pkg_octopus_repo = https://github.com/erlangbureau/octopus +pkg_octopus_commit = master + +PACKAGES += of_protocol +pkg_of_protocol_name = of_protocol +pkg_of_protocol_description = OpenFlow Protocol Library for Erlang +pkg_of_protocol_homepage = https://github.com/FlowForwarding/of_protocol +pkg_of_protocol_fetch = git +pkg_of_protocol_repo = https://github.com/FlowForwarding/of_protocol +pkg_of_protocol_commit = master + +PACKAGES += opencouch +pkg_opencouch_name = couch +pkg_opencouch_description = A embeddable document oriented database compatible with Apache CouchDB +pkg_opencouch_homepage = https://github.com/benoitc/opencouch +pkg_opencouch_fetch = git +pkg_opencouch_repo = https://github.com/benoitc/opencouch +pkg_opencouch_commit = master + +PACKAGES += openflow +pkg_openflow_name = openflow +pkg_openflow_description = An OpenFlow controller written in pure erlang +pkg_openflow_homepage = https://github.com/renatoaguiar/erlang-openflow +pkg_openflow_fetch = git +pkg_openflow_repo = https://github.com/renatoaguiar/erlang-openflow +pkg_openflow_commit = master + +PACKAGES += openid +pkg_openid_name = openid +pkg_openid_description = Erlang OpenID +pkg_openid_homepage = https://github.com/brendonh/erl_openid +pkg_openid_fetch = git +pkg_openid_repo = https://github.com/brendonh/erl_openid +pkg_openid_commit = master + +PACKAGES += openpoker +pkg_openpoker_name = openpoker +pkg_openpoker_description = Genesis Texas hold'em Game Server +pkg_openpoker_homepage = https://github.com/hpyhacking/openpoker +pkg_openpoker_fetch = git +pkg_openpoker_repo = https://github.com/hpyhacking/openpoker +pkg_openpoker_commit = master + +PACKAGES += otpbp +pkg_otpbp_name = otpbp +pkg_otpbp_description = Parse transformer for use new OTP functions in old Erlang/OTP releases (R15, R16, 17, 18, 19) +pkg_otpbp_homepage = https://github.com/Ledest/otpbp +pkg_otpbp_fetch = git +pkg_otpbp_repo = https://github.com/Ledest/otpbp +pkg_otpbp_commit = master + +PACKAGES += pal +pkg_pal_name = pal +pkg_pal_description = Pragmatic Authentication Library +pkg_pal_homepage = https://github.com/manifest/pal +pkg_pal_fetch = git +pkg_pal_repo = https://github.com/manifest/pal +pkg_pal_commit = master + +PACKAGES += parse_trans +pkg_parse_trans_name = parse_trans +pkg_parse_trans_description = Parse transform utilities for Erlang +pkg_parse_trans_homepage = https://github.com/uwiger/parse_trans +pkg_parse_trans_fetch = git +pkg_parse_trans_repo = https://github.com/uwiger/parse_trans +pkg_parse_trans_commit = master + +PACKAGES += parsexml +pkg_parsexml_name = parsexml +pkg_parsexml_description = Simple DOM XML parser with convenient and very simple API +pkg_parsexml_homepage = https://github.com/maxlapshin/parsexml +pkg_parsexml_fetch = git +pkg_parsexml_repo = https://github.com/maxlapshin/parsexml +pkg_parsexml_commit = master + +PACKAGES += partisan +pkg_partisan_name = partisan +pkg_partisan_description = High-performance, high-scalability distributed computing with Erlang and Elixir. +pkg_partisan_homepage = http://partisan.cloud +pkg_partisan_fetch = git +pkg_partisan_repo = https://github.com/lasp-lang/partisan +pkg_partisan_commit = master + +PACKAGES += pegjs +pkg_pegjs_name = pegjs +pkg_pegjs_description = An implementation of PEG.js grammar for Erlang. +pkg_pegjs_homepage = https://github.com/dmitriid/pegjs +pkg_pegjs_fetch = git +pkg_pegjs_repo = https://github.com/dmitriid/pegjs +pkg_pegjs_commit = master + +PACKAGES += percept2 +pkg_percept2_name = percept2 +pkg_percept2_description = Concurrent profiling tool for Erlang +pkg_percept2_homepage = https://github.com/huiqing/percept2 +pkg_percept2_fetch = git +pkg_percept2_repo = https://github.com/huiqing/percept2 +pkg_percept2_commit = master + +PACKAGES += pgo +pkg_pgo_name = pgo +pkg_pgo_description = Erlang Postgres client and connection pool +pkg_pgo_homepage = https://github.com/erleans/pgo.git +pkg_pgo_fetch = git +pkg_pgo_repo = https://github.com/erleans/pgo.git +pkg_pgo_commit = master + +PACKAGES += pgsql +pkg_pgsql_name = pgsql +pkg_pgsql_description = Erlang PostgreSQL driver +pkg_pgsql_homepage = https://github.com/semiocast/pgsql +pkg_pgsql_fetch = git +pkg_pgsql_repo = https://github.com/semiocast/pgsql +pkg_pgsql_commit = master + +PACKAGES += pkgx +pkg_pkgx_name = pkgx +pkg_pkgx_description = Build .deb packages from Erlang releases +pkg_pkgx_homepage = https://github.com/arjan/pkgx +pkg_pkgx_fetch = git +pkg_pkgx_repo = https://github.com/arjan/pkgx +pkg_pkgx_commit = master + +PACKAGES += pkt +pkg_pkt_name = pkt +pkg_pkt_description = Erlang network protocol library +pkg_pkt_homepage = https://github.com/msantos/pkt +pkg_pkt_fetch = git +pkg_pkt_repo = https://github.com/msantos/pkt +pkg_pkt_commit = master + +PACKAGES += plain_fsm +pkg_plain_fsm_name = plain_fsm +pkg_plain_fsm_description = A behaviour/support library for writing plain Erlang FSMs. +pkg_plain_fsm_homepage = https://github.com/uwiger/plain_fsm +pkg_plain_fsm_fetch = git +pkg_plain_fsm_repo = https://github.com/uwiger/plain_fsm +pkg_plain_fsm_commit = master + +PACKAGES += plumtree +pkg_plumtree_name = plumtree +pkg_plumtree_description = Epidemic Broadcast Trees +pkg_plumtree_homepage = https://github.com/helium/plumtree +pkg_plumtree_fetch = git +pkg_plumtree_repo = https://github.com/helium/plumtree +pkg_plumtree_commit = master + +PACKAGES += pmod_transform +pkg_pmod_transform_name = pmod_transform +pkg_pmod_transform_description = Parse transform for parameterized modules +pkg_pmod_transform_homepage = https://github.com/erlang/pmod_transform +pkg_pmod_transform_fetch = git +pkg_pmod_transform_repo = https://github.com/erlang/pmod_transform +pkg_pmod_transform_commit = master + +PACKAGES += pobox +pkg_pobox_name = pobox +pkg_pobox_description = External buffer processes to protect against mailbox overflow in Erlang +pkg_pobox_homepage = https://github.com/ferd/pobox +pkg_pobox_fetch = git +pkg_pobox_repo = https://github.com/ferd/pobox +pkg_pobox_commit = master + +PACKAGES += ponos +pkg_ponos_name = ponos +pkg_ponos_description = ponos is a simple yet powerful load generator written in erlang +pkg_ponos_homepage = https://github.com/klarna/ponos +pkg_ponos_fetch = git +pkg_ponos_repo = https://github.com/klarna/ponos +pkg_ponos_commit = master + +PACKAGES += poolboy +pkg_poolboy_name = poolboy +pkg_poolboy_description = A hunky Erlang worker pool factory +pkg_poolboy_homepage = https://github.com/devinus/poolboy +pkg_poolboy_fetch = git +pkg_poolboy_repo = https://github.com/devinus/poolboy +pkg_poolboy_commit = master + +PACKAGES += pooler +pkg_pooler_name = pooler +pkg_pooler_description = An OTP Process Pool Application +pkg_pooler_homepage = https://github.com/seth/pooler +pkg_pooler_fetch = git +pkg_pooler_repo = https://github.com/seth/pooler +pkg_pooler_commit = master + +PACKAGES += pqueue +pkg_pqueue_name = pqueue +pkg_pqueue_description = Erlang Priority Queues +pkg_pqueue_homepage = https://github.com/okeuday/pqueue +pkg_pqueue_fetch = git +pkg_pqueue_repo = https://github.com/okeuday/pqueue +pkg_pqueue_commit = master + +PACKAGES += procket +pkg_procket_name = procket +pkg_procket_description = Erlang interface to low level socket operations +pkg_procket_homepage = http://blog.listincomprehension.com/search/label/procket +pkg_procket_fetch = git +pkg_procket_repo = https://github.com/msantos/procket +pkg_procket_commit = master + +PACKAGES += prometheus +pkg_prometheus_name = prometheus +pkg_prometheus_description = Prometheus.io client in Erlang +pkg_prometheus_homepage = https://github.com/deadtrickster/prometheus.erl +pkg_prometheus_fetch = git +pkg_prometheus_repo = https://github.com/deadtrickster/prometheus.erl +pkg_prometheus_commit = master + +PACKAGES += prop +pkg_prop_name = prop +pkg_prop_description = An Erlang code scaffolding and generator system. +pkg_prop_homepage = https://github.com/nuex/prop +pkg_prop_fetch = git +pkg_prop_repo = https://github.com/nuex/prop +pkg_prop_commit = master + +PACKAGES += proper +pkg_proper_name = proper +pkg_proper_description = PropEr: a QuickCheck-inspired property-based testing tool for Erlang. +pkg_proper_homepage = http://proper.softlab.ntua.gr +pkg_proper_fetch = git +pkg_proper_repo = https://github.com/manopapad/proper +pkg_proper_commit = master + +PACKAGES += props +pkg_props_name = props +pkg_props_description = Property structure library +pkg_props_homepage = https://github.com/greyarea/props +pkg_props_fetch = git +pkg_props_repo = https://github.com/greyarea/props +pkg_props_commit = master + +PACKAGES += protobuffs +pkg_protobuffs_name = protobuffs +pkg_protobuffs_description = An implementation of Google's Protocol Buffers for Erlang, based on ngerakines/erlang_protobuffs. +pkg_protobuffs_homepage = https://github.com/basho/erlang_protobuffs +pkg_protobuffs_fetch = git +pkg_protobuffs_repo = https://github.com/basho/erlang_protobuffs +pkg_protobuffs_commit = master + +PACKAGES += psycho +pkg_psycho_name = psycho +pkg_psycho_description = HTTP server that provides a WSGI-like interface for applications and middleware. +pkg_psycho_homepage = https://github.com/gar1t/psycho +pkg_psycho_fetch = git +pkg_psycho_repo = https://github.com/gar1t/psycho +pkg_psycho_commit = master + +PACKAGES += purity +pkg_purity_name = purity +pkg_purity_description = A side-effect analyzer for Erlang +pkg_purity_homepage = https://github.com/mpitid/purity +pkg_purity_fetch = git +pkg_purity_repo = https://github.com/mpitid/purity +pkg_purity_commit = master + +PACKAGES += push_service +pkg_push_service_name = push_service +pkg_push_service_description = Push service +pkg_push_service_homepage = https://github.com/hairyhum/push_service +pkg_push_service_fetch = git +pkg_push_service_repo = https://github.com/hairyhum/push_service +pkg_push_service_commit = master + +PACKAGES += qdate +pkg_qdate_name = qdate +pkg_qdate_description = Date, time, and timezone parsing, formatting, and conversion for Erlang. +pkg_qdate_homepage = https://github.com/choptastic/qdate +pkg_qdate_fetch = git +pkg_qdate_repo = https://github.com/choptastic/qdate +pkg_qdate_commit = master + +PACKAGES += qrcode +pkg_qrcode_name = qrcode +pkg_qrcode_description = QR Code encoder in Erlang +pkg_qrcode_homepage = https://github.com/komone/qrcode +pkg_qrcode_fetch = git +pkg_qrcode_repo = https://github.com/komone/qrcode +pkg_qrcode_commit = master + +PACKAGES += quest +pkg_quest_name = quest +pkg_quest_description = Learn Erlang through this set of challenges. An interactive system for getting to know Erlang. +pkg_quest_homepage = https://github.com/eriksoe/ErlangQuest +pkg_quest_fetch = git +pkg_quest_repo = https://github.com/eriksoe/ErlangQuest +pkg_quest_commit = master + +PACKAGES += quickrand +pkg_quickrand_name = quickrand +pkg_quickrand_description = Quick Erlang Random Number Generation +pkg_quickrand_homepage = https://github.com/okeuday/quickrand +pkg_quickrand_fetch = git +pkg_quickrand_repo = https://github.com/okeuday/quickrand +pkg_quickrand_commit = master + +PACKAGES += rabbit +pkg_rabbit_name = rabbit +pkg_rabbit_description = RabbitMQ Server +pkg_rabbit_homepage = https://www.rabbitmq.com/ +pkg_rabbit_fetch = git +pkg_rabbit_repo = https://github.com/rabbitmq/rabbitmq-server.git +pkg_rabbit_commit = master + +PACKAGES += rabbit_exchange_type_riak +pkg_rabbit_exchange_type_riak_name = rabbit_exchange_type_riak +pkg_rabbit_exchange_type_riak_description = Custom RabbitMQ exchange type for sticking messages in Riak +pkg_rabbit_exchange_type_riak_homepage = https://github.com/jbrisbin/riak-exchange +pkg_rabbit_exchange_type_riak_fetch = git +pkg_rabbit_exchange_type_riak_repo = https://github.com/jbrisbin/riak-exchange +pkg_rabbit_exchange_type_riak_commit = master + +PACKAGES += rack +pkg_rack_name = rack +pkg_rack_description = Rack handler for erlang +pkg_rack_homepage = https://github.com/erlyvideo/rack +pkg_rack_fetch = git +pkg_rack_repo = https://github.com/erlyvideo/rack +pkg_rack_commit = master + +PACKAGES += radierl +pkg_radierl_name = radierl +pkg_radierl_description = RADIUS protocol stack implemented in Erlang. +pkg_radierl_homepage = https://github.com/vances/radierl +pkg_radierl_fetch = git +pkg_radierl_repo = https://github.com/vances/radierl +pkg_radierl_commit = master + +PACKAGES += rafter +pkg_rafter_name = rafter +pkg_rafter_description = An Erlang library application which implements the Raft consensus protocol +pkg_rafter_homepage = https://github.com/andrewjstone/rafter +pkg_rafter_fetch = git +pkg_rafter_repo = https://github.com/andrewjstone/rafter +pkg_rafter_commit = master + +PACKAGES += ranch +pkg_ranch_name = ranch +pkg_ranch_description = Socket acceptor pool for TCP protocols. +pkg_ranch_homepage = http://ninenines.eu +pkg_ranch_fetch = git +pkg_ranch_repo = https://github.com/ninenines/ranch +pkg_ranch_commit = 1.2.1 + +PACKAGES += rbeacon +pkg_rbeacon_name = rbeacon +pkg_rbeacon_description = LAN discovery and presence in Erlang. +pkg_rbeacon_homepage = https://github.com/refuge/rbeacon +pkg_rbeacon_fetch = git +pkg_rbeacon_repo = https://github.com/refuge/rbeacon +pkg_rbeacon_commit = master + +PACKAGES += rebar +pkg_rebar_name = rebar +pkg_rebar_description = Erlang build tool that makes it easy to compile and test Erlang applications, port drivers and releases. +pkg_rebar_homepage = http://www.rebar3.org +pkg_rebar_fetch = git +pkg_rebar_repo = https://github.com/rebar/rebar3 +pkg_rebar_commit = master + +PACKAGES += rebus +pkg_rebus_name = rebus +pkg_rebus_description = A stupid simple, internal, pub/sub event bus written in- and for Erlang. +pkg_rebus_homepage = https://github.com/olle/rebus +pkg_rebus_fetch = git +pkg_rebus_repo = https://github.com/olle/rebus +pkg_rebus_commit = master + +PACKAGES += rec2json +pkg_rec2json_name = rec2json +pkg_rec2json_description = Compile erlang record definitions into modules to convert them to/from json easily. +pkg_rec2json_homepage = https://github.com/lordnull/rec2json +pkg_rec2json_fetch = git +pkg_rec2json_repo = https://github.com/lordnull/rec2json +pkg_rec2json_commit = master + +PACKAGES += recon +pkg_recon_name = recon +pkg_recon_description = Collection of functions and scripts to debug Erlang in production. +pkg_recon_homepage = https://github.com/ferd/recon +pkg_recon_fetch = git +pkg_recon_repo = https://github.com/ferd/recon +pkg_recon_commit = master + +PACKAGES += record_info +pkg_record_info_name = record_info +pkg_record_info_description = Convert between record and proplist +pkg_record_info_homepage = https://github.com/bipthelin/erlang-record_info +pkg_record_info_fetch = git +pkg_record_info_repo = https://github.com/bipthelin/erlang-record_info +pkg_record_info_commit = master + +PACKAGES += redgrid +pkg_redgrid_name = redgrid +pkg_redgrid_description = automatic Erlang node discovery via redis +pkg_redgrid_homepage = https://github.com/jkvor/redgrid +pkg_redgrid_fetch = git +pkg_redgrid_repo = https://github.com/jkvor/redgrid +pkg_redgrid_commit = master + +PACKAGES += redo +pkg_redo_name = redo +pkg_redo_description = pipelined erlang redis client +pkg_redo_homepage = https://github.com/jkvor/redo +pkg_redo_fetch = git +pkg_redo_repo = https://github.com/jkvor/redo +pkg_redo_commit = master + +PACKAGES += reload_mk +pkg_reload_mk_name = reload_mk +pkg_reload_mk_description = Live reload plugin for erlang.mk. +pkg_reload_mk_homepage = https://github.com/bullno1/reload.mk +pkg_reload_mk_fetch = git +pkg_reload_mk_repo = https://github.com/bullno1/reload.mk +pkg_reload_mk_commit = master + +PACKAGES += reltool_util +pkg_reltool_util_name = reltool_util +pkg_reltool_util_description = Erlang reltool utility functionality application +pkg_reltool_util_homepage = https://github.com/okeuday/reltool_util +pkg_reltool_util_fetch = git +pkg_reltool_util_repo = https://github.com/okeuday/reltool_util +pkg_reltool_util_commit = master + +PACKAGES += relx +pkg_relx_name = relx +pkg_relx_description = Sane, simple release creation for Erlang +pkg_relx_homepage = https://github.com/erlware/relx +pkg_relx_fetch = git +pkg_relx_repo = https://github.com/erlware/relx +pkg_relx_commit = master + +PACKAGES += resource_discovery +pkg_resource_discovery_name = resource_discovery +pkg_resource_discovery_description = An application used to dynamically discover resources present in an Erlang node cluster. +pkg_resource_discovery_homepage = http://erlware.org/ +pkg_resource_discovery_fetch = git +pkg_resource_discovery_repo = https://github.com/erlware/resource_discovery +pkg_resource_discovery_commit = master + +PACKAGES += restc +pkg_restc_name = restc +pkg_restc_description = Erlang Rest Client +pkg_restc_homepage = https://github.com/kivra/restclient +pkg_restc_fetch = git +pkg_restc_repo = https://github.com/kivra/restclient +pkg_restc_commit = master + +PACKAGES += rfc4627_jsonrpc +pkg_rfc4627_jsonrpc_name = rfc4627_jsonrpc +pkg_rfc4627_jsonrpc_description = Erlang RFC4627 (JSON) codec and JSON-RPC server implementation. +pkg_rfc4627_jsonrpc_homepage = https://github.com/tonyg/erlang-rfc4627 +pkg_rfc4627_jsonrpc_fetch = git +pkg_rfc4627_jsonrpc_repo = https://github.com/tonyg/erlang-rfc4627 +pkg_rfc4627_jsonrpc_commit = master + +PACKAGES += riak_control +pkg_riak_control_name = riak_control +pkg_riak_control_description = Webmachine-based administration interface for Riak. +pkg_riak_control_homepage = https://github.com/basho/riak_control +pkg_riak_control_fetch = git +pkg_riak_control_repo = https://github.com/basho/riak_control +pkg_riak_control_commit = master + +PACKAGES += riak_core +pkg_riak_core_name = riak_core +pkg_riak_core_description = Distributed systems infrastructure used by Riak. +pkg_riak_core_homepage = https://github.com/basho/riak_core +pkg_riak_core_fetch = git +pkg_riak_core_repo = https://github.com/basho/riak_core +pkg_riak_core_commit = master + +PACKAGES += riak_dt +pkg_riak_dt_name = riak_dt +pkg_riak_dt_description = Convergent replicated datatypes in Erlang +pkg_riak_dt_homepage = https://github.com/basho/riak_dt +pkg_riak_dt_fetch = git +pkg_riak_dt_repo = https://github.com/basho/riak_dt +pkg_riak_dt_commit = master + +PACKAGES += riak_ensemble +pkg_riak_ensemble_name = riak_ensemble +pkg_riak_ensemble_description = Multi-Paxos framework in Erlang +pkg_riak_ensemble_homepage = https://github.com/basho/riak_ensemble +pkg_riak_ensemble_fetch = git +pkg_riak_ensemble_repo = https://github.com/basho/riak_ensemble +pkg_riak_ensemble_commit = master + +PACKAGES += riak_kv +pkg_riak_kv_name = riak_kv +pkg_riak_kv_description = Riak Key/Value Store +pkg_riak_kv_homepage = https://github.com/basho/riak_kv +pkg_riak_kv_fetch = git +pkg_riak_kv_repo = https://github.com/basho/riak_kv +pkg_riak_kv_commit = master + +PACKAGES += riak_pg +pkg_riak_pg_name = riak_pg +pkg_riak_pg_description = Distributed process groups with riak_core. +pkg_riak_pg_homepage = https://github.com/cmeiklejohn/riak_pg +pkg_riak_pg_fetch = git +pkg_riak_pg_repo = https://github.com/cmeiklejohn/riak_pg +pkg_riak_pg_commit = master + +PACKAGES += riak_pipe +pkg_riak_pipe_name = riak_pipe +pkg_riak_pipe_description = Riak Pipelines +pkg_riak_pipe_homepage = https://github.com/basho/riak_pipe +pkg_riak_pipe_fetch = git +pkg_riak_pipe_repo = https://github.com/basho/riak_pipe +pkg_riak_pipe_commit = master + +PACKAGES += riak_sysmon +pkg_riak_sysmon_name = riak_sysmon +pkg_riak_sysmon_description = Simple OTP app for managing Erlang VM system_monitor event messages +pkg_riak_sysmon_homepage = https://github.com/basho/riak_sysmon +pkg_riak_sysmon_fetch = git +pkg_riak_sysmon_repo = https://github.com/basho/riak_sysmon +pkg_riak_sysmon_commit = master + +PACKAGES += riak_test +pkg_riak_test_name = riak_test +pkg_riak_test_description = I'm in your cluster, testing your riaks +pkg_riak_test_homepage = https://github.com/basho/riak_test +pkg_riak_test_fetch = git +pkg_riak_test_repo = https://github.com/basho/riak_test +pkg_riak_test_commit = master + +PACKAGES += riakc +pkg_riakc_name = riakc +pkg_riakc_description = Erlang clients for Riak. +pkg_riakc_homepage = https://github.com/basho/riak-erlang-client +pkg_riakc_fetch = git +pkg_riakc_repo = https://github.com/basho/riak-erlang-client +pkg_riakc_commit = master + +PACKAGES += riakhttpc +pkg_riakhttpc_name = riakhttpc +pkg_riakhttpc_description = Riak Erlang client using the HTTP interface +pkg_riakhttpc_homepage = https://github.com/basho/riak-erlang-http-client +pkg_riakhttpc_fetch = git +pkg_riakhttpc_repo = https://github.com/basho/riak-erlang-http-client +pkg_riakhttpc_commit = master + +PACKAGES += riaknostic +pkg_riaknostic_name = riaknostic +pkg_riaknostic_description = A diagnostic tool for Riak installations, to find common errors asap +pkg_riaknostic_homepage = https://github.com/basho/riaknostic +pkg_riaknostic_fetch = git +pkg_riaknostic_repo = https://github.com/basho/riaknostic +pkg_riaknostic_commit = master + +PACKAGES += riakpool +pkg_riakpool_name = riakpool +pkg_riakpool_description = erlang riak client pool +pkg_riakpool_homepage = https://github.com/dweldon/riakpool +pkg_riakpool_fetch = git +pkg_riakpool_repo = https://github.com/dweldon/riakpool +pkg_riakpool_commit = master + +PACKAGES += rivus_cep +pkg_rivus_cep_name = rivus_cep +pkg_rivus_cep_description = Complex event processing in Erlang +pkg_rivus_cep_homepage = https://github.com/vascokk/rivus_cep +pkg_rivus_cep_fetch = git +pkg_rivus_cep_repo = https://github.com/vascokk/rivus_cep +pkg_rivus_cep_commit = master + +PACKAGES += rlimit +pkg_rlimit_name = rlimit +pkg_rlimit_description = Magnus Klaar's rate limiter code from etorrent +pkg_rlimit_homepage = https://github.com/jlouis/rlimit +pkg_rlimit_fetch = git +pkg_rlimit_repo = https://github.com/jlouis/rlimit +pkg_rlimit_commit = master + +PACKAGES += rust_mk +pkg_rust_mk_name = rust_mk +pkg_rust_mk_description = Build Rust crates in an Erlang application +pkg_rust_mk_homepage = https://github.com/goertzenator/rust.mk +pkg_rust_mk_fetch = git +pkg_rust_mk_repo = https://github.com/goertzenator/rust.mk +pkg_rust_mk_commit = master + +PACKAGES += safetyvalve +pkg_safetyvalve_name = safetyvalve +pkg_safetyvalve_description = A safety valve for your erlang node +pkg_safetyvalve_homepage = https://github.com/jlouis/safetyvalve +pkg_safetyvalve_fetch = git +pkg_safetyvalve_repo = https://github.com/jlouis/safetyvalve +pkg_safetyvalve_commit = master + +PACKAGES += seestar +pkg_seestar_name = seestar +pkg_seestar_description = The Erlang client for Cassandra 1.2+ binary protocol +pkg_seestar_homepage = https://github.com/iamaleksey/seestar +pkg_seestar_fetch = git +pkg_seestar_repo = https://github.com/iamaleksey/seestar +pkg_seestar_commit = master + +PACKAGES += service +pkg_service_name = service +pkg_service_description = A minimal Erlang behavior for creating CloudI internal services +pkg_service_homepage = http://cloudi.org/ +pkg_service_fetch = git +pkg_service_repo = https://github.com/CloudI/service +pkg_service_commit = master + +PACKAGES += setup +pkg_setup_name = setup +pkg_setup_description = Generic setup utility for Erlang-based systems +pkg_setup_homepage = https://github.com/uwiger/setup +pkg_setup_fetch = git +pkg_setup_repo = https://github.com/uwiger/setup +pkg_setup_commit = master + +PACKAGES += sext +pkg_sext_name = sext +pkg_sext_description = Sortable Erlang Term Serialization +pkg_sext_homepage = https://github.com/uwiger/sext +pkg_sext_fetch = git +pkg_sext_repo = https://github.com/uwiger/sext +pkg_sext_commit = master + +PACKAGES += sfmt +pkg_sfmt_name = sfmt +pkg_sfmt_description = SFMT pseudo random number generator for Erlang. +pkg_sfmt_homepage = https://github.com/jj1bdx/sfmt-erlang +pkg_sfmt_fetch = git +pkg_sfmt_repo = https://github.com/jj1bdx/sfmt-erlang +pkg_sfmt_commit = master + +PACKAGES += sgte +pkg_sgte_name = sgte +pkg_sgte_description = A simple Erlang Template Engine +pkg_sgte_homepage = https://github.com/filippo/sgte +pkg_sgte_fetch = git +pkg_sgte_repo = https://github.com/filippo/sgte +pkg_sgte_commit = master + +PACKAGES += sheriff +pkg_sheriff_name = sheriff +pkg_sheriff_description = Parse transform for type based validation. +pkg_sheriff_homepage = http://ninenines.eu +pkg_sheriff_fetch = git +pkg_sheriff_repo = https://github.com/extend/sheriff +pkg_sheriff_commit = master + +PACKAGES += shotgun +pkg_shotgun_name = shotgun +pkg_shotgun_description = better than just a gun +pkg_shotgun_homepage = https://github.com/inaka/shotgun +pkg_shotgun_fetch = git +pkg_shotgun_repo = https://github.com/inaka/shotgun +pkg_shotgun_commit = master + +PACKAGES += sidejob +pkg_sidejob_name = sidejob +pkg_sidejob_description = Parallel worker and capacity limiting library for Erlang +pkg_sidejob_homepage = https://github.com/basho/sidejob +pkg_sidejob_fetch = git +pkg_sidejob_repo = https://github.com/basho/sidejob +pkg_sidejob_commit = master + +PACKAGES += sieve +pkg_sieve_name = sieve +pkg_sieve_description = sieve is a simple TCP routing proxy (layer 7) in erlang +pkg_sieve_homepage = https://github.com/benoitc/sieve +pkg_sieve_fetch = git +pkg_sieve_repo = https://github.com/benoitc/sieve +pkg_sieve_commit = master + +PACKAGES += sighandler +pkg_sighandler_name = sighandler +pkg_sighandler_description = Handle UNIX signals in Er lang +pkg_sighandler_homepage = https://github.com/jkingsbery/sighandler +pkg_sighandler_fetch = git +pkg_sighandler_repo = https://github.com/jkingsbery/sighandler +pkg_sighandler_commit = master + +PACKAGES += simhash +pkg_simhash_name = simhash +pkg_simhash_description = Simhashing for Erlang -- hashing algorithm to find near-duplicates in binary data. +pkg_simhash_homepage = https://github.com/ferd/simhash +pkg_simhash_fetch = git +pkg_simhash_repo = https://github.com/ferd/simhash +pkg_simhash_commit = master + +PACKAGES += simple_bridge +pkg_simple_bridge_name = simple_bridge +pkg_simple_bridge_description = A simple, standardized interface library to Erlang HTTP Servers. +pkg_simple_bridge_homepage = https://github.com/nitrogen/simple_bridge +pkg_simple_bridge_fetch = git +pkg_simple_bridge_repo = https://github.com/nitrogen/simple_bridge +pkg_simple_bridge_commit = master + +PACKAGES += simple_oauth2 +pkg_simple_oauth2_name = simple_oauth2 +pkg_simple_oauth2_description = Simple erlang OAuth2 client module for any http server framework (Google, Facebook, Yandex, Vkontakte are preconfigured) +pkg_simple_oauth2_homepage = https://github.com/virtan/simple_oauth2 +pkg_simple_oauth2_fetch = git +pkg_simple_oauth2_repo = https://github.com/virtan/simple_oauth2 +pkg_simple_oauth2_commit = master + +PACKAGES += skel +pkg_skel_name = skel +pkg_skel_description = A Streaming Process-based Skeleton Library for Erlang +pkg_skel_homepage = https://github.com/ParaPhrase/skel +pkg_skel_fetch = git +pkg_skel_repo = https://github.com/ParaPhrase/skel +pkg_skel_commit = master + +PACKAGES += slack +pkg_slack_name = slack +pkg_slack_description = Minimal slack notification OTP library. +pkg_slack_homepage = https://github.com/DonBranson/slack +pkg_slack_fetch = git +pkg_slack_repo = https://github.com/DonBranson/slack.git +pkg_slack_commit = master + +PACKAGES += smother +pkg_smother_name = smother +pkg_smother_description = Extended code coverage metrics for Erlang. +pkg_smother_homepage = https://ramsay-t.github.io/Smother/ +pkg_smother_fetch = git +pkg_smother_repo = https://github.com/ramsay-t/Smother +pkg_smother_commit = master + +PACKAGES += snappyer +pkg_snappyer_name = snappyer +pkg_snappyer_description = Snappy as nif for Erlang +pkg_snappyer_homepage = https://github.com/zmstone/snappyer +pkg_snappyer_fetch = git +pkg_snappyer_repo = https://github.com/zmstone/snappyer.git +pkg_snappyer_commit = master + +PACKAGES += social +pkg_social_name = social +pkg_social_description = Cowboy handler for social login via OAuth2 providers +pkg_social_homepage = https://github.com/dvv/social +pkg_social_fetch = git +pkg_social_repo = https://github.com/dvv/social +pkg_social_commit = master + +PACKAGES += spapi_router +pkg_spapi_router_name = spapi_router +pkg_spapi_router_description = Partially-connected Erlang clustering +pkg_spapi_router_homepage = https://github.com/spilgames/spapi-router +pkg_spapi_router_fetch = git +pkg_spapi_router_repo = https://github.com/spilgames/spapi-router +pkg_spapi_router_commit = master + +PACKAGES += sqerl +pkg_sqerl_name = sqerl +pkg_sqerl_description = An Erlang-flavoured SQL DSL +pkg_sqerl_homepage = https://github.com/hairyhum/sqerl +pkg_sqerl_fetch = git +pkg_sqerl_repo = https://github.com/hairyhum/sqerl +pkg_sqerl_commit = master + +PACKAGES += srly +pkg_srly_name = srly +pkg_srly_description = Native Erlang Unix serial interface +pkg_srly_homepage = https://github.com/msantos/srly +pkg_srly_fetch = git +pkg_srly_repo = https://github.com/msantos/srly +pkg_srly_commit = master + +PACKAGES += sshrpc +pkg_sshrpc_name = sshrpc +pkg_sshrpc_description = Erlang SSH RPC module (experimental) +pkg_sshrpc_homepage = https://github.com/jj1bdx/sshrpc +pkg_sshrpc_fetch = git +pkg_sshrpc_repo = https://github.com/jj1bdx/sshrpc +pkg_sshrpc_commit = master + +PACKAGES += stable +pkg_stable_name = stable +pkg_stable_description = Library of assorted helpers for Cowboy web server. +pkg_stable_homepage = https://github.com/dvv/stable +pkg_stable_fetch = git +pkg_stable_repo = https://github.com/dvv/stable +pkg_stable_commit = master + +PACKAGES += statebox +pkg_statebox_name = statebox +pkg_statebox_description = Erlang state monad with merge/conflict-resolution capabilities. Useful for Riak. +pkg_statebox_homepage = https://github.com/mochi/statebox +pkg_statebox_fetch = git +pkg_statebox_repo = https://github.com/mochi/statebox +pkg_statebox_commit = master + +PACKAGES += statebox_riak +pkg_statebox_riak_name = statebox_riak +pkg_statebox_riak_description = Convenience library that makes it easier to use statebox with riak, extracted from best practices in our production code at Mochi Media. +pkg_statebox_riak_homepage = https://github.com/mochi/statebox_riak +pkg_statebox_riak_fetch = git +pkg_statebox_riak_repo = https://github.com/mochi/statebox_riak +pkg_statebox_riak_commit = master + +PACKAGES += statman +pkg_statman_name = statman +pkg_statman_description = Efficiently collect massive volumes of metrics inside the Erlang VM +pkg_statman_homepage = https://github.com/knutin/statman +pkg_statman_fetch = git +pkg_statman_repo = https://github.com/knutin/statman +pkg_statman_commit = master + +PACKAGES += statsderl +pkg_statsderl_name = statsderl +pkg_statsderl_description = StatsD client (erlang) +pkg_statsderl_homepage = https://github.com/lpgauth/statsderl +pkg_statsderl_fetch = git +pkg_statsderl_repo = https://github.com/lpgauth/statsderl +pkg_statsderl_commit = master + +PACKAGES += stdinout_pool +pkg_stdinout_pool_name = stdinout_pool +pkg_stdinout_pool_description = stdinout_pool : stuff goes in, stuff goes out. there's never any miscommunication. +pkg_stdinout_pool_homepage = https://github.com/mattsta/erlang-stdinout-pool +pkg_stdinout_pool_fetch = git +pkg_stdinout_pool_repo = https://github.com/mattsta/erlang-stdinout-pool +pkg_stdinout_pool_commit = master + +PACKAGES += stockdb +pkg_stockdb_name = stockdb +pkg_stockdb_description = Database for storing Stock Exchange quotes in erlang +pkg_stockdb_homepage = https://github.com/maxlapshin/stockdb +pkg_stockdb_fetch = git +pkg_stockdb_repo = https://github.com/maxlapshin/stockdb +pkg_stockdb_commit = master + +PACKAGES += stripe +pkg_stripe_name = stripe +pkg_stripe_description = Erlang interface to the stripe.com API +pkg_stripe_homepage = https://github.com/mattsta/stripe-erlang +pkg_stripe_fetch = git +pkg_stripe_repo = https://github.com/mattsta/stripe-erlang +pkg_stripe_commit = v1 + +PACKAGES += subproc +pkg_subproc_name = subproc +pkg_subproc_description = unix subprocess manager with {active,once|false} modes +pkg_subproc_homepage = http://dozzie.jarowit.net/trac/wiki/subproc +pkg_subproc_fetch = git +pkg_subproc_repo = https://github.com/dozzie/subproc +pkg_subproc_commit = v0.1.0 + +PACKAGES += supervisor3 +pkg_supervisor3_name = supervisor3 +pkg_supervisor3_description = OTP supervisor with additional strategies +pkg_supervisor3_homepage = https://github.com/klarna/supervisor3 +pkg_supervisor3_fetch = git +pkg_supervisor3_repo = https://github.com/klarna/supervisor3.git +pkg_supervisor3_commit = master + +PACKAGES += surrogate +pkg_surrogate_name = surrogate +pkg_surrogate_description = Proxy server written in erlang. Supports reverse proxy load balancing and forward proxy with http (including CONNECT), socks4, socks5, and transparent proxy modes. +pkg_surrogate_homepage = https://github.com/skruger/Surrogate +pkg_surrogate_fetch = git +pkg_surrogate_repo = https://github.com/skruger/Surrogate +pkg_surrogate_commit = master + +PACKAGES += swab +pkg_swab_name = swab +pkg_swab_description = General purpose buffer handling module +pkg_swab_homepage = https://github.com/crownedgrouse/swab +pkg_swab_fetch = git +pkg_swab_repo = https://github.com/crownedgrouse/swab +pkg_swab_commit = master + +PACKAGES += swarm +pkg_swarm_name = swarm +pkg_swarm_description = Fast and simple acceptor pool for Erlang +pkg_swarm_homepage = https://github.com/jeremey/swarm +pkg_swarm_fetch = git +pkg_swarm_repo = https://github.com/jeremey/swarm +pkg_swarm_commit = master + +PACKAGES += switchboard +pkg_switchboard_name = switchboard +pkg_switchboard_description = A framework for processing email using worker plugins. +pkg_switchboard_homepage = https://github.com/thusfresh/switchboard +pkg_switchboard_fetch = git +pkg_switchboard_repo = https://github.com/thusfresh/switchboard +pkg_switchboard_commit = master + +PACKAGES += syn +pkg_syn_name = syn +pkg_syn_description = A global Process Registry and Process Group manager for Erlang. +pkg_syn_homepage = https://github.com/ostinelli/syn +pkg_syn_fetch = git +pkg_syn_repo = https://github.com/ostinelli/syn +pkg_syn_commit = master + +PACKAGES += sync +pkg_sync_name = sync +pkg_sync_description = On-the-fly recompiling and reloading in Erlang. +pkg_sync_homepage = https://github.com/rustyio/sync +pkg_sync_fetch = git +pkg_sync_repo = https://github.com/rustyio/sync +pkg_sync_commit = master + +PACKAGES += syntaxerl +pkg_syntaxerl_name = syntaxerl +pkg_syntaxerl_description = Syntax checker for Erlang +pkg_syntaxerl_homepage = https://github.com/ten0s/syntaxerl +pkg_syntaxerl_fetch = git +pkg_syntaxerl_repo = https://github.com/ten0s/syntaxerl +pkg_syntaxerl_commit = master + +PACKAGES += syslog +pkg_syslog_name = syslog +pkg_syslog_description = Erlang port driver for interacting with syslog via syslog(3) +pkg_syslog_homepage = https://github.com/Vagabond/erlang-syslog +pkg_syslog_fetch = git +pkg_syslog_repo = https://github.com/Vagabond/erlang-syslog +pkg_syslog_commit = master + +PACKAGES += taskforce +pkg_taskforce_name = taskforce +pkg_taskforce_description = Erlang worker pools for controlled parallelisation of arbitrary tasks. +pkg_taskforce_homepage = https://github.com/g-andrade/taskforce +pkg_taskforce_fetch = git +pkg_taskforce_repo = https://github.com/g-andrade/taskforce +pkg_taskforce_commit = master + +PACKAGES += tddreloader +pkg_tddreloader_name = tddreloader +pkg_tddreloader_description = Shell utility for recompiling, reloading, and testing code as it changes +pkg_tddreloader_homepage = https://github.com/version2beta/tddreloader +pkg_tddreloader_fetch = git +pkg_tddreloader_repo = https://github.com/version2beta/tddreloader +pkg_tddreloader_commit = master + +PACKAGES += tempo +pkg_tempo_name = tempo +pkg_tempo_description = NIF-based date and time parsing and formatting for Erlang. +pkg_tempo_homepage = https://github.com/selectel/tempo +pkg_tempo_fetch = git +pkg_tempo_repo = https://github.com/selectel/tempo +pkg_tempo_commit = master + +PACKAGES += ticktick +pkg_ticktick_name = ticktick +pkg_ticktick_description = Ticktick is an id generator for message service. +pkg_ticktick_homepage = https://github.com/ericliang/ticktick +pkg_ticktick_fetch = git +pkg_ticktick_repo = https://github.com/ericliang/ticktick +pkg_ticktick_commit = master + +PACKAGES += tinymq +pkg_tinymq_name = tinymq +pkg_tinymq_description = TinyMQ - a diminutive, in-memory message queue +pkg_tinymq_homepage = https://github.com/ChicagoBoss/tinymq +pkg_tinymq_fetch = git +pkg_tinymq_repo = https://github.com/ChicagoBoss/tinymq +pkg_tinymq_commit = master + +PACKAGES += tinymt +pkg_tinymt_name = tinymt +pkg_tinymt_description = TinyMT pseudo random number generator for Erlang. +pkg_tinymt_homepage = https://github.com/jj1bdx/tinymt-erlang +pkg_tinymt_fetch = git +pkg_tinymt_repo = https://github.com/jj1bdx/tinymt-erlang +pkg_tinymt_commit = master + +PACKAGES += tirerl +pkg_tirerl_name = tirerl +pkg_tirerl_description = Erlang interface to Elastic Search +pkg_tirerl_homepage = https://github.com/inaka/tirerl +pkg_tirerl_fetch = git +pkg_tirerl_repo = https://github.com/inaka/tirerl +pkg_tirerl_commit = master + +PACKAGES += toml +pkg_toml_name = toml +pkg_toml_description = TOML (0.4.0) config parser +pkg_toml_homepage = http://dozzie.jarowit.net/trac/wiki/TOML +pkg_toml_fetch = git +pkg_toml_repo = https://github.com/dozzie/toml +pkg_toml_commit = v0.2.0 + +PACKAGES += traffic_tools +pkg_traffic_tools_name = traffic_tools +pkg_traffic_tools_description = Simple traffic limiting library +pkg_traffic_tools_homepage = https://github.com/systra/traffic_tools +pkg_traffic_tools_fetch = git +pkg_traffic_tools_repo = https://github.com/systra/traffic_tools +pkg_traffic_tools_commit = master + +PACKAGES += trails +pkg_trails_name = trails +pkg_trails_description = A couple of improvements over Cowboy Routes +pkg_trails_homepage = http://inaka.github.io/cowboy-trails/ +pkg_trails_fetch = git +pkg_trails_repo = https://github.com/inaka/cowboy-trails +pkg_trails_commit = master + +PACKAGES += trane +pkg_trane_name = trane +pkg_trane_description = SAX style broken HTML parser in Erlang +pkg_trane_homepage = https://github.com/massemanet/trane +pkg_trane_fetch = git +pkg_trane_repo = https://github.com/massemanet/trane +pkg_trane_commit = master + +PACKAGES += transit +pkg_transit_name = transit +pkg_transit_description = transit format for erlang +pkg_transit_homepage = https://github.com/isaiah/transit-erlang +pkg_transit_fetch = git +pkg_transit_repo = https://github.com/isaiah/transit-erlang +pkg_transit_commit = master + +PACKAGES += trie +pkg_trie_name = trie +pkg_trie_description = Erlang Trie Implementation +pkg_trie_homepage = https://github.com/okeuday/trie +pkg_trie_fetch = git +pkg_trie_repo = https://github.com/okeuday/trie +pkg_trie_commit = master + +PACKAGES += triq +pkg_triq_name = triq +pkg_triq_description = Trifork QuickCheck +pkg_triq_homepage = https://triq.gitlab.io +pkg_triq_fetch = git +pkg_triq_repo = https://gitlab.com/triq/triq.git +pkg_triq_commit = master + +PACKAGES += tunctl +pkg_tunctl_name = tunctl +pkg_tunctl_description = Erlang TUN/TAP interface +pkg_tunctl_homepage = https://github.com/msantos/tunctl +pkg_tunctl_fetch = git +pkg_tunctl_repo = https://github.com/msantos/tunctl +pkg_tunctl_commit = master + +PACKAGES += twerl +pkg_twerl_name = twerl +pkg_twerl_description = Erlang client for the Twitter Streaming API +pkg_twerl_homepage = https://github.com/lucaspiller/twerl +pkg_twerl_fetch = git +pkg_twerl_repo = https://github.com/lucaspiller/twerl +pkg_twerl_commit = oauth + +PACKAGES += twitter_erlang +pkg_twitter_erlang_name = twitter_erlang +pkg_twitter_erlang_description = An Erlang twitter client +pkg_twitter_erlang_homepage = https://github.com/ngerakines/erlang_twitter +pkg_twitter_erlang_fetch = git +pkg_twitter_erlang_repo = https://github.com/ngerakines/erlang_twitter +pkg_twitter_erlang_commit = master + +PACKAGES += ucol_nif +pkg_ucol_nif_name = ucol_nif +pkg_ucol_nif_description = ICU based collation Erlang module +pkg_ucol_nif_homepage = https://github.com/refuge/ucol_nif +pkg_ucol_nif_fetch = git +pkg_ucol_nif_repo = https://github.com/refuge/ucol_nif +pkg_ucol_nif_commit = master + +PACKAGES += unicorn +pkg_unicorn_name = unicorn +pkg_unicorn_description = Generic configuration server +pkg_unicorn_homepage = https://github.com/shizzard/unicorn +pkg_unicorn_fetch = git +pkg_unicorn_repo = https://github.com/shizzard/unicorn +pkg_unicorn_commit = master + +PACKAGES += unsplit +pkg_unsplit_name = unsplit +pkg_unsplit_description = Resolves conflicts in Mnesia after network splits +pkg_unsplit_homepage = https://github.com/uwiger/unsplit +pkg_unsplit_fetch = git +pkg_unsplit_repo = https://github.com/uwiger/unsplit +pkg_unsplit_commit = master + +PACKAGES += uuid +pkg_uuid_name = uuid +pkg_uuid_description = Erlang UUID Implementation +pkg_uuid_homepage = https://github.com/okeuday/uuid +pkg_uuid_fetch = git +pkg_uuid_repo = https://github.com/okeuday/uuid +pkg_uuid_commit = master + +PACKAGES += ux +pkg_ux_name = ux +pkg_ux_description = Unicode eXtention for Erlang (Strings, Collation) +pkg_ux_homepage = https://github.com/erlang-unicode/ux +pkg_ux_fetch = git +pkg_ux_repo = https://github.com/erlang-unicode/ux +pkg_ux_commit = master + +PACKAGES += vert +pkg_vert_name = vert +pkg_vert_description = Erlang binding to libvirt virtualization API +pkg_vert_homepage = https://github.com/msantos/erlang-libvirt +pkg_vert_fetch = git +pkg_vert_repo = https://github.com/msantos/erlang-libvirt +pkg_vert_commit = master + +PACKAGES += verx +pkg_verx_name = verx +pkg_verx_description = Erlang implementation of the libvirtd remote protocol +pkg_verx_homepage = https://github.com/msantos/verx +pkg_verx_fetch = git +pkg_verx_repo = https://github.com/msantos/verx +pkg_verx_commit = master + +PACKAGES += vmq_acl +pkg_vmq_acl_name = vmq_acl +pkg_vmq_acl_description = Component of VerneMQ: A distributed MQTT message broker +pkg_vmq_acl_homepage = https://verne.mq/ +pkg_vmq_acl_fetch = git +pkg_vmq_acl_repo = https://github.com/erlio/vmq_acl +pkg_vmq_acl_commit = master + +PACKAGES += vmq_bridge +pkg_vmq_bridge_name = vmq_bridge +pkg_vmq_bridge_description = Component of VerneMQ: A distributed MQTT message broker +pkg_vmq_bridge_homepage = https://verne.mq/ +pkg_vmq_bridge_fetch = git +pkg_vmq_bridge_repo = https://github.com/erlio/vmq_bridge +pkg_vmq_bridge_commit = master + +PACKAGES += vmq_graphite +pkg_vmq_graphite_name = vmq_graphite +pkg_vmq_graphite_description = Component of VerneMQ: A distributed MQTT message broker +pkg_vmq_graphite_homepage = https://verne.mq/ +pkg_vmq_graphite_fetch = git +pkg_vmq_graphite_repo = https://github.com/erlio/vmq_graphite +pkg_vmq_graphite_commit = master + +PACKAGES += vmq_passwd +pkg_vmq_passwd_name = vmq_passwd +pkg_vmq_passwd_description = Component of VerneMQ: A distributed MQTT message broker +pkg_vmq_passwd_homepage = https://verne.mq/ +pkg_vmq_passwd_fetch = git +pkg_vmq_passwd_repo = https://github.com/erlio/vmq_passwd +pkg_vmq_passwd_commit = master + +PACKAGES += vmq_server +pkg_vmq_server_name = vmq_server +pkg_vmq_server_description = Component of VerneMQ: A distributed MQTT message broker +pkg_vmq_server_homepage = https://verne.mq/ +pkg_vmq_server_fetch = git +pkg_vmq_server_repo = https://github.com/erlio/vmq_server +pkg_vmq_server_commit = master + +PACKAGES += vmq_snmp +pkg_vmq_snmp_name = vmq_snmp +pkg_vmq_snmp_description = Component of VerneMQ: A distributed MQTT message broker +pkg_vmq_snmp_homepage = https://verne.mq/ +pkg_vmq_snmp_fetch = git +pkg_vmq_snmp_repo = https://github.com/erlio/vmq_snmp +pkg_vmq_snmp_commit = master + +PACKAGES += vmq_systree +pkg_vmq_systree_name = vmq_systree +pkg_vmq_systree_description = Component of VerneMQ: A distributed MQTT message broker +pkg_vmq_systree_homepage = https://verne.mq/ +pkg_vmq_systree_fetch = git +pkg_vmq_systree_repo = https://github.com/erlio/vmq_systree +pkg_vmq_systree_commit = master + +PACKAGES += vmstats +pkg_vmstats_name = vmstats +pkg_vmstats_description = tiny Erlang app that works in conjunction with statsderl in order to generate information on the Erlang VM for graphite logs. +pkg_vmstats_homepage = https://github.com/ferd/vmstats +pkg_vmstats_fetch = git +pkg_vmstats_repo = https://github.com/ferd/vmstats +pkg_vmstats_commit = master + +PACKAGES += walrus +pkg_walrus_name = walrus +pkg_walrus_description = Walrus - Mustache-like Templating +pkg_walrus_homepage = https://github.com/devinus/walrus +pkg_walrus_fetch = git +pkg_walrus_repo = https://github.com/devinus/walrus +pkg_walrus_commit = master + +PACKAGES += webmachine +pkg_webmachine_name = webmachine +pkg_webmachine_description = A REST-based system for building web applications. +pkg_webmachine_homepage = https://github.com/basho/webmachine +pkg_webmachine_fetch = git +pkg_webmachine_repo = https://github.com/basho/webmachine +pkg_webmachine_commit = master + +PACKAGES += websocket_client +pkg_websocket_client_name = websocket_client +pkg_websocket_client_description = Erlang websocket client (ws and wss supported) +pkg_websocket_client_homepage = https://github.com/jeremyong/websocket_client +pkg_websocket_client_fetch = git +pkg_websocket_client_repo = https://github.com/jeremyong/websocket_client +pkg_websocket_client_commit = master + +PACKAGES += worker_pool +pkg_worker_pool_name = worker_pool +pkg_worker_pool_description = a simple erlang worker pool +pkg_worker_pool_homepage = https://github.com/inaka/worker_pool +pkg_worker_pool_fetch = git +pkg_worker_pool_repo = https://github.com/inaka/worker_pool +pkg_worker_pool_commit = master + +PACKAGES += wrangler +pkg_wrangler_name = wrangler +pkg_wrangler_description = Import of the Wrangler svn repository. +pkg_wrangler_homepage = http://www.cs.kent.ac.uk/projects/wrangler/Home.html +pkg_wrangler_fetch = git +pkg_wrangler_repo = https://github.com/RefactoringTools/wrangler +pkg_wrangler_commit = master + +PACKAGES += wsock +pkg_wsock_name = wsock +pkg_wsock_description = Erlang library to build WebSocket clients and servers +pkg_wsock_homepage = https://github.com/madtrick/wsock +pkg_wsock_fetch = git +pkg_wsock_repo = https://github.com/madtrick/wsock +pkg_wsock_commit = master + +PACKAGES += xhttpc +pkg_xhttpc_name = xhttpc +pkg_xhttpc_description = Extensible HTTP Client for Erlang +pkg_xhttpc_homepage = https://github.com/seriyps/xhttpc +pkg_xhttpc_fetch = git +pkg_xhttpc_repo = https://github.com/seriyps/xhttpc +pkg_xhttpc_commit = master + +PACKAGES += xref_runner +pkg_xref_runner_name = xref_runner +pkg_xref_runner_description = Erlang Xref Runner (inspired in rebar xref) +pkg_xref_runner_homepage = https://github.com/inaka/xref_runner +pkg_xref_runner_fetch = git +pkg_xref_runner_repo = https://github.com/inaka/xref_runner +pkg_xref_runner_commit = master + +PACKAGES += yamerl +pkg_yamerl_name = yamerl +pkg_yamerl_description = YAML 1.2 parser in pure Erlang +pkg_yamerl_homepage = https://github.com/yakaz/yamerl +pkg_yamerl_fetch = git +pkg_yamerl_repo = https://github.com/yakaz/yamerl +pkg_yamerl_commit = master + +PACKAGES += yamler +pkg_yamler_name = yamler +pkg_yamler_description = libyaml-based yaml loader for Erlang +pkg_yamler_homepage = https://github.com/goertzenator/yamler +pkg_yamler_fetch = git +pkg_yamler_repo = https://github.com/goertzenator/yamler +pkg_yamler_commit = master + +PACKAGES += yaws +pkg_yaws_name = yaws +pkg_yaws_description = Yaws webserver +pkg_yaws_homepage = http://yaws.hyber.org +pkg_yaws_fetch = git +pkg_yaws_repo = https://github.com/klacke/yaws +pkg_yaws_commit = master + +PACKAGES += zab_engine +pkg_zab_engine_name = zab_engine +pkg_zab_engine_description = zab propotocol implement by erlang +pkg_zab_engine_homepage = https://github.com/xinmingyao/zab_engine +pkg_zab_engine_fetch = git +pkg_zab_engine_repo = https://github.com/xinmingyao/zab_engine +pkg_zab_engine_commit = master + +PACKAGES += zabbix_sender +pkg_zabbix_sender_name = zabbix_sender +pkg_zabbix_sender_description = Zabbix trapper for sending data to Zabbix in pure Erlang +pkg_zabbix_sender_homepage = https://github.com/stalkermn/zabbix_sender +pkg_zabbix_sender_fetch = git +pkg_zabbix_sender_repo = https://github.com/stalkermn/zabbix_sender.git +pkg_zabbix_sender_commit = master + +PACKAGES += zeta +pkg_zeta_name = zeta +pkg_zeta_description = HTTP access log parser in Erlang +pkg_zeta_homepage = https://github.com/s1n4/zeta +pkg_zeta_fetch = git +pkg_zeta_repo = https://github.com/s1n4/zeta +pkg_zeta_commit = master + +PACKAGES += zippers +pkg_zippers_name = zippers +pkg_zippers_description = A library for functional zipper data structures in Erlang. Read more on zippers +pkg_zippers_homepage = https://github.com/ferd/zippers +pkg_zippers_fetch = git +pkg_zippers_repo = https://github.com/ferd/zippers +pkg_zippers_commit = master + +PACKAGES += zlists +pkg_zlists_name = zlists +pkg_zlists_description = Erlang lazy lists library. +pkg_zlists_homepage = https://github.com/vjache/erlang-zlists +pkg_zlists_fetch = git +pkg_zlists_repo = https://github.com/vjache/erlang-zlists +pkg_zlists_commit = master + +PACKAGES += zraft_lib +pkg_zraft_lib_name = zraft_lib +pkg_zraft_lib_description = Erlang raft consensus protocol implementation +pkg_zraft_lib_homepage = https://github.com/dreyk/zraft_lib +pkg_zraft_lib_fetch = git +pkg_zraft_lib_repo = https://github.com/dreyk/zraft_lib +pkg_zraft_lib_commit = master + +PACKAGES += zucchini +pkg_zucchini_name = zucchini +pkg_zucchini_description = An Erlang INI parser +pkg_zucchini_homepage = https://github.com/devinus/zucchini +pkg_zucchini_fetch = git +pkg_zucchini_repo = https://github.com/devinus/zucchini +pkg_zucchini_commit = master + +# Copyright (c) 2015-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: search + +define pkg_print + $(verbose) printf "%s\n" \ + $(if $(call core_eq,$(1),$(pkg_$(1)_name)),,"Pkg name: $(1)") \ + "App name: $(pkg_$(1)_name)" \ + "Description: $(pkg_$(1)_description)" \ + "Home page: $(pkg_$(1)_homepage)" \ + "Fetch with: $(pkg_$(1)_fetch)" \ + "Repository: $(pkg_$(1)_repo)" \ + "Commit: $(pkg_$(1)_commit)" \ + "" + +endef + +search: +ifdef q + $(foreach p,$(PACKAGES), \ + $(if $(findstring $(call core_lc,$(q)),$(call core_lc,$(pkg_$(p)_name) $(pkg_$(p)_description))), \ + $(call pkg_print,$(p)))) +else + $(foreach p,$(PACKAGES),$(call pkg_print,$(p))) +endif + +# Copyright (c) 2013-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: distclean-deps clean-tmp-deps.log + +# Configuration. + +ifdef OTP_DEPS +$(warning The variable OTP_DEPS is deprecated in favor of LOCAL_DEPS.) +endif + +IGNORE_DEPS ?= +export IGNORE_DEPS + +APPS_DIR ?= $(CURDIR)/apps +export APPS_DIR + +DEPS_DIR ?= $(CURDIR)/deps +export DEPS_DIR + +REBAR_DEPS_DIR = $(DEPS_DIR) +export REBAR_DEPS_DIR + +REBAR_GIT ?= https://github.com/rebar/rebar +REBAR_COMMIT ?= 576e12171ab8d69b048b827b92aa65d067deea01 + +# External "early" plugins (see core/plugins.mk for regular plugins). +# They both use the core_dep_plugin macro. + +define core_dep_plugin +ifeq ($(2),$(PROJECT)) +-include $$(patsubst $(PROJECT)/%,%,$(1)) +else +-include $(DEPS_DIR)/$(1) + +$(DEPS_DIR)/$(1): $(DEPS_DIR)/$(2) ; +endif +endef + +DEP_EARLY_PLUGINS ?= + +$(foreach p,$(DEP_EARLY_PLUGINS),\ + $(eval $(if $(findstring /,$p),\ + $(call core_dep_plugin,$p,$(firstword $(subst /, ,$p))),\ + $(call core_dep_plugin,$p/early-plugins.mk,$p)))) + +# Query functions. + +query_fetch_method = $(if $(dep_$(1)),$(call _qfm_dep,$(word 1,$(dep_$(1)))),$(call _qfm_pkg,$(1))) +_qfm_dep = $(if $(dep_fetch_$(1)),$(1),$(if $(IS_DEP),legacy,fail)) +_qfm_pkg = $(if $(pkg_$(1)_fetch),$(pkg_$(1)_fetch),fail) + +query_name = $(if $(dep_$(1)),$(1),$(if $(pkg_$(1)_name),$(pkg_$(1)_name),$(1))) + +query_repo = $(call _qr,$(1),$(call query_fetch_method,$(1))) +_qr = $(if $(query_repo_$(2)),$(call query_repo_$(2),$(1)),$(call dep_repo,$(1))) + +query_repo_default = $(if $(dep_$(1)),$(word 2,$(dep_$(1))),$(pkg_$(1)_repo)) +query_repo_git = $(patsubst git://github.com/%,https://github.com/%,$(call query_repo_default,$(1))) +query_repo_git-subfolder = $(call query_repo_git,$(1)) +query_repo_git-submodule = - +query_repo_hg = $(call query_repo_default,$(1)) +query_repo_svn = $(call query_repo_default,$(1)) +query_repo_cp = $(call query_repo_default,$(1)) +query_repo_ln = $(call query_repo_default,$(1)) +query_repo_hex = https://hex.pm/packages/$(if $(word 3,$(dep_$(1))),$(word 3,$(dep_$(1))),$(1)) +query_repo_fail = - +query_repo_legacy = - + +query_version = $(call _qv,$(1),$(call query_fetch_method,$(1))) +_qv = $(if $(query_version_$(2)),$(call query_version_$(2),$(1)),$(call dep_commit,$(1))) + +query_version_default = $(if $(dep_$(1)_commit),$(dep_$(1)_commit),$(if $(dep_$(1)),$(word 3,$(dep_$(1))),$(pkg_$(1)_commit))) +query_version_git = $(call query_version_default,$(1)) +query_version_git-subfolder = $(call query_version_git,$(1)) +query_version_git-submodule = - +query_version_hg = $(call query_version_default,$(1)) +query_version_svn = - +query_version_cp = - +query_version_ln = - +query_version_hex = $(if $(dep_$(1)_commit),$(dep_$(1)_commit),$(if $(dep_$(1)),$(word 2,$(dep_$(1))),$(pkg_$(1)_commit))) +query_version_fail = - +query_version_legacy = - + +query_extra = $(call _qe,$(1),$(call query_fetch_method,$(1))) +_qe = $(if $(query_extra_$(2)),$(call query_extra_$(2),$(1)),-) + +query_extra_git = - +query_extra_git-subfolder = $(if $(dep_$(1)),subfolder=$(word 4,$(dep_$(1))),-) +query_extra_git-submodule = - +query_extra_hg = - +query_extra_svn = - +query_extra_cp = - +query_extra_ln = - +query_extra_hex = $(if $(dep_$(1)),package-name=$(word 3,$(dep_$(1))),-) +query_extra_fail = - +query_extra_legacy = - + +query_absolute_path = $(addprefix $(DEPS_DIR)/,$(call query_name,$(1))) + +# Deprecated legacy query functions. +dep_fetch = $(call query_fetch_method,$(1)) +dep_name = $(call query_name,$(1)) +dep_repo = $(call query_repo_git,$(1)) +dep_commit = $(if $(dep_$(1)_commit),$(dep_$(1)_commit),$(if $(dep_$(1)),$(if $(filter hex,$(word 1,$(dep_$(1)))),$(word 2,$(dep_$(1))),$(word 3,$(dep_$(1)))),$(pkg_$(1)_commit))) + +LOCAL_DEPS_DIRS = $(foreach a,$(LOCAL_DEPS),$(if $(wildcard $(APPS_DIR)/$(a)),$(APPS_DIR)/$(a))) +ALL_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(foreach dep,$(filter-out $(IGNORE_DEPS),$(BUILD_DEPS) $(DEPS)),$(call dep_name,$(dep)))) + +# When we are calling an app directly we don't want to include it here +# otherwise it'll be treated both as an apps and a top-level project. +ALL_APPS_DIRS = $(if $(wildcard $(APPS_DIR)/),$(filter-out $(APPS_DIR),$(shell find $(APPS_DIR) -maxdepth 1 -type d))) +ifdef ROOT_DIR +ifndef IS_APP +ALL_APPS_DIRS := $(filter-out $(APPS_DIR)/$(notdir $(CURDIR)),$(ALL_APPS_DIRS)) +endif +endif + +ifeq ($(filter $(APPS_DIR) $(DEPS_DIR),$(subst :, ,$(ERL_LIBS))),) +ifeq ($(ERL_LIBS),) + ERL_LIBS = $(APPS_DIR):$(DEPS_DIR) +else + ERL_LIBS := $(ERL_LIBS):$(APPS_DIR):$(DEPS_DIR) +endif +endif +export ERL_LIBS + +export NO_AUTOPATCH + +# Verbosity. + +dep_verbose_0 = @echo " DEP $1 ($(call dep_commit,$1))"; +dep_verbose_2 = set -x; +dep_verbose = $(dep_verbose_$(V)) + +# Optimization: don't recompile deps unless truly necessary. + +ifndef IS_DEP +ifneq ($(MAKELEVEL),0) +$(shell rm -f ebin/dep_built) +endif +endif + +# Core targets. + +ALL_APPS_DIRS_TO_BUILD = $(if $(LOCAL_DEPS_DIRS)$(IS_APP),$(LOCAL_DEPS_DIRS),$(ALL_APPS_DIRS)) + +apps:: $(ALL_APPS_DIRS) clean-tmp-deps.log | $(ERLANG_MK_TMP) +# Create ebin directory for all apps to make sure Erlang recognizes them +# as proper OTP applications when using -include_lib. This is a temporary +# fix, a proper fix would be to compile apps/* in the right order. +ifndef IS_APP +ifneq ($(ALL_APPS_DIRS),) + $(verbose) set -e; for dep in $(ALL_APPS_DIRS) ; do \ + mkdir -p $$dep/ebin; \ + done +endif +endif +# At the toplevel: if LOCAL_DEPS is defined with at least one local app, only +# compile that list of apps. Otherwise, compile everything. +# Within an app: compile all LOCAL_DEPS that are (uncompiled) local apps. +ifneq ($(ALL_APPS_DIRS_TO_BUILD),) + $(verbose) set -e; for dep in $(ALL_APPS_DIRS_TO_BUILD); do \ + if grep -qs ^$$dep$$ $(ERLANG_MK_TMP)/apps.log; then \ + :; \ + else \ + echo $$dep >> $(ERLANG_MK_TMP)/apps.log; \ + $(MAKE) -C $$dep $(if $(IS_TEST),test-build-app) IS_APP=1; \ + fi \ + done +endif + +clean-tmp-deps.log: +ifeq ($(IS_APP)$(IS_DEP),) + $(verbose) rm -f $(ERLANG_MK_TMP)/apps.log $(ERLANG_MK_TMP)/deps.log +endif + +# Erlang.mk does not rebuild dependencies after they were compiled +# once. If a developer is working on the top-level project and some +# dependencies at the same time, he may want to change this behavior. +# There are two solutions: +# 1. Set `FULL=1` so that all dependencies are visited and +# recursively recompiled if necessary. +# 2. Set `FORCE_REBUILD=` to the specific list of dependencies that +# should be recompiled (instead of the whole set). + +FORCE_REBUILD ?= + +ifeq ($(origin FULL),undefined) +ifneq ($(strip $(force_rebuild_dep)$(FORCE_REBUILD)),) +define force_rebuild_dep +echo "$(FORCE_REBUILD)" | grep -qw "$$(basename "$1")" +endef +endif +endif + +ifneq ($(SKIP_DEPS),) +deps:: +else +deps:: $(ALL_DEPS_DIRS) apps clean-tmp-deps.log | $(ERLANG_MK_TMP) +ifneq ($(ALL_DEPS_DIRS),) + $(verbose) set -e; for dep in $(ALL_DEPS_DIRS); do \ + if grep -qs ^$$dep$$ $(ERLANG_MK_TMP)/deps.log; then \ + :; \ + else \ + echo $$dep >> $(ERLANG_MK_TMP)/deps.log; \ + if [ -z "$(strip $(FULL))" ] $(if $(force_rebuild_dep),&& ! ($(call force_rebuild_dep,$$dep)),) && [ ! -L $$dep ] && [ -f $$dep/ebin/dep_built ]; then \ + :; \ + elif [ -f $$dep/GNUmakefile ] || [ -f $$dep/makefile ] || [ -f $$dep/Makefile ]; then \ + $(MAKE) -C $$dep IS_DEP=1; \ + if [ ! -L $$dep ] && [ -d $$dep/ebin ]; then touch $$dep/ebin/dep_built; fi; \ + else \ + echo "Error: No Makefile to build dependency $$dep." >&2; \ + exit 2; \ + fi \ + fi \ + done +endif +endif + +# Deps related targets. + +# @todo rename GNUmakefile and makefile into Makefile first, if they exist +# While Makefile file could be GNUmakefile or makefile, +# in practice only Makefile is needed so far. +define dep_autopatch + if [ -f $(DEPS_DIR)/$(1)/erlang.mk ]; then \ + rm -rf $(DEPS_DIR)/$1/ebin/; \ + $(call erlang,$(call dep_autopatch_appsrc.erl,$(1))); \ + $(call dep_autopatch_erlang_mk,$(1)); \ + elif [ -f $(DEPS_DIR)/$(1)/Makefile ]; then \ + if [ -f $(DEPS_DIR)/$1/rebar.lock ]; then \ + $(call dep_autopatch2,$1); \ + elif [ 0 != `grep -c "include ../\w*\.mk" $(DEPS_DIR)/$(1)/Makefile` ]; then \ + $(call dep_autopatch2,$(1)); \ + elif [ 0 != `grep -ci "^[^#].*rebar" $(DEPS_DIR)/$(1)/Makefile` ]; then \ + $(call dep_autopatch2,$(1)); \ + elif [ -n "`find $(DEPS_DIR)/$(1)/ -type f -name \*.mk -not -name erlang.mk -exec grep -i "^[^#].*rebar" '{}' \;`" ]; then \ + $(call dep_autopatch2,$(1)); \ + fi \ + else \ + if [ ! -d $(DEPS_DIR)/$(1)/src/ ]; then \ + $(call dep_autopatch_noop,$(1)); \ + else \ + $(call dep_autopatch2,$(1)); \ + fi \ + fi +endef + +define dep_autopatch2 + ! test -f $(DEPS_DIR)/$1/ebin/$1.app || \ + mv -n $(DEPS_DIR)/$1/ebin/$1.app $(DEPS_DIR)/$1/src/$1.app.src; \ + rm -f $(DEPS_DIR)/$1/ebin/$1.app; \ + if [ -f $(DEPS_DIR)/$1/src/$1.app.src.script ]; then \ + $(call erlang,$(call dep_autopatch_appsrc_script.erl,$(1))); \ + fi; \ + $(call erlang,$(call dep_autopatch_appsrc.erl,$(1))); \ + if [ -f $(DEPS_DIR)/$(1)/rebar -o -f $(DEPS_DIR)/$(1)/rebar.config -o -f $(DEPS_DIR)/$(1)/rebar.config.script -o -f $(DEPS_DIR)/$1/rebar.lock ]; then \ + $(call dep_autopatch_fetch_rebar); \ + $(call dep_autopatch_rebar,$(1)); \ + else \ + $(call dep_autopatch_gen,$(1)); \ + fi +endef + +define dep_autopatch_noop + printf "noop:\n" > $(DEPS_DIR)/$(1)/Makefile +endef + +# Replace "include erlang.mk" with a line that will load the parent Erlang.mk +# if given. Do it for all 3 possible Makefile file names. +ifeq ($(NO_AUTOPATCH_ERLANG_MK),) +define dep_autopatch_erlang_mk + for f in Makefile makefile GNUmakefile; do \ + if [ -f $(DEPS_DIR)/$1/$$f ]; then \ + sed -i.bak s/'include *erlang.mk'/'include $$(if $$(ERLANG_MK_FILENAME),$$(ERLANG_MK_FILENAME),erlang.mk)'/ $(DEPS_DIR)/$1/$$f; \ + fi \ + done +endef +else +define dep_autopatch_erlang_mk + : +endef +endif + +define dep_autopatch_gen + printf "%s\n" \ + "ERLC_OPTS = +debug_info" \ + "include ../../erlang.mk" > $(DEPS_DIR)/$(1)/Makefile +endef + +# We use flock/lockf when available to avoid concurrency issues. +define dep_autopatch_fetch_rebar + if command -v flock >/dev/null; then \ + flock $(ERLANG_MK_TMP)/rebar.lock sh -c "$(call dep_autopatch_fetch_rebar2)"; \ + elif command -v lockf >/dev/null; then \ + lockf $(ERLANG_MK_TMP)/rebar.lock sh -c "$(call dep_autopatch_fetch_rebar2)"; \ + else \ + $(call dep_autopatch_fetch_rebar2); \ + fi +endef + +define dep_autopatch_fetch_rebar2 + if [ ! -d $(ERLANG_MK_TMP)/rebar ]; then \ + git clone -q -n -- $(REBAR_GIT) $(ERLANG_MK_TMP)/rebar; \ + cd $(ERLANG_MK_TMP)/rebar; \ + git checkout -q $(REBAR_COMMIT); \ + ./bootstrap; \ + cd -; \ + fi +endef + +define dep_autopatch_rebar + if [ -f $(DEPS_DIR)/$(1)/Makefile ]; then \ + mv $(DEPS_DIR)/$(1)/Makefile $(DEPS_DIR)/$(1)/Makefile.orig.mk; \ + fi; \ + $(call erlang,$(call dep_autopatch_rebar.erl,$(1))); \ + rm -f $(DEPS_DIR)/$(1)/ebin/$(1).app +endef + +define dep_autopatch_rebar.erl + application:load(rebar), + application:set_env(rebar, log_level, debug), + rmemo:start(), + Conf1 = case file:consult("$(call core_native_path,$(DEPS_DIR)/$1/rebar.config)") of + {ok, Conf0} -> Conf0; + _ -> [] + end, + {Conf, OsEnv} = fun() -> + case filelib:is_file("$(call core_native_path,$(DEPS_DIR)/$1/rebar.config.script)") of + false -> {Conf1, []}; + true -> + Bindings0 = erl_eval:new_bindings(), + Bindings1 = erl_eval:add_binding('CONFIG', Conf1, Bindings0), + Bindings = erl_eval:add_binding('SCRIPT', "$(call core_native_path,$(DEPS_DIR)/$1/rebar.config.script)", Bindings1), + Before = os:getenv(), + {ok, Conf2} = file:script("$(call core_native_path,$(DEPS_DIR)/$1/rebar.config.script)", Bindings), + {Conf2, lists:foldl(fun(E, Acc) -> lists:delete(E, Acc) end, os:getenv(), Before)} + end + end(), + Write = fun (Text) -> + file:write_file("$(call core_native_path,$(DEPS_DIR)/$1/Makefile)", Text, [append]) + end, + Escape = fun (Text) -> + re:replace(Text, "\\\\$$", "\$$$$", [global, {return, list}]) + end, + Write("IGNORE_DEPS += edown eper eunit_formatters meck node_package " + "rebar_lock_deps_plugin rebar_vsn_plugin reltool_util\n"), + Write("C_SRC_DIR = /path/do/not/exist\n"), + Write("C_SRC_TYPE = rebar\n"), + Write("DRV_CFLAGS = -fPIC\nexport DRV_CFLAGS\n"), + Write(["ERLANG_ARCH = ", rebar_utils:wordsize(), "\nexport ERLANG_ARCH\n"]), + ToList = fun + (V) when is_atom(V) -> atom_to_list(V); + (V) when is_list(V) -> "'\\"" ++ V ++ "\\"'" + end, + fun() -> + Write("ERLC_OPTS = +debug_info\nexport ERLC_OPTS\n"), + case lists:keyfind(erl_opts, 1, Conf) of + false -> ok; + {_, ErlOpts} -> + lists:foreach(fun + ({d, D}) -> + Write("ERLC_OPTS += -D" ++ ToList(D) ++ "=1\n"); + ({d, DKey, DVal}) -> + Write("ERLC_OPTS += -D" ++ ToList(DKey) ++ "=" ++ ToList(DVal) ++ "\n"); + ({i, I}) -> + Write(["ERLC_OPTS += -I ", I, "\n"]); + ({platform_define, Regex, D}) -> + case rebar_utils:is_arch(Regex) of + true -> Write("ERLC_OPTS += -D" ++ ToList(D) ++ "=1\n"); + false -> ok + end; + ({parse_transform, PT}) -> + Write("ERLC_OPTS += +'{parse_transform, " ++ ToList(PT) ++ "}'\n"); + (_) -> ok + end, ErlOpts) + end, + Write("\n") + end(), + GetHexVsn = fun(N, NP) -> + case file:consult("$(call core_native_path,$(DEPS_DIR)/$1/rebar.lock)") of + {ok, Lock} -> + io:format("~p~n", [Lock]), + case lists:keyfind("1.1.0", 1, Lock) of + {_, LockPkgs} -> + io:format("~p~n", [LockPkgs]), + case lists:keyfind(atom_to_binary(N, latin1), 1, LockPkgs) of + {_, {pkg, _, Vsn}, _} -> + io:format("~p~n", [Vsn]), + {N, {hex, NP, binary_to_list(Vsn)}}; + _ -> + false + end; + _ -> + false + end; + _ -> + false + end + end, + SemVsn = fun + ("~>" ++ S0) -> + S = case S0 of + " " ++ S1 -> S1; + _ -> S0 + end, + case length([ok || $$. <- S]) of + 0 -> S ++ ".0.0"; + 1 -> S ++ ".0"; + _ -> S + end; + (S) -> S + end, + fun() -> + File = case lists:keyfind(deps, 1, Conf) of + false -> []; + {_, Deps} -> + [begin case case Dep of + N when is_atom(N) -> GetHexVsn(N, N); + {N, S} when is_atom(N), is_list(S) -> {N, {hex, N, SemVsn(S)}}; + {N, {pkg, NP}} when is_atom(N) -> GetHexVsn(N, NP); + {N, S, {pkg, NP}} -> {N, {hex, NP, S}}; + {N, S} when is_tuple(S) -> {N, S}; + {N, _, S} -> {N, S}; + {N, _, S, _} -> {N, S}; + _ -> false + end of + false -> ok; + {Name, Source} -> + {Method, Repo, Commit} = case Source of + {hex, NPV, V} -> {hex, V, NPV}; + {git, R} -> {git, R, master}; + {M, R, {branch, C}} -> {M, R, C}; + {M, R, {ref, C}} -> {M, R, C}; + {M, R, {tag, C}} -> {M, R, C}; + {M, R, C} -> {M, R, C} + end, + Write(io_lib:format("DEPS += ~s\ndep_~s = ~s ~s ~s~n", [Name, Name, Method, Repo, Commit])) + end end || Dep <- Deps] + end + end(), + fun() -> + case lists:keyfind(erl_first_files, 1, Conf) of + false -> ok; + {_, Files} -> + Names = [[" ", case lists:reverse(F) of + "lre." ++ Elif -> lists:reverse(Elif); + "lrx." ++ Elif -> lists:reverse(Elif); + "lry." ++ Elif -> lists:reverse(Elif); + Elif -> lists:reverse(Elif) + end] || "src/" ++ F <- Files], + Write(io_lib:format("COMPILE_FIRST +=~s\n", [Names])) + end + end(), + Write("\n\nrebar_dep: preprocess pre-deps deps pre-app app\n"), + Write("\npreprocess::\n"), + Write("\npre-deps::\n"), + Write("\npre-app::\n"), + PatchHook = fun(Cmd) -> + Cmd2 = re:replace(Cmd, "^([g]?make)(.*)( -C.*)", "\\\\1\\\\3\\\\2", [{return, list}]), + case Cmd2 of + "make -C" ++ Cmd1 -> "$$\(MAKE) -C" ++ Escape(Cmd1); + "gmake -C" ++ Cmd1 -> "$$\(MAKE) -C" ++ Escape(Cmd1); + "make " ++ Cmd1 -> "$$\(MAKE) -f Makefile.orig.mk " ++ Escape(Cmd1); + "gmake " ++ Cmd1 -> "$$\(MAKE) -f Makefile.orig.mk " ++ Escape(Cmd1); + _ -> Escape(Cmd) + end + end, + fun() -> + case lists:keyfind(pre_hooks, 1, Conf) of + false -> ok; + {_, Hooks} -> + [case H of + {'get-deps', Cmd} -> + Write("\npre-deps::\n\t" ++ PatchHook(Cmd) ++ "\n"); + {compile, Cmd} -> + Write("\npre-app::\n\tCC=$$\(CC) " ++ PatchHook(Cmd) ++ "\n"); + {Regex, compile, Cmd} -> + case rebar_utils:is_arch(Regex) of + true -> Write("\npre-app::\n\tCC=$$\(CC) " ++ PatchHook(Cmd) ++ "\n"); + false -> ok + end; + _ -> ok + end || H <- Hooks] + end + end(), + ShellToMk = fun(V0) -> + V1 = re:replace(V0, "[$$][(]", "$$\(shell ", [global]), + V = re:replace(V1, "([$$])(?![(])(\\\\w*)", "\\\\1(\\\\2)", [global]), + re:replace(V, "-Werror\\\\b", "", [{return, list}, global]) + end, + PortSpecs = fun() -> + case lists:keyfind(port_specs, 1, Conf) of + false -> + case filelib:is_dir("$(call core_native_path,$(DEPS_DIR)/$1/c_src)") of + false -> []; + true -> + [{"priv/" ++ proplists:get_value(so_name, Conf, "$(1)_drv.so"), + proplists:get_value(port_sources, Conf, ["c_src/*.c"]), []}] + end; + {_, Specs} -> + lists:flatten([case S of + {Output, Input} -> {ShellToMk(Output), Input, []}; + {Regex, Output, Input} -> + case rebar_utils:is_arch(Regex) of + true -> {ShellToMk(Output), Input, []}; + false -> [] + end; + {Regex, Output, Input, [{env, Env}]} -> + case rebar_utils:is_arch(Regex) of + true -> {ShellToMk(Output), Input, Env}; + false -> [] + end + end || S <- Specs]) + end + end(), + PortSpecWrite = fun (Text) -> + file:write_file("$(call core_native_path,$(DEPS_DIR)/$1/c_src/Makefile.erlang.mk)", Text, [append]) + end, + case PortSpecs of + [] -> ok; + _ -> + Write("\npre-app::\n\t@$$\(MAKE) --no-print-directory -f c_src/Makefile.erlang.mk\n"), + PortSpecWrite(io_lib:format("ERL_CFLAGS ?= -finline-functions -Wall -fPIC -I \\"~s/erts-~s/include\\" -I \\"~s\\"\n", + [code:root_dir(), erlang:system_info(version), code:lib_dir(erl_interface, include)])), + PortSpecWrite(io_lib:format("ERL_LDFLAGS ?= -L \\"~s\\" -lei\n", + [code:lib_dir(erl_interface, lib)])), + [PortSpecWrite(["\n", E, "\n"]) || E <- OsEnv], + FilterEnv = fun(Env) -> + lists:flatten([case E of + {_, _} -> E; + {Regex, K, V} -> + case rebar_utils:is_arch(Regex) of + true -> {K, V}; + false -> [] + end + end || E <- Env]) + end, + MergeEnv = fun(Env) -> + lists:foldl(fun ({K, V}, Acc) -> + case lists:keyfind(K, 1, Acc) of + false -> [{K, rebar_utils:expand_env_variable(V, K, "")}|Acc]; + {_, V0} -> [{K, rebar_utils:expand_env_variable(V, K, V0)}|Acc] + end + end, [], Env) + end, + PortEnv = case lists:keyfind(port_env, 1, Conf) of + false -> []; + {_, PortEnv0} -> FilterEnv(PortEnv0) + end, + PortSpec = fun ({Output, Input0, Env}) -> + filelib:ensure_dir("$(call core_native_path,$(DEPS_DIR)/$1/)" ++ Output), + Input = [[" ", I] || I <- Input0], + PortSpecWrite([ + [["\n", K, " = ", ShellToMk(V)] || {K, V} <- lists:reverse(MergeEnv(PortEnv))], + case $(PLATFORM) of + darwin -> "\n\nLDFLAGS += -flat_namespace -undefined suppress"; + _ -> "" + end, + "\n\nall:: ", Output, "\n\t@:\n\n", + "%.o: %.c\n\t$$\(CC) -c -o $$\@ $$\< $$\(CFLAGS) $$\(ERL_CFLAGS) $$\(DRV_CFLAGS) $$\(EXE_CFLAGS)\n\n", + "%.o: %.C\n\t$$\(CXX) -c -o $$\@ $$\< $$\(CXXFLAGS) $$\(ERL_CFLAGS) $$\(DRV_CFLAGS) $$\(EXE_CFLAGS)\n\n", + "%.o: %.cc\n\t$$\(CXX) -c -o $$\@ $$\< $$\(CXXFLAGS) $$\(ERL_CFLAGS) $$\(DRV_CFLAGS) $$\(EXE_CFLAGS)\n\n", + "%.o: %.cpp\n\t$$\(CXX) -c -o $$\@ $$\< $$\(CXXFLAGS) $$\(ERL_CFLAGS) $$\(DRV_CFLAGS) $$\(EXE_CFLAGS)\n\n", + [[Output, ": ", K, " += ", ShellToMk(V), "\n"] || {K, V} <- lists:reverse(MergeEnv(FilterEnv(Env)))], + Output, ": $$\(foreach ext,.c .C .cc .cpp,", + "$$\(patsubst %$$\(ext),%.o,$$\(filter %$$\(ext),$$\(wildcard", Input, "))))\n", + "\t$$\(CC) -o $$\@ $$\? $$\(LDFLAGS) $$\(ERL_LDFLAGS) $$\(DRV_LDFLAGS) $$\(EXE_LDFLAGS)", + case {filename:extension(Output), $(PLATFORM)} of + {[], _} -> "\n"; + {_, darwin} -> "\n"; + _ -> " -shared\n" + end]) + end, + [PortSpec(S) || S <- PortSpecs] + end, + fun() -> + case lists:keyfind(plugins, 1, Conf) of + false -> ok; + {_, Plugins0} -> + Plugins = [P || P <- Plugins0, is_tuple(P)], + case lists:keyfind('lfe-compile', 1, Plugins) of + false -> ok; + _ -> Write("\nBUILD_DEPS = lfe lfe.mk\ndep_lfe.mk = git https://github.com/ninenines/lfe.mk master\nDEP_PLUGINS = lfe.mk\n") + end + end + end(), + Write("\ninclude $$\(if $$\(ERLANG_MK_FILENAME),$$\(ERLANG_MK_FILENAME),erlang.mk)"), + RunPlugin = fun(Plugin, Step) -> + case erlang:function_exported(Plugin, Step, 2) of + false -> ok; + true -> + c:cd("$(call core_native_path,$(DEPS_DIR)/$1/)"), + Ret = Plugin:Step({config, "", Conf, dict:new(), dict:new(), dict:new(), + dict:store(base_dir, "", dict:new())}, undefined), + io:format("rebar plugin ~p step ~p ret ~p~n", [Plugin, Step, Ret]) + end + end, + fun() -> + case lists:keyfind(plugins, 1, Conf) of + false -> ok; + {_, Plugins0} -> + Plugins = [P || P <- Plugins0, is_atom(P)], + [begin + case lists:keyfind(deps, 1, Conf) of + false -> ok; + {_, Deps} -> + case lists:keyfind(P, 1, Deps) of + false -> ok; + _ -> + Path = "$(call core_native_path,$(DEPS_DIR)/)" ++ atom_to_list(P), + io:format("~s", [os:cmd("$(MAKE) -C $(call core_native_path,$(DEPS_DIR)/$1) " ++ Path)]), + io:format("~s", [os:cmd("$(MAKE) -C " ++ Path ++ " IS_DEP=1")]), + code:add_patha(Path ++ "/ebin") + end + end + end || P <- Plugins], + [case code:load_file(P) of + {module, P} -> ok; + _ -> + case lists:keyfind(plugin_dir, 1, Conf) of + false -> ok; + {_, PluginsDir} -> + ErlFile = "$(call core_native_path,$(DEPS_DIR)/$1/)" ++ PluginsDir ++ "/" ++ atom_to_list(P) ++ ".erl", + {ok, P, Bin} = compile:file(ErlFile, [binary]), + {module, P} = code:load_binary(P, ErlFile, Bin) + end + end || P <- Plugins], + [RunPlugin(P, preprocess) || P <- Plugins], + [RunPlugin(P, pre_compile) || P <- Plugins], + [RunPlugin(P, compile) || P <- Plugins] + end + end(), + halt() +endef + +define dep_autopatch_appsrc_script.erl + AppSrc = "$(call core_native_path,$(DEPS_DIR)/$1/src/$1.app.src)", + AppSrcScript = AppSrc ++ ".script", + {ok, Conf0} = file:consult(AppSrc), + Bindings0 = erl_eval:new_bindings(), + Bindings1 = erl_eval:add_binding('CONFIG', Conf0, Bindings0), + Bindings = erl_eval:add_binding('SCRIPT', AppSrcScript, Bindings1), + Conf = case file:script(AppSrcScript, Bindings) of + {ok, [C]} -> C; + {ok, C} -> C + end, + ok = file:write_file(AppSrc, io_lib:format("~p.~n", [Conf])), + halt() +endef + +define dep_autopatch_appsrc.erl + AppSrcOut = "$(call core_native_path,$(DEPS_DIR)/$1/src/$1.app.src)", + AppSrcIn = case filelib:is_regular(AppSrcOut) of false -> "$(call core_native_path,$(DEPS_DIR)/$1/ebin/$1.app)"; true -> AppSrcOut end, + case filelib:is_regular(AppSrcIn) of + false -> ok; + true -> + {ok, [{application, $(1), L0}]} = file:consult(AppSrcIn), + L1 = lists:keystore(modules, 1, L0, {modules, []}), + L2 = case lists:keyfind(vsn, 1, L1) of + {_, git} -> lists:keyreplace(vsn, 1, L1, {vsn, lists:droplast(os:cmd("git -C $(DEPS_DIR)/$1 describe --dirty --tags --always"))}); + {_, {cmd, _}} -> lists:keyreplace(vsn, 1, L1, {vsn, "cmd"}); + _ -> L1 + end, + L3 = case lists:keyfind(registered, 1, L2) of false -> [{registered, []}|L2]; _ -> L2 end, + ok = file:write_file(AppSrcOut, io_lib:format("~p.~n", [{application, $(1), L3}])), + case AppSrcOut of AppSrcIn -> ok; _ -> ok = file:delete(AppSrcIn) end + end, + halt() +endef + +define dep_fetch_git + git clone -q -n -- $(call dep_repo,$(1)) $(DEPS_DIR)/$(call dep_name,$(1)); \ + cd $(DEPS_DIR)/$(call dep_name,$(1)) && git checkout -q $(call dep_commit,$(1)); +endef + +define dep_fetch_git-subfolder + mkdir -p $(ERLANG_MK_TMP)/git-subfolder; \ + git clone -q -n -- $(call dep_repo,$1) \ + $(ERLANG_MK_TMP)/git-subfolder/$(call dep_name,$1); \ + cd $(ERLANG_MK_TMP)/git-subfolder/$(call dep_name,$1) \ + && git checkout -q $(call dep_commit,$1); \ + ln -s $(ERLANG_MK_TMP)/git-subfolder/$(call dep_name,$1)/$(word 4,$(dep_$(1))) \ + $(DEPS_DIR)/$(call dep_name,$1); +endef + +define dep_fetch_git-submodule + git submodule update --init -- $(DEPS_DIR)/$1; +endef + +define dep_fetch_hg + hg clone -q -U $(call dep_repo,$(1)) $(DEPS_DIR)/$(call dep_name,$(1)); \ + cd $(DEPS_DIR)/$(call dep_name,$(1)) && hg update -q $(call dep_commit,$(1)); +endef + +define dep_fetch_svn + svn checkout -q $(call dep_repo,$(1)) $(DEPS_DIR)/$(call dep_name,$(1)); +endef + +define dep_fetch_cp + cp -R $(call dep_repo,$(1)) $(DEPS_DIR)/$(call dep_name,$(1)); +endef + +define dep_fetch_ln + ln -s $(call dep_repo,$(1)) $(DEPS_DIR)/$(call dep_name,$(1)); +endef + +# Hex only has a package version. No need to look in the Erlang.mk packages. +define dep_fetch_hex + mkdir -p $(ERLANG_MK_TMP)/hex $(DEPS_DIR)/$1; \ + $(call core_http_get,$(ERLANG_MK_TMP)/hex/$1.tar,\ + https://repo.hex.pm/tarballs/$(if $(word 3,$(dep_$1)),$(word 3,$(dep_$1)),$1)-$(strip $(word 2,$(dep_$1))).tar); \ + tar -xOf $(ERLANG_MK_TMP)/hex/$1.tar contents.tar.gz | tar -C $(DEPS_DIR)/$1 -xzf -; +endef + +define dep_fetch_fail + echo "Error: Unknown or invalid dependency: $(1)." >&2; \ + exit 78; +endef + +# Kept for compatibility purposes with older Erlang.mk configuration. +define dep_fetch_legacy + $(warning WARNING: '$(1)' dependency configuration uses deprecated format.) \ + git clone -q -n -- $(word 1,$(dep_$(1))) $(DEPS_DIR)/$(1); \ + cd $(DEPS_DIR)/$(1) && git checkout -q $(if $(word 2,$(dep_$(1))),$(word 2,$(dep_$(1))),master); +endef + +define dep_target +$(DEPS_DIR)/$(call dep_name,$1): | $(ERLANG_MK_TMP) + $(eval DEP_NAME := $(call dep_name,$1)) + $(eval DEP_STR := $(if $(filter $1,$(DEP_NAME)),$1,"$1 ($(DEP_NAME))")) + $(verbose) if test -d $(APPS_DIR)/$(DEP_NAME); then \ + echo "Error: Dependency" $(DEP_STR) "conflicts with application found in $(APPS_DIR)/$(DEP_NAME)." >&2; \ + exit 17; \ + fi + $(verbose) mkdir -p $(DEPS_DIR) + $(dep_verbose) $(call dep_fetch_$(strip $(call dep_fetch,$(1))),$(1)) + $(verbose) if [ -f $(DEPS_DIR)/$(1)/configure.ac -o -f $(DEPS_DIR)/$(1)/configure.in ] \ + && [ ! -f $(DEPS_DIR)/$(1)/configure ]; then \ + echo " AUTO " $(DEP_STR); \ + cd $(DEPS_DIR)/$(1) && autoreconf -Wall -vif -I m4; \ + fi + - $(verbose) if [ -f $(DEPS_DIR)/$(DEP_NAME)/configure ]; then \ + echo " CONF " $(DEP_STR); \ + cd $(DEPS_DIR)/$(DEP_NAME) && ./configure; \ + fi +ifeq ($(filter $(1),$(NO_AUTOPATCH)),) + $(verbose) $$(MAKE) --no-print-directory autopatch-$(DEP_NAME) +endif + +.PHONY: autopatch-$(call dep_name,$1) + +autopatch-$(call dep_name,$1):: + $(verbose) if [ "$(1)" = "amqp_client" -a "$(RABBITMQ_CLIENT_PATCH)" ]; then \ + if [ ! -d $(DEPS_DIR)/rabbitmq-codegen ]; then \ + echo " PATCH Downloading rabbitmq-codegen"; \ + git clone https://github.com/rabbitmq/rabbitmq-codegen.git $(DEPS_DIR)/rabbitmq-codegen; \ + fi; \ + if [ ! -d $(DEPS_DIR)/rabbitmq-server ]; then \ + echo " PATCH Downloading rabbitmq-server"; \ + git clone https://github.com/rabbitmq/rabbitmq-server.git $(DEPS_DIR)/rabbitmq-server; \ + fi; \ + ln -s $(DEPS_DIR)/amqp_client/deps/rabbit_common-0.0.0 $(DEPS_DIR)/rabbit_common; \ + elif [ "$(1)" = "rabbit" -a "$(RABBITMQ_SERVER_PATCH)" ]; then \ + if [ ! -d $(DEPS_DIR)/rabbitmq-codegen ]; then \ + echo " PATCH Downloading rabbitmq-codegen"; \ + git clone https://github.com/rabbitmq/rabbitmq-codegen.git $(DEPS_DIR)/rabbitmq-codegen; \ + fi \ + elif [ "$1" = "elixir" -a "$(ELIXIR_PATCH)" ]; then \ + ln -s lib/elixir/ebin $(DEPS_DIR)/elixir/; \ + else \ + $$(call dep_autopatch,$(call dep_name,$1)) \ + fi +endef + +$(foreach dep,$(BUILD_DEPS) $(DEPS),$(eval $(call dep_target,$(dep)))) + +ifndef IS_APP +clean:: clean-apps + +clean-apps: + $(verbose) set -e; for dep in $(ALL_APPS_DIRS) ; do \ + $(MAKE) -C $$dep clean IS_APP=1; \ + done + +distclean:: distclean-apps + +distclean-apps: + $(verbose) set -e; for dep in $(ALL_APPS_DIRS) ; do \ + $(MAKE) -C $$dep distclean IS_APP=1; \ + done +endif + +ifndef SKIP_DEPS +distclean:: distclean-deps + +distclean-deps: + $(gen_verbose) rm -rf $(DEPS_DIR) +endif + +# Forward-declare variables used in core/deps-tools.mk. This is required +# in case plugins use them. + +ERLANG_MK_RECURSIVE_DEPS_LIST = $(ERLANG_MK_TMP)/recursive-deps-list.log +ERLANG_MK_RECURSIVE_DOC_DEPS_LIST = $(ERLANG_MK_TMP)/recursive-doc-deps-list.log +ERLANG_MK_RECURSIVE_REL_DEPS_LIST = $(ERLANG_MK_TMP)/recursive-rel-deps-list.log +ERLANG_MK_RECURSIVE_TEST_DEPS_LIST = $(ERLANG_MK_TMP)/recursive-test-deps-list.log +ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST = $(ERLANG_MK_TMP)/recursive-shell-deps-list.log + +ERLANG_MK_QUERY_DEPS_FILE = $(ERLANG_MK_TMP)/query-deps.log +ERLANG_MK_QUERY_DOC_DEPS_FILE = $(ERLANG_MK_TMP)/query-doc-deps.log +ERLANG_MK_QUERY_REL_DEPS_FILE = $(ERLANG_MK_TMP)/query-rel-deps.log +ERLANG_MK_QUERY_TEST_DEPS_FILE = $(ERLANG_MK_TMP)/query-test-deps.log +ERLANG_MK_QUERY_SHELL_DEPS_FILE = $(ERLANG_MK_TMP)/query-shell-deps.log + +# Copyright (c) 2013-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: clean-app + +# Configuration. + +ERLC_OPTS ?= -Werror +debug_info +warn_export_vars +warn_shadow_vars \ + +warn_obsolete_guard # +bin_opt_info +warn_export_all +warn_missing_spec +COMPILE_FIRST ?= +COMPILE_FIRST_PATHS = $(addprefix src/,$(addsuffix .erl,$(COMPILE_FIRST))) +ERLC_EXCLUDE ?= +ERLC_EXCLUDE_PATHS = $(addprefix src/,$(addsuffix .erl,$(ERLC_EXCLUDE))) + +ERLC_ASN1_OPTS ?= + +ERLC_MIB_OPTS ?= +COMPILE_MIB_FIRST ?= +COMPILE_MIB_FIRST_PATHS = $(addprefix mibs/,$(addsuffix .mib,$(COMPILE_MIB_FIRST))) + +# Verbosity. + +app_verbose_0 = @echo " APP " $(PROJECT); +app_verbose_2 = set -x; +app_verbose = $(app_verbose_$(V)) + +appsrc_verbose_0 = @echo " APP " $(PROJECT).app.src; +appsrc_verbose_2 = set -x; +appsrc_verbose = $(appsrc_verbose_$(V)) + +makedep_verbose_0 = @echo " DEPEND" $(PROJECT).d; +makedep_verbose_2 = set -x; +makedep_verbose = $(makedep_verbose_$(V)) + +erlc_verbose_0 = @echo " ERLC " $(filter-out $(patsubst %,%.erl,$(ERLC_EXCLUDE)),\ + $(filter %.erl %.core,$(?F))); +erlc_verbose_2 = set -x; +erlc_verbose = $(erlc_verbose_$(V)) + +xyrl_verbose_0 = @echo " XYRL " $(filter %.xrl %.yrl,$(?F)); +xyrl_verbose_2 = set -x; +xyrl_verbose = $(xyrl_verbose_$(V)) + +asn1_verbose_0 = @echo " ASN1 " $(filter %.asn1,$(?F)); +asn1_verbose_2 = set -x; +asn1_verbose = $(asn1_verbose_$(V)) + +mib_verbose_0 = @echo " MIB " $(filter %.bin %.mib,$(?F)); +mib_verbose_2 = set -x; +mib_verbose = $(mib_verbose_$(V)) + +ifneq ($(wildcard src/),) + +# Targets. + +app:: $(if $(wildcard ebin/test),clean) deps + $(verbose) $(MAKE) --no-print-directory $(PROJECT).d + $(verbose) $(MAKE) --no-print-directory app-build + +ifeq ($(wildcard src/$(PROJECT_MOD).erl),) +define app_file +{application, '$(PROJECT)', [ + {description, "$(PROJECT_DESCRIPTION)"}, + {vsn, "$(PROJECT_VERSION)"},$(if $(IS_DEP), + {id$(comma)$(space)"$(1)"}$(comma)) + {modules, [$(call comma_list,$(2))]}, + {registered, []}, + {applications, [$(call comma_list,kernel stdlib $(OTP_DEPS) $(LOCAL_DEPS) $(foreach dep,$(DEPS),$(call dep_name,$(dep))))]}, + {env, $(subst \,\\,$(PROJECT_ENV))}$(if $(findstring {,$(PROJECT_APP_EXTRA_KEYS)),$(comma)$(newline)$(tab)$(subst \,\\,$(PROJECT_APP_EXTRA_KEYS)),) +]}. +endef +else +define app_file +{application, '$(PROJECT)', [ + {description, "$(PROJECT_DESCRIPTION)"}, + {vsn, "$(PROJECT_VERSION)"},$(if $(IS_DEP), + {id$(comma)$(space)"$(1)"}$(comma)) + {modules, [$(call comma_list,$(2))]}, + {registered, [$(call comma_list,$(PROJECT)_sup $(PROJECT_REGISTERED))]}, + {applications, [$(call comma_list,kernel stdlib $(OTP_DEPS) $(LOCAL_DEPS) $(foreach dep,$(DEPS),$(call dep_name,$(dep))))]}, + {mod, {$(PROJECT_MOD), []}}, + {env, $(subst \,\\,$(PROJECT_ENV))}$(if $(findstring {,$(PROJECT_APP_EXTRA_KEYS)),$(comma)$(newline)$(tab)$(subst \,\\,$(PROJECT_APP_EXTRA_KEYS)),) +]}. +endef +endif + +app-build: ebin/$(PROJECT).app + $(verbose) : + +# Source files. + +ALL_SRC_FILES := $(sort $(call core_find,src/,*)) + +ERL_FILES := $(filter %.erl,$(ALL_SRC_FILES)) +CORE_FILES := $(filter %.core,$(ALL_SRC_FILES)) + +# ASN.1 files. + +ifneq ($(wildcard asn1/),) +ASN1_FILES = $(sort $(call core_find,asn1/,*.asn1)) +ERL_FILES += $(addprefix src/,$(patsubst %.asn1,%.erl,$(notdir $(ASN1_FILES)))) + +define compile_asn1 + $(verbose) mkdir -p include/ + $(asn1_verbose) erlc -v -I include/ -o asn1/ +noobj $(ERLC_ASN1_OPTS) $(1) + $(verbose) mv asn1/*.erl src/ + -$(verbose) mv asn1/*.hrl include/ + $(verbose) mv asn1/*.asn1db include/ +endef + +$(PROJECT).d:: $(ASN1_FILES) + $(if $(strip $?),$(call compile_asn1,$?)) +endif + +# SNMP MIB files. + +ifneq ($(wildcard mibs/),) +MIB_FILES = $(sort $(call core_find,mibs/,*.mib)) + +$(PROJECT).d:: $(COMPILE_MIB_FIRST_PATHS) $(MIB_FILES) + $(verbose) mkdir -p include/ priv/mibs/ + $(mib_verbose) erlc -v $(ERLC_MIB_OPTS) -o priv/mibs/ -I priv/mibs/ $? + $(mib_verbose) erlc -o include/ -- $(addprefix priv/mibs/,$(patsubst %.mib,%.bin,$(notdir $?))) +endif + +# Leex and Yecc files. + +XRL_FILES := $(filter %.xrl,$(ALL_SRC_FILES)) +XRL_ERL_FILES = $(addprefix src/,$(patsubst %.xrl,%.erl,$(notdir $(XRL_FILES)))) +ERL_FILES += $(XRL_ERL_FILES) + +YRL_FILES := $(filter %.yrl,$(ALL_SRC_FILES)) +YRL_ERL_FILES = $(addprefix src/,$(patsubst %.yrl,%.erl,$(notdir $(YRL_FILES)))) +ERL_FILES += $(YRL_ERL_FILES) + +$(PROJECT).d:: $(XRL_FILES) $(YRL_FILES) + $(if $(strip $?),$(xyrl_verbose) erlc -v -o src/ $(YRL_ERLC_OPTS) $?) + +# Erlang and Core Erlang files. + +define makedep.erl + E = ets:new(makedep, [bag]), + G = digraph:new([acyclic]), + ErlFiles = lists:usort(string:tokens("$(ERL_FILES)", " ")), + DepsDir = "$(call core_native_path,$(DEPS_DIR))", + AppsDir = "$(call core_native_path,$(APPS_DIR))", + DepsDirsSrc = "$(if $(wildcard $(DEPS_DIR)/*/src), $(call core_native_path,$(wildcard $(DEPS_DIR)/*/src)))", + DepsDirsInc = "$(if $(wildcard $(DEPS_DIR)/*/include), $(call core_native_path,$(wildcard $(DEPS_DIR)/*/include)))", + AppsDirsSrc = "$(if $(wildcard $(APPS_DIR)/*/src), $(call core_native_path,$(wildcard $(APPS_DIR)/*/src)))", + AppsDirsInc = "$(if $(wildcard $(APPS_DIR)/*/include), $(call core_native_path,$(wildcard $(APPS_DIR)/*/include)))", + DepsDirs = lists:usort(string:tokens(DepsDirsSrc++DepsDirsInc, " ")), + AppsDirs = lists:usort(string:tokens(AppsDirsSrc++AppsDirsInc, " ")), + Modules = [{list_to_atom(filename:basename(F, ".erl")), F} || F <- ErlFiles], + Add = fun (Mod, Dep) -> + case lists:keyfind(Dep, 1, Modules) of + false -> ok; + {_, DepFile} -> + {_, ModFile} = lists:keyfind(Mod, 1, Modules), + ets:insert(E, {ModFile, DepFile}), + digraph:add_vertex(G, Mod), + digraph:add_vertex(G, Dep), + digraph:add_edge(G, Mod, Dep) + end + end, + AddHd = fun (F, Mod, DepFile) -> + case file:open(DepFile, [read]) of + {error, enoent} -> + ok; + {ok, Fd} -> + {_, ModFile} = lists:keyfind(Mod, 1, Modules), + case ets:match(E, {ModFile, DepFile}) of + [] -> + ets:insert(E, {ModFile, DepFile}), + F(F, Fd, Mod,0); + _ -> ok + end + end + end, + SearchHrl = fun + F(_Hrl, []) -> {error,enoent}; + F(Hrl, [Dir|Dirs]) -> + HrlF = filename:join([Dir,Hrl]), + case filelib:is_file(HrlF) of + true -> + {ok, HrlF}; + false -> F(Hrl,Dirs) + end + end, + Attr = fun + (_F, Mod, behavior, Dep) -> + Add(Mod, Dep); + (_F, Mod, behaviour, Dep) -> + Add(Mod, Dep); + (_F, Mod, compile, {parse_transform, Dep}) -> + Add(Mod, Dep); + (_F, Mod, compile, Opts) when is_list(Opts) -> + case proplists:get_value(parse_transform, Opts) of + undefined -> ok; + Dep -> Add(Mod, Dep) + end; + (F, Mod, include, Hrl) -> + case SearchHrl(Hrl, ["src", "include",AppsDir,DepsDir]++AppsDirs++DepsDirs) of + {ok, FoundHrl} -> AddHd(F, Mod, FoundHrl); + {error, _} -> false + end; + (F, Mod, include_lib, Hrl) -> + case SearchHrl(Hrl, ["src", "include",AppsDir,DepsDir]++AppsDirs++DepsDirs) of + {ok, FoundHrl} -> AddHd(F, Mod, FoundHrl); + {error, _} -> false + end; + (F, Mod, import, {Imp, _}) -> + IsFile = + case lists:keyfind(Imp, 1, Modules) of + false -> false; + {_, FilePath} -> filelib:is_file(FilePath) + end, + case IsFile of + false -> ok; + true -> Add(Mod, Imp) + end; + (_, _, _, _) -> ok + end, + MakeDepend = fun + (F, Fd, Mod, StartLocation) -> + {ok, Filename} = file:pid2name(Fd), + case io:parse_erl_form(Fd, undefined, StartLocation) of + {ok, AbsData, EndLocation} -> + case AbsData of + {attribute, _, Key, Value} -> + Attr(F, Mod, Key, Value), + F(F, Fd, Mod, EndLocation); + _ -> F(F, Fd, Mod, EndLocation) + end; + {eof, _ } -> file:close(Fd); + {error, ErrorDescription } -> + file:close(Fd); + {error, ErrorInfo, ErrorLocation} -> + F(F, Fd, Mod, ErrorLocation) + end, + ok + end, + [begin + Mod = list_to_atom(filename:basename(F, ".erl")), + case file:open(F, [read]) of + {ok, Fd} -> MakeDepend(MakeDepend, Fd, Mod,0); + {error, enoent} -> ok + end + end || F <- ErlFiles], + Depend = sofs:to_external(sofs:relation_to_family(sofs:relation(ets:tab2list(E)))), + CompileFirst = [X || X <- lists:reverse(digraph_utils:topsort(G)), [] =/= digraph:in_neighbours(G, X)], + TargetPath = fun(Target) -> + case lists:keyfind(Target, 1, Modules) of + false -> ""; + {_, DepFile} -> + DirSubname = tl(string:tokens(filename:dirname(DepFile), "/")), + string:join(DirSubname ++ [atom_to_list(Target)], "/") + end + end, + Output0 = [ + "# Generated by Erlang.mk. Edit at your own risk!\n\n", + [[F, "::", [[" ", D] || D <- Deps], "; @touch \$$@\n"] || {F, Deps} <- Depend], + "\nCOMPILE_FIRST +=", [[" ", TargetPath(CF)] || CF <- CompileFirst], "\n" + ], + Output = case "é" of + [233] -> unicode:characters_to_binary(Output0); + _ -> Output0 + end, + ok = file:write_file("$(1)", Output), + halt() +endef + +ifeq ($(if $(NO_MAKEDEP),$(wildcard $(PROJECT).d),),) +$(PROJECT).d:: $(ERL_FILES) $(call core_find,include/,*.hrl) $(MAKEFILE_LIST) + $(makedep_verbose) $(call erlang,$(call makedep.erl,$@)) +endif + +ifeq ($(IS_APP)$(IS_DEP),) +ifneq ($(words $(ERL_FILES) $(CORE_FILES) $(ASN1_FILES) $(MIB_FILES) $(XRL_FILES) $(YRL_FILES)),0) +# Rebuild everything when the Makefile changes. +$(ERLANG_MK_TMP)/last-makefile-change: $(MAKEFILE_LIST) | $(ERLANG_MK_TMP) + $(verbose) if test -f $@; then \ + touch $(ERL_FILES) $(CORE_FILES) $(ASN1_FILES) $(MIB_FILES) $(XRL_FILES) $(YRL_FILES); \ + touch -c $(PROJECT).d; \ + fi + $(verbose) touch $@ + +$(ERL_FILES) $(CORE_FILES) $(ASN1_FILES) $(MIB_FILES) $(XRL_FILES) $(YRL_FILES):: $(ERLANG_MK_TMP)/last-makefile-change +ebin/$(PROJECT).app:: $(ERLANG_MK_TMP)/last-makefile-change +endif +endif + +$(PROJECT).d:: + $(verbose) : + +include $(wildcard $(PROJECT).d) + +ebin/$(PROJECT).app:: ebin/ + +ebin/: + $(verbose) mkdir -p ebin/ + +define compile_erl + $(erlc_verbose) erlc -v $(if $(IS_DEP),$(filter-out -Werror,$(ERLC_OPTS)),$(ERLC_OPTS)) -o ebin/ \ + -pa ebin/ -I include/ $(filter-out $(ERLC_EXCLUDE_PATHS),$(COMPILE_FIRST_PATHS) $(1)) +endef + +define validate_app_file + case file:consult("ebin/$(PROJECT).app") of + {ok, _} -> halt(); + _ -> halt(1) + end +endef + +ebin/$(PROJECT).app:: $(ERL_FILES) $(CORE_FILES) $(wildcard src/$(PROJECT).app.src) + $(eval FILES_TO_COMPILE := $(filter-out src/$(PROJECT).app.src,$?)) + $(if $(strip $(FILES_TO_COMPILE)),$(call compile_erl,$(FILES_TO_COMPILE))) +# Older git versions do not have the --first-parent flag. Do without in that case. + $(eval GITDESCRIBE := $(shell git describe --dirty --abbrev=7 --tags --always --first-parent 2>/dev/null \ + || git describe --dirty --abbrev=7 --tags --always 2>/dev/null || true)) + $(eval MODULES := $(patsubst %,'%',$(sort $(notdir $(basename \ + $(filter-out $(ERLC_EXCLUDE_PATHS),$(ERL_FILES) $(CORE_FILES) $(BEAM_FILES))))))) +ifeq ($(wildcard src/$(PROJECT).app.src),) + $(app_verbose) printf '$(subst %,%%,$(subst $(newline),\n,$(subst ','\'',$(call app_file,$(GITDESCRIBE),$(MODULES)))))' \ + > ebin/$(PROJECT).app + $(verbose) if ! $(call erlang,$(call validate_app_file)); then \ + echo "The .app file produced is invalid. Please verify the value of PROJECT_ENV." >&2; \ + exit 1; \ + fi +else + $(verbose) if [ -z "$$(grep -e '^[^%]*{\s*modules\s*,' src/$(PROJECT).app.src)" ]; then \ + echo "Empty modules entry not found in $(PROJECT).app.src. Please consult the erlang.mk documentation for instructions." >&2; \ + exit 1; \ + fi + $(appsrc_verbose) cat src/$(PROJECT).app.src \ + | sed "s/{[[:space:]]*modules[[:space:]]*,[[:space:]]*\[\]}/{modules, \[$(call comma_list,$(MODULES))\]}/" \ + | sed "s/{id,[[:space:]]*\"git\"}/{id, \"$(subst /,\/,$(GITDESCRIBE))\"}/" \ + > ebin/$(PROJECT).app +endif +ifneq ($(wildcard src/$(PROJECT).appup),) + $(verbose) cp src/$(PROJECT).appup ebin/ +endif + +clean:: clean-app + +clean-app: + $(gen_verbose) rm -rf $(PROJECT).d ebin/ priv/mibs/ $(XRL_ERL_FILES) $(YRL_ERL_FILES) \ + $(addprefix include/,$(patsubst %.mib,%.hrl,$(notdir $(MIB_FILES)))) \ + $(addprefix include/,$(patsubst %.asn1,%.hrl,$(notdir $(ASN1_FILES)))) \ + $(addprefix include/,$(patsubst %.asn1,%.asn1db,$(notdir $(ASN1_FILES)))) \ + $(addprefix src/,$(patsubst %.asn1,%.erl,$(notdir $(ASN1_FILES)))) + +endif + +# Copyright (c) 2016, Loïc Hoguin +# Copyright (c) 2015, Viktor Söderqvist +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: docs-deps + +# Configuration. + +ALL_DOC_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(DOC_DEPS)) + +# Targets. + +$(foreach dep,$(DOC_DEPS),$(eval $(call dep_target,$(dep)))) + +ifneq ($(SKIP_DEPS),) +doc-deps: +else +doc-deps: $(ALL_DOC_DEPS_DIRS) + $(verbose) set -e; for dep in $(ALL_DOC_DEPS_DIRS) ; do $(MAKE) -C $$dep IS_DEP=1; done +endif + +# Copyright (c) 2015-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: rel-deps + +# Configuration. + +ALL_REL_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(REL_DEPS)) + +# Targets. + +$(foreach dep,$(REL_DEPS),$(eval $(call dep_target,$(dep)))) + +ifneq ($(SKIP_DEPS),) +rel-deps: +else +rel-deps: $(ALL_REL_DEPS_DIRS) + $(verbose) set -e; for dep in $(ALL_REL_DEPS_DIRS) ; do $(MAKE) -C $$dep; done +endif + +# Copyright (c) 2015-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: test-deps test-dir test-build clean-test-dir + +# Configuration. + +TEST_DIR ?= $(CURDIR)/test + +ALL_TEST_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(TEST_DEPS)) + +TEST_ERLC_OPTS ?= +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard +TEST_ERLC_OPTS += -DTEST=1 + +# Targets. + +$(foreach dep,$(TEST_DEPS),$(eval $(call dep_target,$(dep)))) + +ifneq ($(SKIP_DEPS),) +test-deps: +else +test-deps: $(ALL_TEST_DEPS_DIRS) + $(verbose) set -e; for dep in $(ALL_TEST_DEPS_DIRS) ; do \ + if [ -z "$(strip $(FULL))" ] && [ ! -L $$dep ] && [ -f $$dep/ebin/dep_built ]; then \ + :; \ + else \ + $(MAKE) -C $$dep IS_DEP=1; \ + if [ ! -L $$dep ] && [ -d $$dep/ebin ]; then touch $$dep/ebin/dep_built; fi; \ + fi \ + done +endif + +ifneq ($(wildcard $(TEST_DIR)),) +test-dir: $(ERLANG_MK_TMP)/$(PROJECT).last-testdir-build + @: + +test_erlc_verbose_0 = @echo " ERLC " $(filter-out $(patsubst %,%.erl,$(ERLC_EXCLUDE)),\ + $(filter %.erl %.core,$(notdir $(FILES_TO_COMPILE)))); +test_erlc_verbose_2 = set -x; +test_erlc_verbose = $(test_erlc_verbose_$(V)) + +define compile_test_erl + $(test_erlc_verbose) erlc -v $(TEST_ERLC_OPTS) -o $(TEST_DIR) \ + -pa ebin/ -I include/ $(1) +endef + +ERL_TEST_FILES = $(call core_find,$(TEST_DIR)/,*.erl) +$(ERLANG_MK_TMP)/$(PROJECT).last-testdir-build: $(ERL_TEST_FILES) $(MAKEFILE_LIST) + $(eval FILES_TO_COMPILE := $(if $(filter $(MAKEFILE_LIST),$?),$(filter $(ERL_TEST_FILES),$^),$?)) + $(if $(strip $(FILES_TO_COMPILE)),$(call compile_test_erl,$(FILES_TO_COMPILE)) && touch $@) +endif + +test-build:: IS_TEST=1 +test-build:: ERLC_OPTS=$(TEST_ERLC_OPTS) +test-build:: $(if $(wildcard src),$(if $(wildcard ebin/test),,clean)) $(if $(IS_APP),,deps test-deps) +# We already compiled everything when IS_APP=1. +ifndef IS_APP +ifneq ($(wildcard src),) + $(verbose) $(MAKE) --no-print-directory $(PROJECT).d ERLC_OPTS="$(call escape_dquotes,$(TEST_ERLC_OPTS))" + $(verbose) $(MAKE) --no-print-directory app-build ERLC_OPTS="$(call escape_dquotes,$(TEST_ERLC_OPTS))" + $(gen_verbose) touch ebin/test +endif +ifneq ($(wildcard $(TEST_DIR)),) + $(verbose) $(MAKE) --no-print-directory test-dir ERLC_OPTS="$(call escape_dquotes,$(TEST_ERLC_OPTS))" +endif +endif + +# Roughly the same as test-build, but when IS_APP=1. +# We only care about compiling the current application. +ifdef IS_APP +test-build-app:: ERLC_OPTS=$(TEST_ERLC_OPTS) +test-build-app:: deps test-deps +ifneq ($(wildcard src),) + $(verbose) $(MAKE) --no-print-directory $(PROJECT).d ERLC_OPTS="$(call escape_dquotes,$(TEST_ERLC_OPTS))" + $(verbose) $(MAKE) --no-print-directory app-build ERLC_OPTS="$(call escape_dquotes,$(TEST_ERLC_OPTS))" + $(gen_verbose) touch ebin/test +endif +ifneq ($(wildcard $(TEST_DIR)),) + $(verbose) $(MAKE) --no-print-directory test-dir ERLC_OPTS="$(call escape_dquotes,$(TEST_ERLC_OPTS))" +endif +endif + +clean:: clean-test-dir + +clean-test-dir: +ifneq ($(wildcard $(TEST_DIR)/*.beam),) + $(gen_verbose) rm -f $(TEST_DIR)/*.beam $(ERLANG_MK_TMP)/$(PROJECT).last-testdir-build +endif + +# Copyright (c) 2015-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: rebar.config + +# We strip out -Werror because we don't want to fail due to +# warnings when used as a dependency. + +compat_prepare_erlc_opts = $(shell echo "$1" | sed 's/, */,/g') + +define compat_convert_erlc_opts +$(if $(filter-out -Werror,$1),\ + $(if $(findstring +,$1),\ + $(shell echo $1 | cut -b 2-))) +endef + +define compat_erlc_opts_to_list +[$(call comma_list,$(foreach o,$(call compat_prepare_erlc_opts,$1),$(call compat_convert_erlc_opts,$o)))] +endef + +define compat_rebar_config +{deps, [ +$(call comma_list,$(foreach d,$(DEPS),\ + $(if $(filter hex,$(call dep_fetch,$d)),\ + {$(call dep_name,$d)$(comma)"$(call dep_repo,$d)"},\ + {$(call dep_name,$d)$(comma)".*"$(comma){git,"$(call dep_repo,$d)"$(comma)"$(call dep_commit,$d)"}}))) +]}. +{erl_opts, $(call compat_erlc_opts_to_list,$(ERLC_OPTS))}. +endef + +rebar.config: + $(gen_verbose) $(call core_render,compat_rebar_config,rebar.config) + +# Copyright (c) 2015-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +ifeq ($(filter asciideck,$(DEPS) $(DOC_DEPS)),asciideck) + +.PHONY: asciidoc asciidoc-guide asciidoc-manual install-asciidoc distclean-asciidoc-guide distclean-asciidoc-manual + +# Core targets. + +docs:: asciidoc + +distclean:: distclean-asciidoc-guide distclean-asciidoc-manual + +# Plugin-specific targets. + +asciidoc: asciidoc-guide asciidoc-manual + +# User guide. + +ifeq ($(wildcard doc/src/guide/book.asciidoc),) +asciidoc-guide: +else +asciidoc-guide: distclean-asciidoc-guide doc-deps + a2x -v -f pdf doc/src/guide/book.asciidoc && mv doc/src/guide/book.pdf doc/guide.pdf + a2x -v -f chunked doc/src/guide/book.asciidoc && mv doc/src/guide/book.chunked/ doc/html/ + +distclean-asciidoc-guide: + $(gen_verbose) rm -rf doc/html/ doc/guide.pdf +endif + +# Man pages. + +ASCIIDOC_MANUAL_FILES := $(wildcard doc/src/manual/*.asciidoc) + +ifeq ($(ASCIIDOC_MANUAL_FILES),) +asciidoc-manual: +else + +# Configuration. + +MAN_INSTALL_PATH ?= /usr/local/share/man +MAN_SECTIONS ?= 3 7 +MAN_PROJECT ?= $(shell echo $(PROJECT) | sed 's/^./\U&\E/') +MAN_VERSION ?= $(PROJECT_VERSION) + +# Plugin-specific targets. + +define asciidoc2man.erl +try + [begin + io:format(" ADOC ~s~n", [F]), + ok = asciideck:to_manpage(asciideck:parse_file(F), #{ + compress => gzip, + outdir => filename:dirname(F), + extra2 => "$(MAN_PROJECT) $(MAN_VERSION)", + extra3 => "$(MAN_PROJECT) Function Reference" + }) + end || F <- [$(shell echo $(addprefix $(comma)\",$(addsuffix \",$1)) | sed 's/^.//')]], + halt(0) +catch C:E -> + io:format("Exception ~p:~p~nStacktrace: ~p~n", [C, E, erlang:get_stacktrace()]), + halt(1) +end. +endef + +asciidoc-manual:: doc-deps + +asciidoc-manual:: $(ASCIIDOC_MANUAL_FILES) + $(gen_verbose) $(call erlang,$(call asciidoc2man.erl,$?)) + $(verbose) $(foreach s,$(MAN_SECTIONS),mkdir -p doc/man$s/ && mv doc/src/manual/*.$s.gz doc/man$s/;) + +install-docs:: install-asciidoc + +install-asciidoc: asciidoc-manual + $(foreach s,$(MAN_SECTIONS),\ + mkdir -p $(MAN_INSTALL_PATH)/man$s/ && \ + install -g `id -g` -o `id -u` -m 0644 doc/man$s/*.gz $(MAN_INSTALL_PATH)/man$s/;) + +distclean-asciidoc-manual: + $(gen_verbose) rm -rf $(addprefix doc/man,$(MAN_SECTIONS)) +endif +endif + +# Copyright (c) 2014-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: bootstrap bootstrap-lib bootstrap-rel new list-templates + +# Core targets. + +help:: + $(verbose) printf "%s\n" "" \ + "Bootstrap targets:" \ + " bootstrap Generate a skeleton of an OTP application" \ + " bootstrap-lib Generate a skeleton of an OTP library" \ + " bootstrap-rel Generate the files needed to build a release" \ + " new-app in=NAME Create a new local OTP application NAME" \ + " new-lib in=NAME Create a new local OTP library NAME" \ + " new t=TPL n=NAME Generate a module NAME based on the template TPL" \ + " new t=T n=N in=APP Generate a module NAME based on the template TPL in APP" \ + " list-templates List available templates" + +# Bootstrap templates. + +define bs_appsrc +{application, $p, [ + {description, ""}, + {vsn, "0.1.0"}, + {id, "git"}, + {modules, []}, + {registered, []}, + {applications, [ + kernel, + stdlib + ]}, + {mod, {$p_app, []}}, + {env, []} +]}. +endef + +define bs_appsrc_lib +{application, $p, [ + {description, ""}, + {vsn, "0.1.0"}, + {id, "git"}, + {modules, []}, + {registered, []}, + {applications, [ + kernel, + stdlib + ]} +]}. +endef + +# To prevent autocompletion issues with ZSH, we add "include erlang.mk" +# separately during the actual bootstrap. +define bs_Makefile +PROJECT = $p +PROJECT_DESCRIPTION = New project +PROJECT_VERSION = 0.1.0 +$(if $(SP), +# Whitespace to be used when creating files from templates. +SP = $(SP) +) +endef + +define bs_apps_Makefile +PROJECT = $p +PROJECT_DESCRIPTION = New project +PROJECT_VERSION = 0.1.0 +$(if $(SP), +# Whitespace to be used when creating files from templates. +SP = $(SP) +) +# Make sure we know where the applications are located. +ROOT_DIR ?= $(call core_relpath,$(dir $(ERLANG_MK_FILENAME)),$(APPS_DIR)/app) +APPS_DIR ?= .. +DEPS_DIR ?= $(call core_relpath,$(DEPS_DIR),$(APPS_DIR)/app) + +include $$(ROOT_DIR)/erlang.mk +endef + +define bs_app +-module($p_app). +-behaviour(application). + +-export([start/2]). +-export([stop/1]). + +start(_Type, _Args) -> + $p_sup:start_link(). + +stop(_State) -> + ok. +endef + +define bs_relx_config +{release, {$p_release, "1"}, [$p, sasl, runtime_tools]}. +{extended_start_script, true}. +{sys_config, "config/sys.config"}. +{vm_args, "config/vm.args"}. +endef + +define bs_sys_config +[ +]. +endef + +define bs_vm_args +-name $p@127.0.0.1 +-setcookie $p +-heart +endef + +# Normal templates. + +define tpl_supervisor +-module($(n)). +-behaviour(supervisor). + +-export([start_link/0]). +-export([init/1]). + +start_link() -> + supervisor:start_link({local, ?MODULE}, ?MODULE, []). + +init([]) -> + Procs = [], + {ok, {{one_for_one, 1, 5}, Procs}}. +endef + +define tpl_gen_server +-module($(n)). +-behaviour(gen_server). + +%% API. +-export([start_link/0]). + +%% gen_server. +-export([init/1]). +-export([handle_call/3]). +-export([handle_cast/2]). +-export([handle_info/2]). +-export([terminate/2]). +-export([code_change/3]). + +-record(state, { +}). + +%% API. + +-spec start_link() -> {ok, pid()}. +start_link() -> + gen_server:start_link(?MODULE, [], []). + +%% gen_server. + +init([]) -> + {ok, #state{}}. + +handle_call(_Request, _From, State) -> + {reply, ignored, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. +endef + +define tpl_module +-module($(n)). +-export([]). +endef + +define tpl_cowboy_http +-module($(n)). +-behaviour(cowboy_http_handler). + +-export([init/3]). +-export([handle/2]). +-export([terminate/3]). + +-record(state, { +}). + +init(_, Req, _Opts) -> + {ok, Req, #state{}}. + +handle(Req, State=#state{}) -> + {ok, Req2} = cowboy_req:reply(200, Req), + {ok, Req2, State}. + +terminate(_Reason, _Req, _State) -> + ok. +endef + +define tpl_gen_fsm +-module($(n)). +-behaviour(gen_fsm). + +%% API. +-export([start_link/0]). + +%% gen_fsm. +-export([init/1]). +-export([state_name/2]). +-export([handle_event/3]). +-export([state_name/3]). +-export([handle_sync_event/4]). +-export([handle_info/3]). +-export([terminate/3]). +-export([code_change/4]). + +-record(state, { +}). + +%% API. + +-spec start_link() -> {ok, pid()}. +start_link() -> + gen_fsm:start_link(?MODULE, [], []). + +%% gen_fsm. + +init([]) -> + {ok, state_name, #state{}}. + +state_name(_Event, StateData) -> + {next_state, state_name, StateData}. + +handle_event(_Event, StateName, StateData) -> + {next_state, StateName, StateData}. + +state_name(_Event, _From, StateData) -> + {reply, ignored, state_name, StateData}. + +handle_sync_event(_Event, _From, StateName, StateData) -> + {reply, ignored, StateName, StateData}. + +handle_info(_Info, StateName, StateData) -> + {next_state, StateName, StateData}. + +terminate(_Reason, _StateName, _StateData) -> + ok. + +code_change(_OldVsn, StateName, StateData, _Extra) -> + {ok, StateName, StateData}. +endef + +define tpl_gen_statem +-module($(n)). +-behaviour(gen_statem). + +%% API. +-export([start_link/0]). + +%% gen_statem. +-export([callback_mode/0]). +-export([init/1]). +-export([state_name/3]). +-export([handle_event/4]). +-export([terminate/3]). +-export([code_change/4]). + +-record(state, { +}). + +%% API. + +-spec start_link() -> {ok, pid()}. +start_link() -> + gen_statem:start_link(?MODULE, [], []). + +%% gen_statem. + +callback_mode() -> + state_functions. + +init([]) -> + {ok, state_name, #state{}}. + +state_name(_EventType, _EventData, StateData) -> + {next_state, state_name, StateData}. + +handle_event(_EventType, _EventData, StateName, StateData) -> + {next_state, StateName, StateData}. + +terminate(_Reason, _StateName, _StateData) -> + ok. + +code_change(_OldVsn, StateName, StateData, _Extra) -> + {ok, StateName, StateData}. +endef + +define tpl_cowboy_loop +-module($(n)). +-behaviour(cowboy_loop_handler). + +-export([init/3]). +-export([info/3]). +-export([terminate/3]). + +-record(state, { +}). + +init(_, Req, _Opts) -> + {loop, Req, #state{}, 5000, hibernate}. + +info(_Info, Req, State) -> + {loop, Req, State, hibernate}. + +terminate(_Reason, _Req, _State) -> + ok. +endef + +define tpl_cowboy_rest +-module($(n)). + +-export([init/3]). +-export([content_types_provided/2]). +-export([get_html/2]). + +init(_, _Req, _Opts) -> + {upgrade, protocol, cowboy_rest}. + +content_types_provided(Req, State) -> + {[{{<<"text">>, <<"html">>, '*'}, get_html}], Req, State}. + +get_html(Req, State) -> + {<<"This is REST!">>, Req, State}. +endef + +define tpl_cowboy_ws +-module($(n)). +-behaviour(cowboy_websocket_handler). + +-export([init/3]). +-export([websocket_init/3]). +-export([websocket_handle/3]). +-export([websocket_info/3]). +-export([websocket_terminate/3]). + +-record(state, { +}). + +init(_, _, _) -> + {upgrade, protocol, cowboy_websocket}. + +websocket_init(_, Req, _Opts) -> + Req2 = cowboy_req:compact(Req), + {ok, Req2, #state{}}. + +websocket_handle({text, Data}, Req, State) -> + {reply, {text, Data}, Req, State}; +websocket_handle({binary, Data}, Req, State) -> + {reply, {binary, Data}, Req, State}; +websocket_handle(_Frame, Req, State) -> + {ok, Req, State}. + +websocket_info(_Info, Req, State) -> + {ok, Req, State}. + +websocket_terminate(_Reason, _Req, _State) -> + ok. +endef + +define tpl_ranch_protocol +-module($(n)). +-behaviour(ranch_protocol). + +-export([start_link/4]). +-export([init/4]). + +-type opts() :: []. +-export_type([opts/0]). + +-record(state, { + socket :: inet:socket(), + transport :: module() +}). + +start_link(Ref, Socket, Transport, Opts) -> + Pid = spawn_link(?MODULE, init, [Ref, Socket, Transport, Opts]), + {ok, Pid}. + +-spec init(ranch:ref(), inet:socket(), module(), opts()) -> ok. +init(Ref, Socket, Transport, _Opts) -> + ok = ranch:accept_ack(Ref), + loop(#state{socket=Socket, transport=Transport}). + +loop(State) -> + loop(State). +endef + +# Plugin-specific targets. + +ifndef WS +ifdef SP +WS = $(subst a,,a $(wordlist 1,$(SP),a a a a a a a a a a a a a a a a a a a a)) +else +WS = $(tab) +endif +endif + +bootstrap: +ifneq ($(wildcard src/),) + $(error Error: src/ directory already exists) +endif + $(eval p := $(PROJECT)) + $(if $(shell echo $p | LC_ALL=C grep -x "[a-z0-9_]*"),,\ + $(error Error: Invalid characters in the application name)) + $(eval n := $(PROJECT)_sup) + $(verbose) $(call core_render,bs_Makefile,Makefile) + $(verbose) echo "include erlang.mk" >> Makefile + $(verbose) mkdir src/ +ifdef LEGACY + $(verbose) $(call core_render,bs_appsrc,src/$(PROJECT).app.src) +endif + $(verbose) $(call core_render,bs_app,src/$(PROJECT)_app.erl) + $(verbose) $(call core_render,tpl_supervisor,src/$(PROJECT)_sup.erl) + +bootstrap-lib: +ifneq ($(wildcard src/),) + $(error Error: src/ directory already exists) +endif + $(eval p := $(PROJECT)) + $(if $(shell echo $p | LC_ALL=C grep -x "[a-z0-9_]*"),,\ + $(error Error: Invalid characters in the application name)) + $(verbose) $(call core_render,bs_Makefile,Makefile) + $(verbose) echo "include erlang.mk" >> Makefile + $(verbose) mkdir src/ +ifdef LEGACY + $(verbose) $(call core_render,bs_appsrc_lib,src/$(PROJECT).app.src) +endif + +bootstrap-rel: +ifneq ($(wildcard relx.config),) + $(error Error: relx.config already exists) +endif +ifneq ($(wildcard config/),) + $(error Error: config/ directory already exists) +endif + $(eval p := $(PROJECT)) + $(verbose) $(call core_render,bs_relx_config,relx.config) + $(verbose) mkdir config/ + $(verbose) $(call core_render,bs_sys_config,config/sys.config) + $(verbose) $(call core_render,bs_vm_args,config/vm.args) + +new-app: +ifndef in + $(error Usage: $(MAKE) new-app in=APP) +endif +ifneq ($(wildcard $(APPS_DIR)/$in),) + $(error Error: Application $in already exists) +endif + $(eval p := $(in)) + $(if $(shell echo $p | LC_ALL=C grep -x "[a-z0-9_]*"),,\ + $(error Error: Invalid characters in the application name)) + $(eval n := $(in)_sup) + $(verbose) mkdir -p $(APPS_DIR)/$p/src/ + $(verbose) $(call core_render,bs_apps_Makefile,$(APPS_DIR)/$p/Makefile) +ifdef LEGACY + $(verbose) $(call core_render,bs_appsrc,$(APPS_DIR)/$p/src/$p.app.src) +endif + $(verbose) $(call core_render,bs_app,$(APPS_DIR)/$p/src/$p_app.erl) + $(verbose) $(call core_render,tpl_supervisor,$(APPS_DIR)/$p/src/$p_sup.erl) + +new-lib: +ifndef in + $(error Usage: $(MAKE) new-lib in=APP) +endif +ifneq ($(wildcard $(APPS_DIR)/$in),) + $(error Error: Application $in already exists) +endif + $(eval p := $(in)) + $(if $(shell echo $p | LC_ALL=C grep -x "[a-z0-9_]*"),,\ + $(error Error: Invalid characters in the application name)) + $(verbose) mkdir -p $(APPS_DIR)/$p/src/ + $(verbose) $(call core_render,bs_apps_Makefile,$(APPS_DIR)/$p/Makefile) +ifdef LEGACY + $(verbose) $(call core_render,bs_appsrc_lib,$(APPS_DIR)/$p/src/$p.app.src) +endif + +new: +ifeq ($(wildcard src/)$(in),) + $(error Error: src/ directory does not exist) +endif +ifndef t + $(error Usage: $(MAKE) new t=TEMPLATE n=NAME [in=APP]) +endif +ifndef n + $(error Usage: $(MAKE) new t=TEMPLATE n=NAME [in=APP]) +endif +ifdef in + $(verbose) $(call core_render,tpl_$(t),$(APPS_DIR)/$(in)/src/$(n).erl) +else + $(verbose) $(call core_render,tpl_$(t),src/$(n).erl) +endif + +list-templates: + $(verbose) @echo Available templates: + $(verbose) printf " %s\n" $(sort $(patsubst tpl_%,%,$(filter tpl_%,$(.VARIABLES)))) + +# Copyright (c) 2014-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: clean-c_src distclean-c_src-env + +# Configuration. + +C_SRC_DIR ?= $(CURDIR)/c_src +C_SRC_ENV ?= $(C_SRC_DIR)/env.mk +C_SRC_OUTPUT ?= $(CURDIR)/priv/$(PROJECT) +C_SRC_TYPE ?= shared + +# System type and C compiler/flags. + +ifeq ($(PLATFORM),msys2) + C_SRC_OUTPUT_EXECUTABLE_EXTENSION ?= .exe + C_SRC_OUTPUT_SHARED_EXTENSION ?= .dll +else + C_SRC_OUTPUT_EXECUTABLE_EXTENSION ?= + C_SRC_OUTPUT_SHARED_EXTENSION ?= .so +endif + +ifeq ($(C_SRC_TYPE),shared) + C_SRC_OUTPUT_FILE = $(C_SRC_OUTPUT)$(C_SRC_OUTPUT_SHARED_EXTENSION) +else + C_SRC_OUTPUT_FILE = $(C_SRC_OUTPUT)$(C_SRC_OUTPUT_EXECUTABLE_EXTENSION) +endif + +ifeq ($(PLATFORM),msys2) +# We hardcode the compiler used on MSYS2. The default CC=cc does +# not produce working code. The "gcc" MSYS2 package also doesn't. + CC = /mingw64/bin/gcc + export CC + CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes + CXXFLAGS ?= -O3 -finline-functions -Wall +else ifeq ($(PLATFORM),darwin) + CC ?= cc + CFLAGS ?= -O3 -std=c99 -arch x86_64 -Wall -Wmissing-prototypes + CXXFLAGS ?= -O3 -arch x86_64 -Wall + LDFLAGS ?= -arch x86_64 -flat_namespace -undefined suppress +else ifeq ($(PLATFORM),freebsd) + CC ?= cc + CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes + CXXFLAGS ?= -O3 -finline-functions -Wall +else ifeq ($(PLATFORM),linux) + CC ?= gcc + CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes + CXXFLAGS ?= -O3 -finline-functions -Wall +endif + +ifneq ($(PLATFORM),msys2) + CFLAGS += -fPIC + CXXFLAGS += -fPIC +endif + +CFLAGS += -I"$(ERTS_INCLUDE_DIR)" -I"$(ERL_INTERFACE_INCLUDE_DIR)" +CXXFLAGS += -I"$(ERTS_INCLUDE_DIR)" -I"$(ERL_INTERFACE_INCLUDE_DIR)" + +LDLIBS += -L"$(ERL_INTERFACE_LIB_DIR)" -lei + +# Verbosity. + +c_verbose_0 = @echo " C " $(filter-out $(notdir $(MAKEFILE_LIST) $(C_SRC_ENV)),$(^F)); +c_verbose = $(c_verbose_$(V)) + +cpp_verbose_0 = @echo " CPP " $(filter-out $(notdir $(MAKEFILE_LIST) $(C_SRC_ENV)),$(^F)); +cpp_verbose = $(cpp_verbose_$(V)) + +link_verbose_0 = @echo " LD " $(@F); +link_verbose = $(link_verbose_$(V)) + +# Targets. + +ifeq ($(wildcard $(C_SRC_DIR)),) +else ifneq ($(wildcard $(C_SRC_DIR)/Makefile),) +app:: app-c_src + +test-build:: app-c_src + +app-c_src: + $(MAKE) -C $(C_SRC_DIR) + +clean:: + $(MAKE) -C $(C_SRC_DIR) clean + +else + +ifeq ($(SOURCES),) +SOURCES := $(sort $(foreach pat,*.c *.C *.cc *.cpp,$(call core_find,$(C_SRC_DIR)/,$(pat)))) +endif +OBJECTS = $(addsuffix .o, $(basename $(SOURCES))) + +COMPILE_C = $(c_verbose) $(CC) $(CFLAGS) $(CPPFLAGS) -c +COMPILE_CPP = $(cpp_verbose) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c + +app:: $(C_SRC_ENV) $(C_SRC_OUTPUT_FILE) + +test-build:: $(C_SRC_ENV) $(C_SRC_OUTPUT_FILE) + +$(C_SRC_OUTPUT_FILE): $(OBJECTS) + $(verbose) mkdir -p $(dir $@) + $(link_verbose) $(CC) $(OBJECTS) \ + $(LDFLAGS) $(if $(filter $(C_SRC_TYPE),shared),-shared) $(LDLIBS) \ + -o $(C_SRC_OUTPUT_FILE) + +$(OBJECTS): $(MAKEFILE_LIST) $(C_SRC_ENV) + +%.o: %.c + $(COMPILE_C) $(OUTPUT_OPTION) $< + +%.o: %.cc + $(COMPILE_CPP) $(OUTPUT_OPTION) $< + +%.o: %.C + $(COMPILE_CPP) $(OUTPUT_OPTION) $< + +%.o: %.cpp + $(COMPILE_CPP) $(OUTPUT_OPTION) $< + +clean:: clean-c_src + +clean-c_src: + $(gen_verbose) rm -f $(C_SRC_OUTPUT_FILE) $(OBJECTS) + +endif + +ifneq ($(wildcard $(C_SRC_DIR)),) +ERL_ERTS_DIR = $(shell $(ERL) -eval 'io:format("~s~n", [code:lib_dir(erts)]), halt().') + +$(C_SRC_ENV): + $(verbose) $(ERL) -eval "file:write_file(\"$(call core_native_path,$(C_SRC_ENV))\", \ + io_lib:format( \ + \"# Generated by Erlang.mk. Edit at your own risk!~n~n\" \ + \"ERTS_INCLUDE_DIR ?= ~s/erts-~s/include/~n\" \ + \"ERL_INTERFACE_INCLUDE_DIR ?= ~s~n\" \ + \"ERL_INTERFACE_LIB_DIR ?= ~s~n\" \ + \"ERTS_DIR ?= $(ERL_ERTS_DIR)~n\", \ + [code:root_dir(), erlang:system_info(version), \ + code:lib_dir(erl_interface, include), \ + code:lib_dir(erl_interface, lib)])), \ + halt()." + +distclean:: distclean-c_src-env + +distclean-c_src-env: + $(gen_verbose) rm -f $(C_SRC_ENV) + +-include $(C_SRC_ENV) + +ifneq ($(ERL_ERTS_DIR),$(ERTS_DIR)) +$(shell rm -f $(C_SRC_ENV)) +endif +endif + +# Templates. + +define bs_c_nif +#include "erl_nif.h" + +static int loads = 0; + +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) +{ + /* Initialize private data. */ + *priv_data = NULL; + + loads++; + + return 0; +} + +static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info) +{ + /* Convert the private data to the new version. */ + *priv_data = *old_priv_data; + + loads++; + + return 0; +} + +static void unload(ErlNifEnv* env, void* priv_data) +{ + if (loads == 1) { + /* Destroy the private data. */ + } + + loads--; +} + +static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + if (enif_is_atom(env, argv[0])) { + return enif_make_tuple2(env, + enif_make_atom(env, "hello"), + argv[0]); + } + + return enif_make_tuple2(env, + enif_make_atom(env, "error"), + enif_make_atom(env, "badarg")); +} + +static ErlNifFunc nif_funcs[] = { + {"hello", 1, hello} +}; + +ERL_NIF_INIT($n, nif_funcs, load, NULL, upgrade, unload) +endef + +define bs_erl_nif +-module($n). + +-export([hello/1]). + +-on_load(on_load/0). +on_load() -> + PrivDir = case code:priv_dir(?MODULE) of + {error, _} -> + AppPath = filename:dirname(filename:dirname(code:which(?MODULE))), + filename:join(AppPath, "priv"); + Path -> + Path + end, + erlang:load_nif(filename:join(PrivDir, atom_to_list(?MODULE)), 0). + +hello(_) -> + erlang:nif_error({not_loaded, ?MODULE}). +endef + +new-nif: +ifneq ($(wildcard $(C_SRC_DIR)/$n.c),) + $(error Error: $(C_SRC_DIR)/$n.c already exists) +endif +ifneq ($(wildcard src/$n.erl),) + $(error Error: src/$n.erl already exists) +endif +ifndef n + $(error Usage: $(MAKE) new-nif n=NAME [in=APP]) +endif +ifdef in + $(verbose) $(MAKE) -C $(APPS_DIR)/$(in)/ new-nif n=$n in= +else + $(verbose) mkdir -p $(C_SRC_DIR) src/ + $(verbose) $(call core_render,bs_c_nif,$(C_SRC_DIR)/$n.c) + $(verbose) $(call core_render,bs_erl_nif,src/$n.erl) +endif + +# Copyright (c) 2015-2017, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: ci ci-prepare ci-setup + +CI_OTP ?= +CI_HIPE ?= +CI_ERLLVM ?= + +ifeq ($(CI_VM),native) +ERLC_OPTS += +native +TEST_ERLC_OPTS += +native +else ifeq ($(CI_VM),erllvm) +ERLC_OPTS += +native +'{hipe, [to_llvm]}' +TEST_ERLC_OPTS += +native +'{hipe, [to_llvm]}' +endif + +ifeq ($(strip $(CI_OTP) $(CI_HIPE) $(CI_ERLLVM)),) +ci:: +else + +ci:: $(addprefix ci-,$(CI_OTP) $(addsuffix -native,$(CI_HIPE)) $(addsuffix -erllvm,$(CI_ERLLVM))) + +ci-prepare: $(addprefix $(KERL_INSTALL_DIR)/,$(CI_OTP) $(addsuffix -native,$(CI_HIPE))) + +ci-setup:: + $(verbose) : + +ci-extra:: + $(verbose) : + +ci_verbose_0 = @echo " CI " $(1); +ci_verbose = $(ci_verbose_$(V)) + +define ci_target +ci-$1: $(KERL_INSTALL_DIR)/$2 + $(verbose) $(MAKE) --no-print-directory clean + $(ci_verbose) \ + PATH="$(KERL_INSTALL_DIR)/$2/bin:$(PATH)" \ + CI_OTP_RELEASE="$1" \ + CT_OPTS="-label $1" \ + CI_VM="$3" \ + $(MAKE) ci-setup tests + $(verbose) $(MAKE) --no-print-directory ci-extra +endef + +$(foreach otp,$(CI_OTP),$(eval $(call ci_target,$(otp),$(otp),otp))) +$(foreach otp,$(CI_HIPE),$(eval $(call ci_target,$(otp)-native,$(otp)-native,native))) +$(foreach otp,$(CI_ERLLVM),$(eval $(call ci_target,$(otp)-erllvm,$(otp)-native,erllvm))) + +$(foreach otp,$(filter-out $(ERLANG_OTP),$(CI_OTP)),$(eval $(call kerl_otp_target,$(otp)))) +$(foreach otp,$(filter-out $(ERLANG_HIPE),$(sort $(CI_HIPE) $(CI_ERLLLVM))),$(eval $(call kerl_hipe_target,$(otp)))) + +help:: + $(verbose) printf "%s\n" "" \ + "Continuous Integration targets:" \ + " ci Run '$(MAKE) tests' on all configured Erlang versions." \ + "" \ + "The CI_OTP variable must be defined with the Erlang versions" \ + "that must be tested. For example: CI_OTP = OTP-17.3.4 OTP-17.5.3" + +endif + +# Copyright (c) 2020, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +ifdef CONCUERROR_TESTS + +.PHONY: concuerror distclean-concuerror + +# Configuration + +CONCUERROR_LOGS_DIR ?= $(CURDIR)/logs +CONCUERROR_OPTS ?= + +# Core targets. + +check:: concuerror + +ifndef KEEP_LOGS +distclean:: distclean-concuerror +endif + +# Plugin-specific targets. + +$(ERLANG_MK_TMP)/Concuerror/bin/concuerror: | $(ERLANG_MK_TMP) + $(verbose) git clone https://github.com/parapluu/Concuerror $(ERLANG_MK_TMP)/Concuerror + $(verbose) $(MAKE) -C $(ERLANG_MK_TMP)/Concuerror + +$(CONCUERROR_LOGS_DIR): + $(verbose) mkdir -p $(CONCUERROR_LOGS_DIR) + +define concuerror_html_report + + + + +Concuerror HTML report + + +

Concuerror HTML report

+

Generated on $(concuerror_date)

+
    +$(foreach t,$(concuerror_targets),
  • $(t)
  • ) +
+ + +endef + +concuerror: $(addprefix concuerror-,$(subst :,-,$(CONCUERROR_TESTS))) + $(eval concuerror_date := $(shell date)) + $(eval concuerror_targets := $^) + $(verbose) $(call core_render,concuerror_html_report,$(CONCUERROR_LOGS_DIR)/concuerror.html) + +define concuerror_target +.PHONY: concuerror-$1-$2 + +concuerror-$1-$2: test-build | $(ERLANG_MK_TMP)/Concuerror/bin/concuerror $(CONCUERROR_LOGS_DIR) + $(ERLANG_MK_TMP)/Concuerror/bin/concuerror \ + --pa $(CURDIR)/ebin --pa $(TEST_DIR) \ + -o $(CONCUERROR_LOGS_DIR)/concuerror-$1-$2.txt \ + $$(CONCUERROR_OPTS) -m $1 -t $2 +endef + +$(foreach test,$(CONCUERROR_TESTS),$(eval $(call concuerror_target,$(firstword $(subst :, ,$(test))),$(lastword $(subst :, ,$(test)))))) + +distclean-concuerror: + $(gen_verbose) rm -rf $(CONCUERROR_LOGS_DIR) + +endif + +# Copyright (c) 2013-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: ct apps-ct distclean-ct + +# Configuration. + +CT_OPTS ?= + +ifneq ($(wildcard $(TEST_DIR)),) +ifndef CT_SUITES +CT_SUITES := $(sort $(subst _SUITE.erl,,$(notdir $(call core_find,$(TEST_DIR)/,*_SUITE.erl)))) +endif +endif +CT_SUITES ?= +CT_LOGS_DIR ?= $(CURDIR)/logs + +# Core targets. + +tests:: ct + +ifndef KEEP_LOGS +distclean:: distclean-ct +endif + +help:: + $(verbose) printf "%s\n" "" \ + "Common_test targets:" \ + " ct Run all the common_test suites for this project" \ + "" \ + "All your common_test suites have their associated targets." \ + "A suite named http_SUITE can be ran using the ct-http target." + +# Plugin-specific targets. + +CT_RUN = ct_run \ + -no_auto_compile \ + -noinput \ + -pa $(CURDIR)/ebin $(TEST_DIR) \ + -dir $(TEST_DIR) \ + -logdir $(CT_LOGS_DIR) + +ifeq ($(CT_SUITES),) +ct: $(if $(IS_APP)$(ROOT_DIR),,apps-ct) +else +# We do not run tests if we are in an apps/* with no test directory. +ifneq ($(IS_APP)$(wildcard $(TEST_DIR)),1) +ct: test-build $(if $(IS_APP)$(ROOT_DIR),,apps-ct) + $(verbose) mkdir -p $(CT_LOGS_DIR) + $(gen_verbose) $(CT_RUN) -sname ct_$(PROJECT) -suite $(addsuffix _SUITE,$(CT_SUITES)) $(CT_OPTS) +endif +endif + +ifneq ($(ALL_APPS_DIRS),) +define ct_app_target +apps-ct-$1: test-build + $$(MAKE) -C $1 ct IS_APP=1 +endef + +$(foreach app,$(ALL_APPS_DIRS),$(eval $(call ct_app_target,$(app)))) + +apps-ct: $(addprefix apps-ct-,$(ALL_APPS_DIRS)) +endif + +ifdef t +ifeq (,$(findstring :,$t)) +CT_EXTRA = -group $t +else +t_words = $(subst :, ,$t) +CT_EXTRA = -group $(firstword $(t_words)) -case $(lastword $(t_words)) +endif +else +ifdef c +CT_EXTRA = -case $c +else +CT_EXTRA = +endif +endif + +define ct_suite_target +ct-$(1): test-build + $(verbose) mkdir -p $(CT_LOGS_DIR) + $(gen_verbose_esc) $(CT_RUN) -sname ct_$(PROJECT) -suite $(addsuffix _SUITE,$(1)) $(CT_EXTRA) $(CT_OPTS) +endef + +$(foreach test,$(CT_SUITES),$(eval $(call ct_suite_target,$(test)))) + +distclean-ct: + $(gen_verbose) rm -rf $(CT_LOGS_DIR) + +# Copyright (c) 2013-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: plt distclean-plt dialyze + +# Configuration. + +DIALYZER_PLT ?= $(CURDIR)/.$(PROJECT).plt +export DIALYZER_PLT + +PLT_APPS ?= +DIALYZER_DIRS ?= --src -r $(wildcard src) $(ALL_APPS_DIRS) +DIALYZER_OPTS ?= -Werror_handling -Wrace_conditions -Wunmatched_returns # -Wunderspecs +DIALYZER_PLT_OPTS ?= + +# Core targets. + +check:: dialyze + +distclean:: distclean-plt + +help:: + $(verbose) printf "%s\n" "" \ + "Dialyzer targets:" \ + " plt Build a PLT file for this project" \ + " dialyze Analyze the project using Dialyzer" + +# Plugin-specific targets. + +define filter_opts.erl + Opts = init:get_plain_arguments(), + {Filtered, _} = lists:foldl(fun + (O, {Os, true}) -> {[O|Os], false}; + (O = "-D", {Os, _}) -> {[O|Os], true}; + (O = [\\$$-, \\$$D, _ | _], {Os, _}) -> {[O|Os], false}; + (O = "-I", {Os, _}) -> {[O|Os], true}; + (O = [\\$$-, \\$$I, _ | _], {Os, _}) -> {[O|Os], false}; + (O = "-pa", {Os, _}) -> {[O|Os], true}; + (_, Acc) -> Acc + end, {[], false}, Opts), + io:format("~s~n", [string:join(lists:reverse(Filtered), " ")]), + halt(). +endef + +# DIALYZER_PLT is a variable understood directly by Dialyzer. +# +# We append the path to erts at the end of the PLT. This works +# because the PLT file is in the external term format and the +# function binary_to_term/1 ignores any trailing data. +$(DIALYZER_PLT): deps app + $(eval DEPS_LOG := $(shell test -f $(ERLANG_MK_TMP)/deps.log && \ + while read p; do test -d $$p/ebin && echo $$p/ebin; done <$(ERLANG_MK_TMP)/deps.log)) + $(verbose) dialyzer --build_plt $(DIALYZER_PLT_OPTS) --apps \ + erts kernel stdlib $(PLT_APPS) $(OTP_DEPS) $(LOCAL_DEPS) $(DEPS_LOG) || test $$? -eq 2 + $(verbose) $(ERL) -eval 'io:format("~n~s~n", [code:lib_dir(erts)]), halt().' >> $@ + +plt: $(DIALYZER_PLT) + +distclean-plt: + $(gen_verbose) rm -f $(DIALYZER_PLT) + +ifneq ($(wildcard $(DIALYZER_PLT)),) +dialyze: $(if $(filter --src,$(DIALYZER_DIRS)),,deps app) + $(verbose) if ! tail -n1 $(DIALYZER_PLT) | \ + grep -q "^`$(ERL) -eval 'io:format("~s", [code:lib_dir(erts)]), halt().'`$$"; then \ + rm $(DIALYZER_PLT); \ + $(MAKE) plt; \ + fi +else +dialyze: $(DIALYZER_PLT) +endif + $(verbose) dialyzer --no_native `$(ERL) \ + -eval "$(subst $(newline),,$(call escape_dquotes,$(call filter_opts.erl)))" \ + -extra $(ERLC_OPTS)` $(DIALYZER_DIRS) $(DIALYZER_OPTS) $(if $(wildcard ebin/),-pa ebin/) + +# Copyright (c) 2013-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: distclean-edoc edoc + +# Configuration. + +EDOC_OPTS ?= +EDOC_SRC_DIRS ?= +EDOC_OUTPUT ?= doc + +define edoc.erl + SrcPaths = lists:foldl(fun(P, Acc) -> + filelib:wildcard(atom_to_list(P) ++ "/{src,c_src}") ++ Acc + end, [], [$(call comma_list,$(patsubst %,'%',$(call core_native_path,$(EDOC_SRC_DIRS))))]), + DefaultOpts = [{dir, "$(EDOC_OUTPUT)"}, {source_path, SrcPaths}, {subpackages, false}], + edoc:application($(1), ".", [$(2)] ++ DefaultOpts), + halt(0). +endef + +# Core targets. + +ifneq ($(strip $(EDOC_SRC_DIRS)$(wildcard doc/overview.edoc)),) +docs:: edoc +endif + +distclean:: distclean-edoc + +# Plugin-specific targets. + +edoc: distclean-edoc doc-deps + $(gen_verbose) $(call erlang,$(call edoc.erl,$(PROJECT),$(EDOC_OPTS))) + +distclean-edoc: + $(gen_verbose) rm -f $(EDOC_OUTPUT)/*.css $(EDOC_OUTPUT)/*.html $(EDOC_OUTPUT)/*.png $(EDOC_OUTPUT)/edoc-info + +# Copyright (c) 2013-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +# Configuration. + +DTL_FULL_PATH ?= +DTL_PATH ?= templates/ +DTL_PREFIX ?= +DTL_SUFFIX ?= _dtl +DTL_OPTS ?= + +# Verbosity. + +dtl_verbose_0 = @echo " DTL " $(filter %.dtl,$(?F)); +dtl_verbose = $(dtl_verbose_$(V)) + +# Core targets. + +DTL_PATH := $(abspath $(DTL_PATH)) +DTL_FILES := $(sort $(call core_find,$(DTL_PATH),*.dtl)) + +ifneq ($(DTL_FILES),) + +DTL_NAMES = $(addprefix $(DTL_PREFIX),$(addsuffix $(DTL_SUFFIX),$(DTL_FILES:$(DTL_PATH)/%.dtl=%))) +DTL_MODULES = $(if $(DTL_FULL_PATH),$(subst /,_,$(DTL_NAMES)),$(notdir $(DTL_NAMES))) +BEAM_FILES += $(addsuffix .beam,$(addprefix ebin/,$(DTL_MODULES))) + +ifneq ($(words $(DTL_FILES)),0) +# Rebuild templates when the Makefile changes. +$(ERLANG_MK_TMP)/last-makefile-change-erlydtl: $(MAKEFILE_LIST) | $(ERLANG_MK_TMP) + $(verbose) if test -f $@; then \ + touch $(DTL_FILES); \ + fi + $(verbose) touch $@ + +ebin/$(PROJECT).app:: $(ERLANG_MK_TMP)/last-makefile-change-erlydtl +endif + +define erlydtl_compile.erl + [begin + Module0 = case "$(strip $(DTL_FULL_PATH))" of + "" -> + filename:basename(F, ".dtl"); + _ -> + "$(call core_native_path,$(DTL_PATH))/" ++ F2 = filename:rootname(F, ".dtl"), + re:replace(F2, "/", "_", [{return, list}, global]) + end, + Module = list_to_atom("$(DTL_PREFIX)" ++ string:to_lower(Module0) ++ "$(DTL_SUFFIX)"), + case erlydtl:compile(F, Module, [$(DTL_OPTS)] ++ [{out_dir, "ebin/"}, return_errors]) of + ok -> ok; + {ok, _} -> ok + end + end || F <- string:tokens("$(1)", " ")], + halt(). +endef + +ebin/$(PROJECT).app:: $(DTL_FILES) | ebin/ + $(if $(strip $?),\ + $(dtl_verbose) $(call erlang,$(call erlydtl_compile.erl,$(call core_native_path,$?)),\ + -pa ebin/)) + +endif + +# Copyright (c) 2016, Loïc Hoguin +# Copyright (c) 2014, Dave Cottlehuber +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: distclean-escript escript escript-zip + +# Configuration. + +ESCRIPT_NAME ?= $(PROJECT) +ESCRIPT_FILE ?= $(ESCRIPT_NAME) + +ESCRIPT_SHEBANG ?= /usr/bin/env escript +ESCRIPT_COMMENT ?= This is an -*- erlang -*- file +ESCRIPT_EMU_ARGS ?= -escript main $(ESCRIPT_NAME) + +ESCRIPT_ZIP ?= 7z a -tzip -mx=9 -mtc=off $(if $(filter-out 0,$(V)),,> /dev/null) +ESCRIPT_ZIP_FILE ?= $(ERLANG_MK_TMP)/escript.zip + +# Core targets. + +distclean:: distclean-escript + +help:: + $(verbose) printf "%s\n" "" \ + "Escript targets:" \ + " escript Build an executable escript archive" \ + +# Plugin-specific targets. + +escript-zip:: FULL=1 +escript-zip:: deps app + $(verbose) mkdir -p $(dir $(ESCRIPT_ZIP)) + $(verbose) rm -f $(ESCRIPT_ZIP_FILE) + $(gen_verbose) cd .. && $(ESCRIPT_ZIP) $(ESCRIPT_ZIP_FILE) $(PROJECT)/ebin/* +ifneq ($(DEPS),) + $(verbose) cd $(DEPS_DIR) && $(ESCRIPT_ZIP) $(ESCRIPT_ZIP_FILE) \ + $(subst $(DEPS_DIR)/,,$(addsuffix /*,$(wildcard \ + $(addsuffix /ebin,$(shell cat $(ERLANG_MK_TMP)/deps.log))))) +endif + +escript:: escript-zip + $(gen_verbose) printf "%s\n" \ + "#!$(ESCRIPT_SHEBANG)" \ + "%% $(ESCRIPT_COMMENT)" \ + "%%! $(ESCRIPT_EMU_ARGS)" > $(ESCRIPT_FILE) + $(verbose) cat $(ESCRIPT_ZIP_FILE) >> $(ESCRIPT_FILE) + $(verbose) chmod +x $(ESCRIPT_FILE) + +distclean-escript: + $(gen_verbose) rm -f $(ESCRIPT_FILE) + +# Copyright (c) 2015-2016, Loïc Hoguin +# Copyright (c) 2014, Enrique Fernandez +# This file is contributed to erlang.mk and subject to the terms of the ISC License. + +.PHONY: eunit apps-eunit + +# Configuration + +EUNIT_OPTS ?= +EUNIT_ERL_OPTS ?= + +# Core targets. + +tests:: eunit + +help:: + $(verbose) printf "%s\n" "" \ + "EUnit targets:" \ + " eunit Run all the EUnit tests for this project" + +# Plugin-specific targets. + +define eunit.erl + $(call cover.erl) + CoverSetup(), + case eunit:test($1, [$(EUNIT_OPTS)]) of + ok -> ok; + error -> halt(2) + end, + CoverExport("$(call core_native_path,$(COVER_DATA_DIR))/eunit.coverdata"), + halt() +endef + +EUNIT_ERL_OPTS += -pa $(TEST_DIR) $(CURDIR)/ebin + +ifdef t +ifeq (,$(findstring :,$(t))) +eunit: test-build cover-data-dir + $(gen_verbose) $(call erlang,$(call eunit.erl,['$(t)']),$(EUNIT_ERL_OPTS)) +else +eunit: test-build cover-data-dir + $(gen_verbose) $(call erlang,$(call eunit.erl,fun $(t)/0),$(EUNIT_ERL_OPTS)) +endif +else +EUNIT_EBIN_MODS = $(notdir $(basename $(ERL_FILES) $(BEAM_FILES))) +EUNIT_TEST_MODS = $(notdir $(basename $(call core_find,$(TEST_DIR)/,*.erl))) + +EUNIT_MODS = $(foreach mod,$(EUNIT_EBIN_MODS) $(filter-out \ + $(patsubst %,%_tests,$(EUNIT_EBIN_MODS)),$(EUNIT_TEST_MODS)),'$(mod)') + +eunit: test-build $(if $(IS_APP)$(ROOT_DIR),,apps-eunit) cover-data-dir +ifneq ($(wildcard src/ $(TEST_DIR)),) + $(gen_verbose) $(call erlang,$(call eunit.erl,[$(call comma_list,$(EUNIT_MODS))]),$(EUNIT_ERL_OPTS)) +endif + +ifneq ($(ALL_APPS_DIRS),) +apps-eunit: test-build + $(verbose) eunit_retcode=0 ; for app in $(ALL_APPS_DIRS); do $(MAKE) -C $$app eunit IS_APP=1; \ + [ $$? -ne 0 ] && eunit_retcode=1 ; done ; \ + exit $$eunit_retcode +endif +endif + +# Copyright (c) 2015-2017, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +ifeq ($(filter proper,$(DEPS) $(TEST_DEPS)),proper) +.PHONY: proper + +# Targets. + +tests:: proper + +define proper_check.erl + $(call cover.erl) + code:add_pathsa([ + "$(call core_native_path,$(CURDIR)/ebin)", + "$(call core_native_path,$(DEPS_DIR)/*/ebin)", + "$(call core_native_path,$(TEST_DIR))"]), + Module = fun(M) -> + [true] =:= lists:usort([ + case atom_to_list(F) of + "prop_" ++ _ -> + io:format("Testing ~p:~p/0~n", [M, F]), + proper:quickcheck(M:F(), nocolors); + _ -> + true + end + || {F, 0} <- M:module_info(exports)]) + end, + try begin + CoverSetup(), + Res = case $(1) of + all -> [true] =:= lists:usort([Module(M) || M <- [$(call comma_list,$(3))]]); + module -> Module($(2)); + function -> proper:quickcheck($(2), nocolors) + end, + CoverExport("$(COVER_DATA_DIR)/proper.coverdata"), + Res + end of + true -> halt(0); + _ -> halt(1) + catch error:undef -> + io:format("Undefined property or module?~n~p~n", [erlang:get_stacktrace()]), + halt(0) + end. +endef + +ifdef t +ifeq (,$(findstring :,$(t))) +proper: test-build cover-data-dir + $(verbose) $(call erlang,$(call proper_check.erl,module,$(t))) +else +proper: test-build cover-data-dir + $(verbose) echo Testing $(t)/0 + $(verbose) $(call erlang,$(call proper_check.erl,function,$(t)())) +endif +else +proper: test-build cover-data-dir + $(eval MODULES := $(patsubst %,'%',$(sort $(notdir $(basename \ + $(wildcard ebin/*.beam) $(call core_find,$(TEST_DIR)/,*.beam)))))) + $(gen_verbose) $(call erlang,$(call proper_check.erl,all,undefined,$(MODULES))) +endif +endif + +# Copyright (c) 2015-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +# Verbosity. + +proto_verbose_0 = @echo " PROTO " $(filter %.proto,$(?F)); +proto_verbose = $(proto_verbose_$(V)) + +# Core targets. + +ifneq ($(wildcard src/),) +ifneq ($(filter gpb protobuffs,$(BUILD_DEPS) $(DEPS)),) +PROTO_FILES := $(filter %.proto,$(ALL_SRC_FILES)) +ERL_FILES += $(addprefix src/,$(patsubst %.proto,%_pb.erl,$(notdir $(PROTO_FILES)))) + +ifeq ($(PROTO_FILES),) +$(ERLANG_MK_TMP)/last-makefile-change-protobuffs: + $(verbose) : +else +# Rebuild proto files when the Makefile changes. +# We exclude $(PROJECT).d to avoid a circular dependency. +$(ERLANG_MK_TMP)/last-makefile-change-protobuffs: $(filter-out $(PROJECT).d,$(MAKEFILE_LIST)) | $(ERLANG_MK_TMP) + $(verbose) if test -f $@; then \ + touch $(PROTO_FILES); \ + fi + $(verbose) touch $@ + +$(PROJECT).d:: $(ERLANG_MK_TMP)/last-makefile-change-protobuffs +endif + +ifeq ($(filter gpb,$(BUILD_DEPS) $(DEPS)),) +define compile_proto.erl + [begin + protobuffs_compile:generate_source(F, [ + {output_include_dir, "./include"}, + {output_src_dir, "./src"}]) + end || F <- string:tokens("$1", " ")], + halt(). +endef +else +define compile_proto.erl + [begin + gpb_compile:file(F, [ + {include_as_lib, true}, + {module_name_suffix, "_pb"}, + {o_hrl, "./include"}, + {o_erl, "./src"}]) + end || F <- string:tokens("$1", " ")], + halt(). +endef +endif + +ifneq ($(PROTO_FILES),) +$(PROJECT).d:: $(PROTO_FILES) + $(verbose) mkdir -p ebin/ include/ + $(if $(strip $?),$(proto_verbose) $(call erlang,$(call compile_proto.erl,$?))) +endif +endif +endif + +# Copyright (c) 2013-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: relx-rel relx-relup distclean-relx-rel run + +# Configuration. + +RELX ?= $(ERLANG_MK_TMP)/relx +RELX_CONFIG ?= $(CURDIR)/relx.config + +RELX_URL ?= https://erlang.mk/res/relx-v3.27.0 +RELX_OPTS ?= +RELX_OUTPUT_DIR ?= _rel +RELX_REL_EXT ?= +RELX_TAR ?= 1 + +ifdef SFX + RELX_TAR = 1 +endif + +ifeq ($(firstword $(RELX_OPTS)),-o) + RELX_OUTPUT_DIR = $(word 2,$(RELX_OPTS)) +else + RELX_OPTS += -o $(RELX_OUTPUT_DIR) +endif + +# Core targets. + +ifeq ($(IS_DEP),) +ifneq ($(wildcard $(RELX_CONFIG)),) +rel:: relx-rel + +relup:: relx-relup +endif +endif + +distclean:: distclean-relx-rel + +# Plugin-specific targets. + +$(RELX): | $(ERLANG_MK_TMP) + $(gen_verbose) $(call core_http_get,$(RELX),$(RELX_URL)) + $(verbose) chmod +x $(RELX) + +relx-rel: $(RELX) rel-deps app + $(verbose) $(RELX) $(if $(filter 1,$V),-V 3) -c $(RELX_CONFIG) $(RELX_OPTS) release + $(verbose) $(MAKE) relx-post-rel +ifeq ($(RELX_TAR),1) + $(verbose) $(RELX) $(if $(filter 1,$V),-V 3) -c $(RELX_CONFIG) $(RELX_OPTS) tar +endif + +relx-relup: $(RELX) rel-deps app + $(verbose) $(RELX) $(if $(filter 1,$V),-V 3) -c $(RELX_CONFIG) $(RELX_OPTS) release + $(MAKE) relx-post-rel + $(verbose) $(RELX) $(if $(filter 1,$V),-V 3) -c $(RELX_CONFIG) $(RELX_OPTS) relup $(if $(filter 1,$(RELX_TAR)),tar) + +distclean-relx-rel: + $(gen_verbose) rm -rf $(RELX_OUTPUT_DIR) + +# Default hooks. +relx-post-rel:: + $(verbose) : + +# Run target. + +ifeq ($(wildcard $(RELX_CONFIG)),) +run:: +else + +define get_relx_release.erl + {ok, Config} = file:consult("$(call core_native_path,$(RELX_CONFIG))"), + {release, {Name, Vsn0}, _} = lists:keyfind(release, 1, Config), + Vsn = case Vsn0 of + {cmd, Cmd} -> os:cmd(Cmd); + semver -> ""; + {semver, _} -> ""; + VsnStr -> Vsn0 + end, + Extended = case lists:keyfind(extended_start_script, 1, Config) of + {_, true} -> "1"; + _ -> "" + end, + io:format("~s ~s ~s", [Name, Vsn, Extended]), + halt(0). +endef + +RELX_REL := $(shell $(call erlang,$(get_relx_release.erl))) +RELX_REL_NAME := $(word 1,$(RELX_REL)) +RELX_REL_VSN := $(word 2,$(RELX_REL)) +RELX_REL_CMD := $(if $(word 3,$(RELX_REL)),console) + +ifeq ($(PLATFORM),msys2) +RELX_REL_EXT := .cmd +endif + +run:: all + $(verbose) $(RELX_OUTPUT_DIR)/$(RELX_REL_NAME)/bin/$(RELX_REL_NAME)$(RELX_REL_EXT) $(RELX_REL_CMD) + +ifdef RELOAD +rel:: + $(verbose) $(RELX_OUTPUT_DIR)/$(RELX_REL_NAME)/bin/$(RELX_REL_NAME)$(RELX_REL_EXT) ping + $(verbose) $(RELX_OUTPUT_DIR)/$(RELX_REL_NAME)/bin/$(RELX_REL_NAME)$(RELX_REL_EXT) \ + eval "io:format(\"~p~n\", [c:lm()])" +endif + +help:: + $(verbose) printf "%s\n" "" \ + "Relx targets:" \ + " run Compile the project, build the release and run it" + +endif + +# Copyright (c) 2015-2016, Loïc Hoguin +# Copyright (c) 2014, M Robert Martin +# This file is contributed to erlang.mk and subject to the terms of the ISC License. + +.PHONY: shell + +# Configuration. + +SHELL_ERL ?= erl +SHELL_PATHS ?= $(CURDIR)/ebin $(TEST_DIR) +SHELL_OPTS ?= + +ALL_SHELL_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(SHELL_DEPS)) + +# Core targets + +help:: + $(verbose) printf "%s\n" "" \ + "Shell targets:" \ + " shell Run an erlang shell with SHELL_OPTS or reasonable default" + +# Plugin-specific targets. + +$(foreach dep,$(SHELL_DEPS),$(eval $(call dep_target,$(dep)))) + +ifneq ($(SKIP_DEPS),) +build-shell-deps: +else +build-shell-deps: $(ALL_SHELL_DEPS_DIRS) + $(verbose) set -e; for dep in $(ALL_SHELL_DEPS_DIRS) ; do \ + if [ -z "$(strip $(FULL))" ] && [ ! -L $$dep ] && [ -f $$dep/ebin/dep_built ]; then \ + :; \ + else \ + $(MAKE) -C $$dep IS_DEP=1; \ + if [ ! -L $$dep ] && [ -d $$dep/ebin ]; then touch $$dep/ebin/dep_built; fi; \ + fi \ + done +endif + +shell:: build-shell-deps + $(gen_verbose) $(SHELL_ERL) -pa $(SHELL_PATHS) $(SHELL_OPTS) + +# Copyright 2017, Stanislaw Klekot +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: distclean-sphinx sphinx + +# Configuration. + +SPHINX_BUILD ?= sphinx-build +SPHINX_SOURCE ?= doc +SPHINX_CONFDIR ?= +SPHINX_FORMATS ?= html +SPHINX_DOCTREES ?= $(ERLANG_MK_TMP)/sphinx.doctrees +SPHINX_OPTS ?= + +#sphinx_html_opts = +#sphinx_html_output = html +#sphinx_man_opts = +#sphinx_man_output = man +#sphinx_latex_opts = +#sphinx_latex_output = latex + +# Helpers. + +sphinx_build_0 = @echo " SPHINX" $1; $(SPHINX_BUILD) -N -q +sphinx_build_1 = $(SPHINX_BUILD) -N +sphinx_build_2 = set -x; $(SPHINX_BUILD) +sphinx_build = $(sphinx_build_$(V)) + +define sphinx.build +$(call sphinx_build,$1) -b $1 -d $(SPHINX_DOCTREES) $(if $(SPHINX_CONFDIR),-c $(SPHINX_CONFDIR)) $(SPHINX_OPTS) $(sphinx_$1_opts) -- $(SPHINX_SOURCE) $(call sphinx.output,$1) + +endef + +define sphinx.output +$(if $(sphinx_$1_output),$(sphinx_$1_output),$1) +endef + +# Targets. + +ifneq ($(wildcard $(if $(SPHINX_CONFDIR),$(SPHINX_CONFDIR),$(SPHINX_SOURCE))/conf.py),) +docs:: sphinx +distclean:: distclean-sphinx +endif + +help:: + $(verbose) printf "%s\n" "" \ + "Sphinx targets:" \ + " sphinx Generate Sphinx documentation." \ + "" \ + "ReST sources and 'conf.py' file are expected in directory pointed by" \ + "SPHINX_SOURCE ('doc' by default). SPHINX_FORMATS lists formats to build (only" \ + "'html' format is generated by default); target directory can be specified by" \ + 'setting sphinx_$${format}_output, for example: sphinx_html_output = output/html' \ + "Additional Sphinx options can be set in SPHINX_OPTS." + +# Plugin-specific targets. + +sphinx: + $(foreach F,$(SPHINX_FORMATS),$(call sphinx.build,$F)) + +distclean-sphinx: + $(gen_verbose) rm -rf $(filter-out $(SPHINX_SOURCE),$(foreach F,$(SPHINX_FORMATS),$(call sphinx.output,$F))) + +# Copyright (c) 2017, Jean-Sébastien Pédron +# This file is contributed to erlang.mk and subject to the terms of the ISC License. + +.PHONY: show-ERL_LIBS show-ERLC_OPTS show-TEST_ERLC_OPTS + +show-ERL_LIBS: + @echo $(ERL_LIBS) + +show-ERLC_OPTS: + @$(foreach opt,$(ERLC_OPTS) -pa ebin -I include,echo "$(opt)";) + +show-TEST_ERLC_OPTS: + @$(foreach opt,$(TEST_ERLC_OPTS) -pa ebin -I include,echo "$(opt)";) + +# Copyright (c) 2015-2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +ifeq ($(filter triq,$(DEPS) $(TEST_DEPS)),triq) +.PHONY: triq + +# Targets. + +tests:: triq + +define triq_check.erl + $(call cover.erl) + code:add_pathsa([ + "$(call core_native_path,$(CURDIR)/ebin)", + "$(call core_native_path,$(DEPS_DIR)/*/ebin)", + "$(call core_native_path,$(TEST_DIR))"]), + try begin + CoverSetup(), + Res = case $(1) of + all -> [true] =:= lists:usort([triq:check(M) || M <- [$(call comma_list,$(3))]]); + module -> triq:check($(2)); + function -> triq:check($(2)) + end, + CoverExport("$(COVER_DATA_DIR)/triq.coverdata"), + Res + end of + true -> halt(0); + _ -> halt(1) + catch error:undef -> + io:format("Undefined property or module?~n~p~n", [erlang:get_stacktrace()]), + halt(0) + end. +endef + +ifdef t +ifeq (,$(findstring :,$(t))) +triq: test-build cover-data-dir + $(verbose) $(call erlang,$(call triq_check.erl,module,$(t))) +else +triq: test-build cover-data-dir + $(verbose) echo Testing $(t)/0 + $(verbose) $(call erlang,$(call triq_check.erl,function,$(t)())) +endif +else +triq: test-build cover-data-dir + $(eval MODULES := $(patsubst %,'%',$(sort $(notdir $(basename \ + $(wildcard ebin/*.beam) $(call core_find,$(TEST_DIR)/,*.beam)))))) + $(gen_verbose) $(call erlang,$(call triq_check.erl,all,undefined,$(MODULES))) +endif +endif + +# Copyright (c) 2016, Loïc Hoguin +# Copyright (c) 2015, Erlang Solutions Ltd. +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: xref distclean-xref + +# Configuration. + +ifeq ($(XREF_CONFIG),) + XREFR_ARGS := +else + XREFR_ARGS := -c $(XREF_CONFIG) +endif + +XREFR ?= $(CURDIR)/xrefr +export XREFR + +XREFR_URL ?= https://github.com/inaka/xref_runner/releases/download/1.1.0/xrefr + +# Core targets. + +help:: + $(verbose) printf '%s\n' '' \ + 'Xref targets:' \ + ' xref Run Xrefr using $$XREF_CONFIG as config file if defined' + +distclean:: distclean-xref + +# Plugin-specific targets. + +$(XREFR): + $(gen_verbose) $(call core_http_get,$(XREFR),$(XREFR_URL)) + $(verbose) chmod +x $(XREFR) + +xref: deps app $(XREFR) + $(gen_verbose) $(XREFR) $(XREFR_ARGS) + +distclean-xref: + $(gen_verbose) rm -rf $(XREFR) + +# Copyright (c) 2016, Loïc Hoguin +# Copyright (c) 2015, Viktor Söderqvist +# This file is part of erlang.mk and subject to the terms of the ISC License. + +COVER_REPORT_DIR ?= cover +COVER_DATA_DIR ?= $(COVER_REPORT_DIR) + +ifdef COVER +COVER_APPS ?= $(notdir $(ALL_APPS_DIRS)) +COVER_DEPS ?= +endif + +# Code coverage for Common Test. + +ifdef COVER +ifdef CT_RUN +ifneq ($(wildcard $(TEST_DIR)),) +test-build:: $(TEST_DIR)/ct.cover.spec + +$(TEST_DIR)/ct.cover.spec: cover-data-dir + $(gen_verbose) printf "%s\n" \ + "{incl_app, '$(PROJECT)', details}." \ + "{incl_dirs, '$(PROJECT)', [\"$(call core_native_path,$(CURDIR)/ebin)\" \ + $(foreach a,$(COVER_APPS),$(comma) \"$(call core_native_path,$(APPS_DIR)/$a/ebin)\") \ + $(foreach d,$(COVER_DEPS),$(comma) \"$(call core_native_path,$(DEPS_DIR)/$d/ebin)\")]}." \ + '{export,"$(call core_native_path,$(abspath $(COVER_DATA_DIR))/ct.coverdata)"}.' > $@ + +CT_RUN += -cover $(TEST_DIR)/ct.cover.spec +endif +endif +endif + +# Code coverage for other tools. + +ifdef COVER +define cover.erl + CoverSetup = fun() -> + Dirs = ["$(call core_native_path,$(CURDIR)/ebin)" + $(foreach a,$(COVER_APPS),$(comma) "$(call core_native_path,$(APPS_DIR)/$a/ebin)") + $(foreach d,$(COVER_DEPS),$(comma) "$(call core_native_path,$(DEPS_DIR)/$d/ebin)")], + [begin + case filelib:is_dir(Dir) of + false -> false; + true -> + case cover:compile_beam_directory(Dir) of + {error, _} -> halt(1); + _ -> true + end + end + end || Dir <- Dirs] + end, + CoverExport = fun(Filename) -> cover:export(Filename) end, +endef +else +define cover.erl + CoverSetup = fun() -> ok end, + CoverExport = fun(_) -> ok end, +endef +endif + +# Core targets + +ifdef COVER +ifneq ($(COVER_REPORT_DIR),) +tests:: + $(verbose) $(MAKE) --no-print-directory cover-report +endif + +cover-data-dir: | $(COVER_DATA_DIR) + +$(COVER_DATA_DIR): + $(verbose) mkdir -p $(COVER_DATA_DIR) +else +cover-data-dir: +endif + +clean:: coverdata-clean + +ifneq ($(COVER_REPORT_DIR),) +distclean:: cover-report-clean +endif + +help:: + $(verbose) printf "%s\n" "" \ + "Cover targets:" \ + " cover-report Generate a HTML coverage report from previously collected" \ + " cover data." \ + " all.coverdata Merge all coverdata files into all.coverdata." \ + "" \ + "If COVER=1 is set, coverage data is generated by the targets eunit and ct. The" \ + "target tests additionally generates a HTML coverage report from the combined" \ + "coverdata files from each of these testing tools. HTML reports can be disabled" \ + "by setting COVER_REPORT_DIR to empty." + +# Plugin specific targets + +COVERDATA = $(filter-out $(COVER_DATA_DIR)/all.coverdata,$(wildcard $(COVER_DATA_DIR)/*.coverdata)) + +.PHONY: coverdata-clean +coverdata-clean: + $(gen_verbose) rm -f $(COVER_DATA_DIR)/*.coverdata $(TEST_DIR)/ct.cover.spec + +# Merge all coverdata files into one. +define cover_export.erl + $(foreach f,$(COVERDATA),cover:import("$(f)") == ok orelse halt(1),) + cover:export("$(COVER_DATA_DIR)/$@"), halt(0). +endef + +all.coverdata: $(COVERDATA) cover-data-dir + $(gen_verbose) $(call erlang,$(cover_export.erl)) + +# These are only defined if COVER_REPORT_DIR is non-empty. Set COVER_REPORT_DIR to +# empty if you want the coverdata files but not the HTML report. +ifneq ($(COVER_REPORT_DIR),) + +.PHONY: cover-report-clean cover-report + +cover-report-clean: + $(gen_verbose) rm -rf $(COVER_REPORT_DIR) +ifneq ($(COVER_REPORT_DIR),$(COVER_DATA_DIR)) + $(if $(shell ls -A $(COVER_DATA_DIR)/),,$(verbose) rmdir $(COVER_DATA_DIR)) +endif + +ifeq ($(COVERDATA),) +cover-report: +else + +# Modules which include eunit.hrl always contain one line without coverage +# because eunit defines test/0 which is never called. We compensate for this. +EUNIT_HRL_MODS = $(subst $(space),$(comma),$(shell \ + grep -H -e '^\s*-include.*include/eunit\.hrl"' src/*.erl \ + | sed "s/^src\/\(.*\)\.erl:.*/'\1'/" | uniq)) + +define cover_report.erl + $(foreach f,$(COVERDATA),cover:import("$(f)") == ok orelse halt(1),) + Ms = cover:imported_modules(), + [cover:analyse_to_file(M, "$(COVER_REPORT_DIR)/" ++ atom_to_list(M) + ++ ".COVER.html", [html]) || M <- Ms], + Report = [begin {ok, R} = cover:analyse(M, module), R end || M <- Ms], + EunitHrlMods = [$(EUNIT_HRL_MODS)], + Report1 = [{M, {Y, case lists:member(M, EunitHrlMods) of + true -> N - 1; false -> N end}} || {M, {Y, N}} <- Report], + TotalY = lists:sum([Y || {_, {Y, _}} <- Report1]), + TotalN = lists:sum([N || {_, {_, N}} <- Report1]), + Perc = fun(Y, N) -> case Y + N of 0 -> 100; S -> round(100 * Y / S) end end, + TotalPerc = Perc(TotalY, TotalN), + {ok, F} = file:open("$(COVER_REPORT_DIR)/index.html", [write]), + io:format(F, "~n" + "~n" + "Coverage report~n" + "~n", []), + io:format(F, "

Coverage

~n

Total: ~p%

~n", [TotalPerc]), + io:format(F, "~n", []), + [io:format(F, "" + "~n", + [M, M, Perc(Y, N)]) || {M, {Y, N}} <- Report1], + How = "$(subst $(space),$(comma)$(space),$(basename $(COVERDATA)))", + Date = "$(shell date -u "+%Y-%m-%dT%H:%M:%SZ")", + io:format(F, "
ModuleCoverage
~p~p%
~n" + "

Generated using ~s and erlang.mk on ~s.

~n" + "", [How, Date]), + halt(). +endef + +cover-report: + $(verbose) mkdir -p $(COVER_REPORT_DIR) + $(gen_verbose) $(call erlang,$(cover_report.erl)) + +endif +endif # ifneq ($(COVER_REPORT_DIR),) + +# Copyright (c) 2016, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: sfx + +ifdef RELX_REL +ifdef SFX + +# Configuration. + +SFX_ARCHIVE ?= $(RELX_OUTPUT_DIR)/$(RELX_REL_NAME)/$(RELX_REL_NAME)-$(RELX_REL_VSN).tar.gz +SFX_OUTPUT_FILE ?= $(RELX_OUTPUT_DIR)/$(RELX_REL_NAME).run + +# Core targets. + +rel:: sfx + +# Plugin-specific targets. + +define sfx_stub +#!/bin/sh + +TMPDIR=`mktemp -d` +ARCHIVE=`awk '/^__ARCHIVE_BELOW__$$/ {print NR + 1; exit 0;}' $$0` +FILENAME=$$(basename $$0) +REL=$${FILENAME%.*} + +tail -n+$$ARCHIVE $$0 | tar -xzf - -C $$TMPDIR + +$$TMPDIR/bin/$$REL console +RET=$$? + +rm -rf $$TMPDIR + +exit $$RET + +__ARCHIVE_BELOW__ +endef + +sfx: + $(verbose) $(call core_render,sfx_stub,$(SFX_OUTPUT_FILE)) + $(gen_verbose) cat $(SFX_ARCHIVE) >> $(SFX_OUTPUT_FILE) + $(verbose) chmod +x $(SFX_OUTPUT_FILE) + +endif +endif + +# Copyright (c) 2013-2017, Loïc Hoguin +# This file is part of erlang.mk and subject to the terms of the ISC License. + +# External plugins. + +DEP_PLUGINS ?= + +$(foreach p,$(DEP_PLUGINS),\ + $(eval $(if $(findstring /,$p),\ + $(call core_dep_plugin,$p,$(firstword $(subst /, ,$p))),\ + $(call core_dep_plugin,$p/plugins.mk,$p)))) + +help:: help-plugins + +help-plugins:: + $(verbose) : + +# Copyright (c) 2013-2015, Loïc Hoguin +# Copyright (c) 2015-2016, Jean-Sébastien Pédron +# This file is part of erlang.mk and subject to the terms of the ISC License. + +# Fetch dependencies recursively (without building them). + +.PHONY: fetch-deps fetch-doc-deps fetch-rel-deps fetch-test-deps \ + fetch-shell-deps + +.PHONY: $(ERLANG_MK_RECURSIVE_DEPS_LIST) \ + $(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) \ + $(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) \ + $(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) \ + $(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST) + +fetch-deps: $(ERLANG_MK_RECURSIVE_DEPS_LIST) +fetch-doc-deps: $(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) +fetch-rel-deps: $(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) +fetch-test-deps: $(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) +fetch-shell-deps: $(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST) + +ifneq ($(SKIP_DEPS),) +$(ERLANG_MK_RECURSIVE_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST): + $(verbose) :> $@ +else +# By default, we fetch "normal" dependencies. They are also included no +# matter the type of requested dependencies. +# +# $(ALL_DEPS_DIRS) includes $(BUILD_DEPS). + +$(ERLANG_MK_RECURSIVE_DEPS_LIST): $(LOCAL_DEPS_DIRS) $(ALL_DEPS_DIRS) +$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST): $(LOCAL_DEPS_DIRS) $(ALL_DEPS_DIRS) $(ALL_DOC_DEPS_DIRS) +$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST): $(LOCAL_DEPS_DIRS) $(ALL_DEPS_DIRS) $(ALL_REL_DEPS_DIRS) +$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST): $(LOCAL_DEPS_DIRS) $(ALL_DEPS_DIRS) $(ALL_TEST_DEPS_DIRS) +$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST): $(LOCAL_DEPS_DIRS) $(ALL_DEPS_DIRS) $(ALL_SHELL_DEPS_DIRS) + +# Allow to use fetch-deps and $(DEP_TYPES) to fetch multiple types of +# dependencies with a single target. +ifneq ($(filter doc,$(DEP_TYPES)),) +$(ERLANG_MK_RECURSIVE_DEPS_LIST): $(ALL_DOC_DEPS_DIRS) +endif +ifneq ($(filter rel,$(DEP_TYPES)),) +$(ERLANG_MK_RECURSIVE_DEPS_LIST): $(ALL_REL_DEPS_DIRS) +endif +ifneq ($(filter test,$(DEP_TYPES)),) +$(ERLANG_MK_RECURSIVE_DEPS_LIST): $(ALL_TEST_DEPS_DIRS) +endif +ifneq ($(filter shell,$(DEP_TYPES)),) +$(ERLANG_MK_RECURSIVE_DEPS_LIST): $(ALL_SHELL_DEPS_DIRS) +endif + +ERLANG_MK_RECURSIVE_TMP_LIST := $(abspath $(ERLANG_MK_TMP)/recursive-tmp-deps-$(shell echo $$PPID).log) + +$(ERLANG_MK_RECURSIVE_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST): | $(ERLANG_MK_TMP) +ifeq ($(IS_APP)$(IS_DEP),) + $(verbose) rm -f $(ERLANG_MK_RECURSIVE_TMP_LIST) +endif + $(verbose) touch $(ERLANG_MK_RECURSIVE_TMP_LIST) + $(verbose) set -e; for dep in $^ ; do \ + if ! grep -qs ^$$dep$$ $(ERLANG_MK_RECURSIVE_TMP_LIST); then \ + echo $$dep >> $(ERLANG_MK_RECURSIVE_TMP_LIST); \ + if grep -qs -E "^[[:blank:]]*include[[:blank:]]+(erlang\.mk|.*/erlang\.mk|.*ERLANG_MK_FILENAME.*)$$" \ + $$dep/GNUmakefile $$dep/makefile $$dep/Makefile; then \ + $(MAKE) -C $$dep fetch-deps \ + IS_DEP=1 \ + ERLANG_MK_RECURSIVE_TMP_LIST=$(ERLANG_MK_RECURSIVE_TMP_LIST); \ + fi \ + fi \ + done +ifeq ($(IS_APP)$(IS_DEP),) + $(verbose) sort < $(ERLANG_MK_RECURSIVE_TMP_LIST) | \ + uniq > $(ERLANG_MK_RECURSIVE_TMP_LIST).sorted + $(verbose) cmp -s $(ERLANG_MK_RECURSIVE_TMP_LIST).sorted $@ \ + || mv $(ERLANG_MK_RECURSIVE_TMP_LIST).sorted $@ + $(verbose) rm -f $(ERLANG_MK_RECURSIVE_TMP_LIST).sorted + $(verbose) rm $(ERLANG_MK_RECURSIVE_TMP_LIST) +endif +endif # ifneq ($(SKIP_DEPS),) + +# List dependencies recursively. + +.PHONY: list-deps list-doc-deps list-rel-deps list-test-deps \ + list-shell-deps + +list-deps: $(ERLANG_MK_RECURSIVE_DEPS_LIST) +list-doc-deps: $(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) +list-rel-deps: $(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) +list-test-deps: $(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) +list-shell-deps: $(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST) + +list-deps list-doc-deps list-rel-deps list-test-deps list-shell-deps: + $(verbose) cat $^ + +# Query dependencies recursively. + +.PHONY: query-deps query-doc-deps query-rel-deps query-test-deps \ + query-shell-deps + +QUERY ?= name fetch_method repo version + +define query_target +$(1): $(2) clean-tmp-query.log +ifeq ($(IS_APP)$(IS_DEP),) + $(verbose) rm -f $(4) +endif + $(verbose) $(foreach dep,$(3),\ + echo $(PROJECT): $(foreach q,$(QUERY),$(call query_$(q),$(dep))) >> $(4) ;) + $(if $(filter-out query-deps,$(1)),,\ + $(verbose) set -e; for dep in $(3) ; do \ + if grep -qs ^$$$$dep$$$$ $(ERLANG_MK_TMP)/query.log; then \ + :; \ + else \ + echo $$$$dep >> $(ERLANG_MK_TMP)/query.log; \ + $(MAKE) -C $(DEPS_DIR)/$$$$dep $$@ QUERY="$(QUERY)" IS_DEP=1 || true; \ + fi \ + done) +ifeq ($(IS_APP)$(IS_DEP),) + $(verbose) touch $(4) + $(verbose) cat $(4) +endif +endef + +clean-tmp-query.log: +ifeq ($(IS_DEP),) + $(verbose) rm -f $(ERLANG_MK_TMP)/query.log +endif + +$(eval $(call query_target,query-deps,$(ERLANG_MK_RECURSIVE_DEPS_LIST),$(BUILD_DEPS) $(DEPS),$(ERLANG_MK_QUERY_DEPS_FILE))) +$(eval $(call query_target,query-doc-deps,$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST),$(DOC_DEPS),$(ERLANG_MK_QUERY_DOC_DEPS_FILE))) +$(eval $(call query_target,query-rel-deps,$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST),$(REL_DEPS),$(ERLANG_MK_QUERY_REL_DEPS_FILE))) +$(eval $(call query_target,query-test-deps,$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST),$(TEST_DEPS),$(ERLANG_MK_QUERY_TEST_DEPS_FILE))) +$(eval $(call query_target,query-shell-deps,$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST),$(SHELL_DEPS),$(ERLANG_MK_QUERY_SHELL_DEPS_FILE))) diff --git a/examples/10k.csv.gz b/examples/10k.csv.gz deleted file mode 100644 index 8582ac3222f500f12ba11615e988ffe0b0b7d3c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67353 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 &YOAGrBt<^t+M{rJon{ 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 Q`v3l!MSUMPEMvg=Kdwl*wg3PC diff --git a/examples/benchmark b/examples/benchmark deleted file mode 100755 index 0bd50fe..0000000 --- a/examples/benchmark +++ /dev/null @@ -1,41 +0,0 @@ -#! /usr/bin/env escript -%%! -pa ./ebin/ -pa ./deps/ejson/ebin - -main(Args) -> - case Args of - [File] -> process_it(File); - _ -> io:format("Wrong usage: file~n") - end. - -get_timestamp() -> - {Megasecs, Secs, Microsecs} = erlang:now(), - (Megasecs * 1000000) + Secs + (Microsecs / 1000000). - -label_if_1k(N) -> - Modulo = N rem 1000, - case Modulo of - 0 -> - io:format("--> ~p parsed rows~n", [N]); - _ -> - ok - end. - -process_it(File) -> - {ok, IoDevice} = file:open(File, [read, compressed]), - - DisplayRow = fun(_Element, Counter) -> - label_if_1k(Counter), - Counter + 1 - end, - - Begin = get_timestamp(), - {ok, ProcessedRows} = ecsv:process_csv_file_with(IoDevice, DisplayRow, 0), - End = get_timestamp(), - - Duration = End - Begin, - Rate = ProcessedRows / Duration, - - io:format("# processed rows ~p in ~p s~n", [ProcessedRows, Duration]), - io:format("Rate: ~p item/s~n", [Rate]), - - ok. diff --git a/examples/sample.csv b/examples/sample.csv deleted file mode 100644 index b581ec5..0000000 --- a/examples/sample.csv +++ /dev/null @@ -1,3 +0,0 @@ -SC_Group_ID,SC_Group_Desc,SC_GroupCommod_ID,SC_GroupCommod_Desc,SC_Geography_ID,SortOrder,SC_GeographyIndented_Desc,SC_Commodity_ID,SC_Commodity_Desc,SC_Attribute_ID,SC_Attribute_Desc,SC_Unit_ID,SC_Unit_Desc,Year_ID,SC_Frequency_ID,SC_Frequency_Desc,Timeperiod_ID,Timeperiod_Desc,Amount -2,"Supply and use",9,"Barley",1,0.800,"United States",1,"Barley",34,"Imports, trade year",7,"1,000 metric tons",1960,3,"Annual",114,"MY Oct-Sep",248 -2,"Supply and use",9,"Barley",1,0.800,"United States",1,"Barley",34,"Imports, trade year",7,"1,000 metric tons",1961,3,"Annual",114,"MY Oct-Sep",326 diff --git a/rebar b/rebar deleted file mode 100755 index 7f01532f8d4f46dad8e25651b229103e7e030579..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109352 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 z zs6cucq3h4^9d_!A=aIS=7SR=J8mU{P4;Kp!SxpB>M!E^15CohU!M#4`G

V9~m0-tS!D@1u=^;gahP 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 ogahEeQ#@c2I1_;(ktH2M!ng+y*zrLiV!*Eo@Ms"). diff --git a/src/ecsv_parser.erl b/src/ecsv_parser.erl index be4e706..a55d7c5 100644 --- a/src/ecsv_parser.erl +++ b/src/ecsv_parser.erl @@ -135,88 +135,71 @@ do_ready( PState#pstate{current_value=[Char | CurrentValue]} end. -do_in_quotes( - Input, - #pstate{ - current_line=CurrentLine, - current_value=CurrentValue, - process_fun=ProcessingFun, - process_fun_state=ProcessingFunState - }=PState - ) -> +do_in_quotes(Input, #pstate{current_value = CurrentValue} = PState) -> case Input of - {eof} -> - NewLine = lists:reverse([lists:reverse(CurrentValue) | CurrentLine]), - UpdatedProcessingFunState = - process_new_line(ProcessingFun, NewLine, ProcessingFunState), - UpdatedProcessingFunState1 = - ProcessingFun({eof}, UpdatedProcessingFunState), - PState#pstate{ - state=eof, - current_line=[], - current_value=[], - process_fun_state=UpdatedProcessingFunState1 - }; + {eof} -> on_eof(on_new_line(PState)); {char, Char} when Char == $" -> %% Handle the case when there is an escaped double quote %% in the field - case CurrentValue of - [$\\ | V] -> - PState#pstate{current_value=[Char | V]}; - _ -> - PState#pstate{ - state=skip_to_delimiter, - current_line=[lists:reverse(CurrentValue) | CurrentLine], - current_value=[] - } - end; + PState#pstate{ + state=skip_to_delimiter, + current_value=CurrentValue + }; {char, Char} -> + % io:format("do_in_quotes: ~s~n", [ lists:reverse([Char | CurrentValue]) ]), PState#pstate{current_value=[Char | CurrentValue]} end. -do_skip_to_delimiter( - Input, - #pstate{ - opts=Opts, - current_line=CurrentLine, - current_value=CurrentValue, - process_fun=ProcessingFun, - process_fun_state=ProcessingFunState - }=PState - ) -> +do_skip_to_delimiter(Input, #pstate{ + opts = Opts, + current_line = CurrentLine, + current_value = CurrentValue + } = PState) -> case Input of - {eof} -> - NewLine = lists:reverse([lists:reverse(CurrentValue) | CurrentLine]), - UpdatedProcessingFunState = - process_new_line(ProcessingFun, NewLine, ProcessingFunState), - UpdatedProcessingFunState1 = - ProcessingFun({eof}, UpdatedProcessingFunState), + {eof} -> on_eof(on_new_line(PState)); + {char, Char} when (Char == $\n) -> on_new_line(PState); + {char, Char} when (Char == Opts#ecsv_opts.delimiter) -> PState#pstate{ - state=eof, - current_line=[], - current_value=[], - process_fun_state=UpdatedProcessingFunState1 - }; - {char, Char} when Char == Opts#ecsv_opts.delimiter -> - PState#pstate{ - state=ready, - current_value=[] + state = ready, + current_value = [], + current_line = [lists:reverse(CurrentValue) | CurrentLine] }; - {char, Char} when Char == $\n -> - % a new line has been parsed: time to send it back - NewLine = lists:reverse(CurrentLine), - UpdatedProcessingFunState = - process_new_line(ProcessingFun, NewLine, ProcessingFunState), + {char, Char} -> + % io:format("do_skip_to_delimiter: ~s~n", [ lists:reverse([Char | CurrentValue]) ]), PState#pstate{ - state=ready, - current_line=[], - current_value=[], - process_fun_state=UpdatedProcessingFunState - }; - {char, _} -> - PState + state = in_quotes, + current_value = [Char | CurrentValue] + } end. +on_new_line(#pstate{ + current_line = CurrentLine, + current_value = CurrentValue, + process_fun = ProcessingFun, + process_fun_state = ProcessingFunState + } = PState) -> + NewLine = lists:reverse([lists:reverse(CurrentValue) | CurrentLine]), + UpdatedProcessingFunState = + process_new_line(ProcessingFun, NewLine, ProcessingFunState), + PState#pstate{ + state = ready, + current_line = [], + current_value = [], + process_fun_state = UpdatedProcessingFunState + }. + +on_eof(#pstate{ + process_fun = ProcessingFun, + process_fun_state = ProcessingFunState + } = PState) -> + UpdatedProcessingFunState = ProcessingFun({eof}, ProcessingFunState), + PState#pstate{ + state = eof, + current_line = [], + current_value = [], + process_fun_state = UpdatedProcessingFunState + }. + process_new_line(_ProcessingFun, [], State) -> % ignore empty lines State; From f8dc3bafc536463b2dee1a3d10cbd64e273bb78f Mon Sep 17 00:00:00 2001 From: Pankaj Soni Date: Thu, 23 Jul 2020 16:18:20 +0530 Subject: [PATCH 2/5] readd license --- LICENSE | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7347179 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +2011 (c) Nicolas R Dufour + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. From cfeaa2eda53e9e3a8b3cc5718f4254984645af43 Mon Sep 17 00:00:00 2001 From: Pankaj Soni Date: Mon, 10 Aug 2020 22:13:09 +0530 Subject: [PATCH 3/5] escape " and \ --- src/ecsv_parser.erl | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/ecsv_parser.erl b/src/ecsv_parser.erl index a55d7c5..f630562 100644 --- a/src/ecsv_parser.erl +++ b/src/ecsv_parser.erl @@ -1,4 +1,3 @@ - % This file is part of ecsv released under the MIT license. % See the LICENSE file for more information. @@ -139,14 +138,25 @@ do_in_quotes(Input, #pstate{current_value = CurrentValue} = PState) -> case Input of {eof} -> on_eof(on_new_line(PState)); {char, Char} when Char == $" -> - %% Handle the case when there is an escaped double quote - %% in the field - PState#pstate{ - state=skip_to_delimiter, - current_value=CurrentValue - }; + case CurrentValue of + [ $\\ | TCurrentValue] -> + %% Handle the case when there is an escaped double quote in the field + io:format("do_in_quotes:2: ~p~n", [ lists:reverse([Char | TCurrentValue]) ]), + PState#pstate{current_value=[Char | TCurrentValue]}; + _ -> + io:format("do_in_quotes:3: ~p~n", [ lists:reverse(CurrentValue) ]), + PState#pstate{ + state=skip_to_delimiter, + current_value=CurrentValue + } + end; + {char, Char} when Char == $\\ -> + case CurrentValue of + [ $\\ | _] -> PState; + _ -> PState#pstate{current_value=[Char | CurrentValue]} + end; {char, Char} -> - % io:format("do_in_quotes: ~s~n", [ lists:reverse([Char | CurrentValue]) ]), + io:format("do_in_quotes:1: ~p~n", [ lists:reverse([Char | CurrentValue]) ]), PState#pstate{current_value=[Char | CurrentValue]} end. @@ -165,7 +175,7 @@ do_skip_to_delimiter(Input, #pstate{ current_line = [lists:reverse(CurrentValue) | CurrentLine] }; {char, Char} -> - % io:format("do_skip_to_delimiter: ~s~n", [ lists:reverse([Char | CurrentValue]) ]), + io:format("do_skip_to_delimiter: ~s~n", [ lists:reverse([Char | CurrentValue]) ]), PState#pstate{ state = in_quotes, current_value = [Char | CurrentValue] From 02e947b25cd1d617fbb18be191b3eb504c6b25b5 Mon Sep 17 00:00:00 2001 From: Pankaj Soni Date: Mon, 10 Aug 2020 22:15:46 +0530 Subject: [PATCH 4/5] rem io format --- src/ecsv_parser.erl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/ecsv_parser.erl b/src/ecsv_parser.erl index f630562..88c97e5 100644 --- a/src/ecsv_parser.erl +++ b/src/ecsv_parser.erl @@ -141,10 +141,8 @@ do_in_quotes(Input, #pstate{current_value = CurrentValue} = PState) -> case CurrentValue of [ $\\ | TCurrentValue] -> %% Handle the case when there is an escaped double quote in the field - io:format("do_in_quotes:2: ~p~n", [ lists:reverse([Char | TCurrentValue]) ]), PState#pstate{current_value=[Char | TCurrentValue]}; _ -> - io:format("do_in_quotes:3: ~p~n", [ lists:reverse(CurrentValue) ]), PState#pstate{ state=skip_to_delimiter, current_value=CurrentValue @@ -156,7 +154,6 @@ do_in_quotes(Input, #pstate{current_value = CurrentValue} = PState) -> _ -> PState#pstate{current_value=[Char | CurrentValue]} end; {char, Char} -> - io:format("do_in_quotes:1: ~p~n", [ lists:reverse([Char | CurrentValue]) ]), PState#pstate{current_value=[Char | CurrentValue]} end. @@ -175,7 +172,6 @@ do_skip_to_delimiter(Input, #pstate{ current_line = [lists:reverse(CurrentValue) | CurrentLine] }; {char, Char} -> - io:format("do_skip_to_delimiter: ~s~n", [ lists:reverse([Char | CurrentValue]) ]), PState#pstate{ state = in_quotes, current_value = [Char | CurrentValue] From b444735841397c972016066bc8fe88ab0949a737 Mon Sep 17 00:00:00 2001 From: Pankaj Soni Date: Mon, 10 Aug 2020 22:47:07 +0530 Subject: [PATCH 5/5] escape \ --- src/ecsv_parser.erl | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/ecsv_parser.erl b/src/ecsv_parser.erl index 88c97e5..bf40578 100644 --- a/src/ecsv_parser.erl +++ b/src/ecsv_parser.erl @@ -28,6 +28,7 @@ -record(pstate, { state, % ready, in_quotes, skip_to_delimiter, eof + skipped_backslash, current_line, current_value, opts, @@ -50,6 +51,7 @@ init(ProcessingFun, ProcessingFunInitState) -> init(Opts, ProcessingFun, ProcessingFunInitState) -> #pstate{ state = ready, + skipped_backslash = true, current_line = [], current_value = [], opts = Opts, @@ -111,11 +113,12 @@ do_ready( {char, Char} when (Char == $") -> % pass an empty string to in_quotes as we do not want the % preceeding characters to be included, only those in quotes - PState#pstate{state=in_quotes, current_value=[]}; + PState#pstate{state=in_quotes, current_value=[], skipped_backslash = true}; {char, Char} when Char == Delimiter -> PState#pstate{ current_line=[lists:reverse(CurrentValue) | CurrentLine], - current_value=[] + current_value=[], + skipped_backslash = true }; {char, Char} when Char == $\n -> % a new line has been parsed: time to send it back @@ -135,26 +138,44 @@ do_ready( end. do_in_quotes(Input, #pstate{current_value = CurrentValue} = PState) -> + %io:format("input ~p~n", [Input]), case Input of {eof} -> on_eof(on_new_line(PState)); {char, Char} when Char == $" -> case CurrentValue of - [ $\\ | TCurrentValue] -> + [ $\\ | TCurrentValue] when (PState#pstate.skipped_backslash == false) -> %% Handle the case when there is an escaped double quote in the field - PState#pstate{current_value=[Char | TCurrentValue]}; + %io:format("do_in_quotes:2: ~p~n", [ lists:reverse([Char | TCurrentValue]) ]), + PState#pstate{ + current_value=[Char | TCurrentValue], + skipped_backslash = true + }; _ -> + %io:format("do_in_quotes:3: ~p~n", [ lists:reverse(CurrentValue) ]), PState#pstate{ - state=skip_to_delimiter, - current_value=CurrentValue + state = skip_to_delimiter, + current_value = CurrentValue, + skipped_backslash = true } end; {char, Char} when Char == $\\ -> + %io:format("do_in_quotes:5: ~p~n", [ PState#pstate.skipped_backslash ] ), case CurrentValue of - [ $\\ | _] -> PState; - _ -> PState#pstate{current_value=[Char | CurrentValue]} + [ $\\ | _] when (PState#pstate.skipped_backslash == false) -> + PState#pstate{skipped_backslash = true}; + _ -> + %io:format("do_in_quotes:6: ~p~n", [ lists:reverse([Char | CurrentValue]) ]), + PState#pstate{ + current_value=[Char | CurrentValue], + skipped_backslash = false + } end; {char, Char} -> - PState#pstate{current_value=[Char | CurrentValue]} + %io:format("do_in_quotes:1: ~p~n", [ lists:reverse([Char | CurrentValue]) ]), + PState#pstate{ + current_value=[Char | CurrentValue], + skipped_backslash = true + } end. do_skip_to_delimiter(Input, #pstate{ @@ -172,6 +193,7 @@ do_skip_to_delimiter(Input, #pstate{ current_line = [lists:reverse(CurrentValue) | CurrentLine] }; {char, Char} -> + %io:format("do_skip_to_delimiter: ~s~n", [ lists:reverse([Char | CurrentValue]) ]), PState#pstate{ state = in_quotes, current_value = [Char | CurrentValue]