mirror of
https://github.com/valitydev/erlang-templates.git
synced 2024-11-06 10:35:21 +00:00
Feat: Library template (#22)
* docs: Update README link to rebar3 templates * refactor: switch to default elvis rulesets * feat: more comprehensive gitignore in templates * feat: Add erlang_ls config * feat: Add editorconfig * refactor: split templates in common and service parts * feat: Add rebar3_lint to service/rebar.config * refactor: move rebar script to service templates * feat: Add shell to service Makefile * refactor: move service-specific elvis config * refactor: Use plugin-based linter in service Makefile * feat: Add rebar.config for file formatting * feat: Add library templates * refactor: Structure service template * docs: Rewrite docs for library * deps: Update plugin versions * ci: Fix caching on local `act` for lib templates * fix: remove unnecesary distclean dirs for cleaning * test: Add test jobs for library template * deps: update build_utils * fix: I've fixed my tab settings * feat: Wercker -> build_utils+Jenkins for service * ci: Fix wc_gen commands * fix: format service erl templates * fix: another try at jenkinsfile * ci: move pipeline defs * ci: move build_utils init * ci: submodule -> clone build_utils * fix: Use build_utils to test library template as well * ci: Fix make arg order * ci: cp Makefile.ci and optimize repo Makefile * ci: Fix Makefile.ci path * ci: Pass service docker-files to lib for testing * feat: Remove custom macro name rules * ci: fix typo * ci: fix path typo * ci: change chmod pos * fix: Remove erlang_ls and ext. gitignore
This commit is contained in:
parent
422fb39fad
commit
067f1e3921
3
.gitignore
vendored
3
.gitignore
vendored
@ -5,4 +5,7 @@
|
||||
.DS_Store
|
||||
snakeoil
|
||||
Dockerfile
|
||||
_build
|
||||
|
||||
# Rebar is only used for erlfmt: lock file has no meaning
|
||||
rebar.lock
|
||||
|
105
Jenkinsfile
vendored
105
Jenkinsfile
vendored
@ -9,13 +9,28 @@ def finalHook = {
|
||||
}
|
||||
|
||||
build('erlang-service-template', 'docker-host', finalHook) {
|
||||
runStage('clone build_utils') {
|
||||
withGithubSshCredentials {
|
||||
sh "git clone git@github.com:rbkmoney/build_utils.git build_utils"
|
||||
}
|
||||
}
|
||||
|
||||
def pipeDefault
|
||||
def withWsCache
|
||||
runStage('load library pipeline') {
|
||||
env.JENKINS_LIB = "build_utils/jenkins_lib"
|
||||
pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy")
|
||||
withWsCache = load("${env.JENKINS_LIB}/withWsCache.groovy")
|
||||
}
|
||||
|
||||
// erlang-service-template
|
||||
ws {
|
||||
try {
|
||||
checkoutRepo()
|
||||
loadBuildUtils()
|
||||
|
||||
runStage('generate erlang service: snakeoil') {
|
||||
sh 'make wc_gen'
|
||||
sh 'make wc_gen_service'
|
||||
}
|
||||
|
||||
runStage('archive snakeoil') {
|
||||
@ -48,14 +63,6 @@ build('erlang-service-template', 'docker-host', finalHook) {
|
||||
}
|
||||
}
|
||||
|
||||
def pipeDefault
|
||||
def withWsCache
|
||||
runStage('load service pipeline') {
|
||||
env.JENKINS_LIB = "build_utils/jenkins_lib"
|
||||
pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy")
|
||||
withWsCache = load("${env.JENKINS_LIB}/withWsCache.groovy")
|
||||
}
|
||||
|
||||
pipeDefault() {
|
||||
def imageTags = "BASE_IMAGE_TAG=51bd5f25d00cbf75616e2d672601dfe7351dcaa4 BUILD_IMAGE_TAG=61a001bbb48128895735a3ac35b0858484fdb2eb"
|
||||
|
||||
@ -67,6 +74,9 @@ build('erlang-service-template', 'docker-host', finalHook) {
|
||||
runStage('lint service') {
|
||||
sh "make wc_lint ${imageTags}"
|
||||
}
|
||||
runStage('check formatting for service') {
|
||||
sh "make wc_check_format ${imageTags}"
|
||||
}
|
||||
runStage('xref service') {
|
||||
sh "make wc_xref ${imageTags}"
|
||||
}
|
||||
@ -85,5 +95,80 @@ build('erlang-service-template', 'docker-host', finalHook) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// erlang-library-template
|
||||
ws {
|
||||
try {
|
||||
checkoutRepo()
|
||||
loadBuildUtils()
|
||||
|
||||
runStage('generate erlang library: trickster') {
|
||||
sh 'make wc_gen_library'
|
||||
sh """
|
||||
cp \\
|
||||
library-templates/Makefile.ci \\
|
||||
service-templates/Dockerfile.sh \\
|
||||
service-templates/docker-compose.sh \\
|
||||
trickster/
|
||||
"""
|
||||
}
|
||||
|
||||
runStage('archive trickster') {
|
||||
archive 'trickster/'
|
||||
}
|
||||
} finally {
|
||||
runStage('cleanup sub ws') {
|
||||
sh 'rm -rf * .* || echo ignore'
|
||||
}
|
||||
}
|
||||
} //close other ws
|
||||
|
||||
runStage('unarchive trickster') {
|
||||
unarchive mapping: ['trickster/': '.']
|
||||
sh 'chmod 755 trickster/Dockerfile.sh trickster/docker-compose.sh'
|
||||
}
|
||||
|
||||
dir('trickster') {
|
||||
runStage('init git repo') {
|
||||
sh 'git init'
|
||||
sh 'git config user.email "$CHANGE_AUTHOR_EMAIL"'
|
||||
sh 'git config user.name "$COMMIT_AUTHOR"'
|
||||
sh 'git add README.md'
|
||||
sh 'git commit -m "Initial commit"'
|
||||
}
|
||||
|
||||
runStage('add git submodule') {
|
||||
withGithubSshCredentials {
|
||||
sh "git submodule add -b master git@github.com:rbkmoney/build_utils.git build_utils"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pipeDefault() {
|
||||
def imageTags = "BASE_IMAGE_TAG=51bd5f25d00cbf75616e2d672601dfe7351dcaa4 BUILD_IMAGE_TAG=61a001bbb48128895735a3ac35b0858484fdb2eb"
|
||||
|
||||
runStage('compile library') {
|
||||
withGithubPrivkey {
|
||||
sh "make --file=Makefile.ci wc_compile ${imageTags}"
|
||||
}
|
||||
}
|
||||
runStage('lint library') {
|
||||
sh "make --file=Makefile.ci wc_lint ${imageTags}"
|
||||
}
|
||||
runStage('check formatting for library') {
|
||||
sh "make --file=Makefile.ci wc_check_format ${imageTags}"
|
||||
}
|
||||
runStage('xref library') {
|
||||
sh "make --file=Makefile.ci wc_xref ${imageTags}"
|
||||
}
|
||||
runStage('dialyze library') {
|
||||
withWsCache("_build/default/rebar3_23.2.3_plt") {
|
||||
sh "make --file=Makefile.ci wc_dialyze ${imageTags}"
|
||||
}
|
||||
}
|
||||
runStage('test library') {
|
||||
sh "make --file=Makefile.ci wdeps_test ${imageTags}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
Makefile
12
Makefile
@ -7,7 +7,7 @@ SERVICE_NAME := service_erlang
|
||||
BUILD_IMAGE_NAME := build-erlang
|
||||
BUILD_IMAGE_TAG := 61a001bbb48128895735a3ac35b0858484fdb2eb
|
||||
|
||||
CALL_W_CONTAINER := all gen submodules clean
|
||||
CALL_W_CONTAINER := all gen_service gen_library submodules clean
|
||||
|
||||
all: gen
|
||||
|
||||
@ -21,13 +21,17 @@ $(SUBTARGETS): %/.git: %
|
||||
|
||||
submodules: $(SUBTARGETS)
|
||||
|
||||
add_template:
|
||||
~/.config/rebar3/templates:
|
||||
mkdir -p ~/.config/rebar3/templates
|
||||
cp -rv ./* ~/.config/rebar3/templates
|
||||
|
||||
gen: add_template
|
||||
add_template: ~/.config/rebar3/templates
|
||||
|
||||
gen_service: add_template
|
||||
rebar3 new erlang-service name=snakeoil
|
||||
|
||||
gen_library: add_template
|
||||
rebar3 new erlang-service name=trickster
|
||||
|
||||
clean:
|
||||
rm Dockerfile
|
||||
|
||||
|
@ -33,7 +33,6 @@ $ git submodule init
|
||||
> * GNU Make
|
||||
> * [rebar3](http://www.rebar3.org/)
|
||||
> * [elvis](https://github.com/inaka/elvis/releases)
|
||||
> * [wercker cli](http://devcenter.wercker.com/cli/index.html)
|
||||
>
|
||||
> К счастью, теперь все это доступно в build образе, работать с которым легко и удобно через `make`:
|
||||
> * wc_<target> - запустить в build контейнере
|
||||
@ -60,4 +59,4 @@ erlang-service:
|
||||
apps_dir="apps" (Directory where applications will be created if needed)
|
||||
```
|
||||
|
||||
В случае необходимости доработки в первую очередь обращайтесь к [официальной документации](http://www.rebar3.org/docs/using-templates).
|
||||
В случае необходимости доработки в первую очередь обращайтесь к [официальной документации](http://rebar3.org/docs/tutorials/templates/).
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit e1318727d4d0c3e48f5122bf3197158b6695f50e
|
||||
Subproject commit 24aa772730be966667adb285a09fcb494d4f218e
|
8
common-templates/editorconfig
Normal file
8
common-templates/editorconfig
Normal file
@ -0,0 +1,8 @@
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
trim_trailing_whitespace = true
|
||||
max_line_length = 120
|
13
common-templates/gitignore
Normal file
13
common-templates/gitignore
Normal file
@ -0,0 +1,13 @@
|
||||
# Build artifacts
|
||||
/_build/
|
||||
*.o
|
||||
*.beam
|
||||
*.plt
|
||||
|
||||
# Run artifacts
|
||||
erl_crash.dump
|
||||
log
|
||||
|
||||
# Files generated from scripts
|
||||
Dockerfile
|
||||
docker-compose.yml
|
35
erlang-library.template
Normal file
35
erlang-library.template
Normal file
@ -0,0 +1,35 @@
|
||||
{description, "Erlang OTP Library"}.
|
||||
|
||||
{variables, [
|
||||
{name, "myapp", "Name of the library, an application with this name will also be created"},
|
||||
{description, "A library that does something", "Short description of purpose of the library"},
|
||||
{version, "1", "Initial version string"}
|
||||
]}.
|
||||
|
||||
%% Project and plugins
|
||||
{template, "library-templates/rebar.config", "{{name}}/rebar.config"}.
|
||||
{template, "library-templates/elvis.config", "{{name}}/elvis.config"}.
|
||||
{dir, "{{name}}/include"}.
|
||||
{dir, "{{name}}/test"}.
|
||||
|
||||
%% Code
|
||||
{template, "library-templates/src/app.app.src", "{{name}}/src/{{name}}.app.src"}.
|
||||
{template, "library-templates/src/app.erl", "{{name}}/src/{{name}}.erl"}.
|
||||
|
||||
%% Build
|
||||
{template, "library-templates/Makefile", "{{name}}/Makefile"}.
|
||||
|
||||
%% VCS setup
|
||||
{template, "common-templates/gitignore", "{{name}}/.gitignore"}.
|
||||
|
||||
%% Docs
|
||||
{template, "library-templates/README.md", "{{name}}/README.md"}.
|
||||
|
||||
%% Tools
|
||||
{file, "common-templates/editorconfig", "{{name}}/.editorconfig"}.
|
||||
|
||||
%% CI/CD
|
||||
{file, "library-templates/github/workflows/code-checks.yml", "{{name}}/.github/workflows/code-checks.yml"}.
|
||||
|
||||
%% Licenses
|
||||
{file, "common-templates/LICENSE", "{{name}}/LICENSE"}.
|
@ -1,12 +0,0 @@
|
||||
# general
|
||||
log
|
||||
/_build/
|
||||
*~
|
||||
erl_crash.dump
|
||||
.tags*
|
||||
*.sublime-workspace
|
||||
.DS_Store
|
||||
.edts
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
|
@ -1,5 +0,0 @@
|
||||
case os:getenv("WERCKER_CACHE_DIR") of
|
||||
false -> CONFIG;
|
||||
[] -> CONFIG;
|
||||
Dir -> lists:keystore(global_rebar_dir, 1, CONFIG, {global_rebar_dir, Dir})
|
||||
end.
|
@ -6,22 +6,37 @@
|
||||
{version, "1", "Initial version string"}
|
||||
]}.
|
||||
|
||||
{template, "erlang-service-files/apps/app/src/app.app.src", "{{name}}/{{apps_dir}}/{{name}}/src/{{name}}.app.src"}.
|
||||
{template, "erlang-service-files/apps/app/src/app.erl", "{{name}}/{{apps_dir}}/{{name}}/src/{{name}}.erl"}.
|
||||
{template, "erlang-service-files/apps/app/test/app_tests_SUITE.erl", "{{name}}/{{apps_dir}}/{{name}}/test/{{name}}_tests_SUITE.erl"}.
|
||||
{template, "erlang-service-files/config/sys.config", "{{name}}/config/sys.config"}.
|
||||
{template, "erlang-service-files/config/vm.args", "{{name}}/config/vm.args"}.
|
||||
{template, "erlang-service-files/doc/index.md", "{{name}}/doc/index.md"}.
|
||||
{template, "erlang-service-files/rebar.config", "{{name}}/rebar.config"}.
|
||||
{template, "erlang-service-files/elvis.config", "{{name}}/elvis.config"}.
|
||||
{template, "erlang-service-files/rebar.config.script", "{{name}}/rebar.config.script"}.
|
||||
{template, "erlang-service-files/gitignore", "{{name}}/.gitignore"}.
|
||||
{template, "erlang-service-files/README.md", "{{name}}/README.md"}.
|
||||
{template, "erlang-service-files/Makefile", "{{name}}/Makefile"}.
|
||||
{template, "erlang-service-files/Jenkinsfile", "{{name}}/Jenkinsfile"}.
|
||||
{template, "erlang-service-files/Dockerfile.sh", "{{name}}/Dockerfile.sh"}.
|
||||
{chmod, "{{name}}/Dockerfile.sh", 8#755}.
|
||||
{template, "erlang-service-files/docker-compose.sh", "{{name}}/docker-compose.sh"}.
|
||||
{chmod, "{{name}}/docker-compose.sh", 8#755}.
|
||||
{file, "erlang-service-files/LICENSE", "{{name}}/LICENSE"}.
|
||||
%% Project and plugins
|
||||
{template, "service-templates/rebar.config", "{{name}}/rebar.config"}.
|
||||
{template, "service-templates/elvis.config", "{{name}}/elvis.config"}.
|
||||
|
||||
%% Code
|
||||
{template, "service-templates/apps/app/src/app.app.src", "{{name}}/{{apps_dir}}/{{name}}/src/{{name}}.app.src"}.
|
||||
{template, "service-templates/apps/app/src/app.erl", "{{name}}/{{apps_dir}}/{{name}}/src/{{name}}.erl"}.
|
||||
{template, "service-templates/apps/app/test/app_tests_SUITE.erl",
|
||||
"{{name}}/{{apps_dir}}/{{name}}/test/{{name}}_tests_SUITE.erl"}.
|
||||
{template, "service-templates/config/sys.config", "{{name}}/config/sys.config"}.
|
||||
{template, "service-templates/config/vm.args", "{{name}}/config/vm.args"}.
|
||||
|
||||
%% Build
|
||||
{template, "service-templates/Makefile", "{{name}}/Makefile"}.
|
||||
{template, "service-templates/Dockerfile.sh", "{{name}}/Dockerfile.sh"}.
|
||||
{chmod, "{{name}}/Dockerfile.sh", 8#755}.
|
||||
{template, "service-templates/docker-compose.sh", "{{name}}/docker-compose.sh"}.
|
||||
{chmod, "{{name}}/docker-compose.sh", 8#755}.
|
||||
|
||||
%% VCS
|
||||
{template, "common-templates/gitignore", "{{name}}/.gitignore"}.
|
||||
|
||||
%% Docs
|
||||
{template, "service-templates/README.md", "{{name}}/README.md"}.
|
||||
{template, "service-templates/doc/index.md", "{{name}}/doc/index.md"}.
|
||||
|
||||
%% Tools
|
||||
{file, "common-templates/editorconfig", "{{name}}/.editorconfig"}.
|
||||
|
||||
%% CI/CD
|
||||
{template, "service-templates/Jenkinsfile", "{{name}}/Jenkinsfile"}.
|
||||
|
||||
%% Licenses
|
||||
{file, "common-templates/LICENSE", "{{name}}/LICENSE"}.
|
||||
|
43
library-templates/Makefile
Normal file
43
library-templates/Makefile
Normal file
@ -0,0 +1,43 @@
|
||||
REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3)
|
||||
|
||||
.PHONY: all get_deps ensure_elvis compile lint check_format \
|
||||
format test xref clean distclean dialyze plt_update shell
|
||||
|
||||
all: compile
|
||||
|
||||
get_deps:
|
||||
$(REBAR) get-deps
|
||||
|
||||
compile:
|
||||
$(REBAR) compile
|
||||
|
||||
shell: submodules
|
||||
$(REBAR) shell
|
||||
|
||||
lint:
|
||||
$(REBAR) lint
|
||||
|
||||
check_format:
|
||||
$(REBAR) fmt -c
|
||||
|
||||
format:
|
||||
$(REBAR) fmt -w
|
||||
|
||||
test:
|
||||
$(REBAR) do eunit, proper
|
||||
|
||||
xref:
|
||||
$(REBAR) xref
|
||||
|
||||
clean:
|
||||
$(REBAR) clean
|
||||
|
||||
distclean:
|
||||
$(REBAR) clean -a
|
||||
rm -rfv _build
|
||||
|
||||
dialyze:
|
||||
$(REBAR) dialyzer
|
||||
|
||||
plt_update:
|
||||
$(REBAR) dialyzer -u true -s false
|
77
library-templates/Makefile.ci
Normal file
77
library-templates/Makefile.ci
Normal file
@ -0,0 +1,77 @@
|
||||
REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3)
|
||||
SUBMODULES = build_utils
|
||||
SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES))
|
||||
|
||||
UTILS_PATH := build_utils
|
||||
TEMPLATES_PATH := .
|
||||
|
||||
# Name of the service
|
||||
SERVICE_NAME := {{name}}
|
||||
# Service image default tag
|
||||
SERVICE_IMAGE_TAG ?= $(shell git rev-parse HEAD)
|
||||
# The tag for service image to be pushed with
|
||||
SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG)
|
||||
|
||||
# Base image for the service
|
||||
BASE_IMAGE_NAME := service_erlang
|
||||
BASE_IMAGE_TAG := $(BASE_IMAGE_TAG) # Replace with the current version (tag) for service_erlang image!
|
||||
|
||||
# Build image tag to be used
|
||||
BUILD_IMAGE_NAME := build-erlang
|
||||
BUILD_IMAGE_TAG := $(BUILD_IMAGE_TAG) # Replace with the current version (tag) for build image!
|
||||
|
||||
CALL_ANYWHERE := all submodules compile xref lint dialyze plt_update test \
|
||||
shell release clean distclean format check_format
|
||||
|
||||
# Hint: 'test' might be a candidate for CALL_W_CONTAINER-only target
|
||||
CALL_W_CONTAINER := $(CALL_ANYWHERE)
|
||||
|
||||
.PHONY: $(CALL_W_CONTAINER)
|
||||
|
||||
all: compile
|
||||
|
||||
-include $(UTILS_PATH)/make_lib/utils_container.mk
|
||||
-include $(UTILS_PATH)/make_lib/utils_image.mk
|
||||
|
||||
$(SUBTARGETS): %/.git: %
|
||||
git submodule update --init $<
|
||||
touch $@
|
||||
|
||||
submodules: $(SUBTARGETS)
|
||||
|
||||
compile: submodules
|
||||
$(REBAR) compile
|
||||
|
||||
shell: submodules
|
||||
$(REBAR) shell
|
||||
|
||||
lint:
|
||||
$(REBAR) lint
|
||||
|
||||
check_format:
|
||||
$(REBAR) fmt -c
|
||||
|
||||
format:
|
||||
$(REBAR) fmt -w
|
||||
|
||||
test: submodules
|
||||
$(REBAR) do eunit, ct
|
||||
|
||||
xref: submodules
|
||||
$(REBAR) xref
|
||||
|
||||
clean:
|
||||
$(REBAR) clean
|
||||
|
||||
distclean:
|
||||
$(REBAR) clean -a
|
||||
rm -rfv _build
|
||||
|
||||
dialyze:
|
||||
$(REBAR) dialyzer
|
||||
|
||||
plt_update:
|
||||
$(REBAR) dialyzer -u true -s false
|
||||
|
||||
release: submodules
|
||||
$(REBAR) as prod release
|
21
library-templates/README.md
Normal file
21
library-templates/README.md
Normal file
@ -0,0 +1,21 @@
|
||||
# {{name}}
|
||||
|
||||
{{description}}
|
||||
|
||||
## Сборка
|
||||
|
||||
Для запуска процесса сборки достаточно выполнить просто:
|
||||
|
||||
make
|
||||
|
||||
Чтобы запустить проект в режиме разработки и получить стандартный [Erlang shell][2], нужно всего лишь:
|
||||
|
||||
make shell
|
||||
|
||||
## CI/CD
|
||||
Данная библиотека проходит автоматическую проверку с помощью Github Actions, которую можно также запустить локально с помощью [act](https://github.com/nektos/act):
|
||||
```
|
||||
act
|
||||
```
|
||||
|
||||
> _Хозяйке на заметку._ В зависимости от вашего окружения и операционной системы вам может понадобиться [Docker Machine][4].
|
49
library-templates/elvis.config
Normal file
49
library-templates/elvis.config
Normal file
@ -0,0 +1,49 @@
|
||||
[
|
||||
{elvis, [
|
||||
{config, [
|
||||
#{
|
||||
dirs => ["src", "include", "test"],
|
||||
filter => "*.erl",
|
||||
ruleset => erl_files,
|
||||
rules => [
|
||||
{elvis_text_style, line_length, #{limit => 120}},
|
||||
{elvis_text_style, no_trailing_whitespace, #{ignore_empty_lines => true}},
|
||||
{elvis_style, nesting_level, #{level => 3, ignore => [genlib_trunc_io]}},
|
||||
{elvis_style, atom_naming_convention, disable},
|
||||
|
||||
{elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}},
|
||||
{elvis_style, no_if_expression, disable}
|
||||
]
|
||||
},
|
||||
#{
|
||||
dirs => ["."],
|
||||
filter => "Makefile",
|
||||
ruleset => makefiles
|
||||
},
|
||||
#{
|
||||
dirs => ["."],
|
||||
filter => "elvis.config",
|
||||
ruleset => elvis_config
|
||||
},
|
||||
#{
|
||||
dirs => ["."],
|
||||
filter => "rebar.config",
|
||||
ruleset => rebar_config,
|
||||
rules => [
|
||||
{elvis_text_style, line_length, #{limit => 120, skip_comments => false}},
|
||||
{elvis_text_style, no_tabs},
|
||||
{elvis_text_style, no_trailing_whitespace}
|
||||
]
|
||||
},
|
||||
#{
|
||||
dirs => ["src"],
|
||||
filter => "*.app.src",
|
||||
rules => [
|
||||
{elvis_text_style, line_length, #{limit => 120, skip_comments => false}},
|
||||
{elvis_text_style, no_tabs},
|
||||
{elvis_text_style, no_trailing_whitespace}
|
||||
]
|
||||
}
|
||||
]}
|
||||
]}
|
||||
].
|
37
library-templates/github/workflows/code-checks.yml
Normal file
37
library-templates/github/workflows/code-checks.yml
Normal file
@ -0,0 +1,37 @@
|
||||
name: Erlang Code Checks
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: erlang:22.0.7
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Cache build
|
||||
if: ${{ !env.ACT }}
|
||||
id: cache-build
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: "_build/default/"
|
||||
key: ${{ runner.os }}-${{ hashFiles('rebar.lock') }}-build-default
|
||||
- name: Fetch Deps
|
||||
run: make get_deps
|
||||
- name: Compile
|
||||
run: make compile
|
||||
- name: Run Xref
|
||||
run: make xref
|
||||
- name: Run Dialyzer
|
||||
run: make dialyze
|
||||
- name: Run erlfmt
|
||||
run: make check_format
|
||||
- name: Run linter
|
||||
run: make lint
|
||||
- name: Run tests (eunit, proper)
|
||||
run: make test
|
70
library-templates/rebar.config
Normal file
70
library-templates/rebar.config
Normal file
@ -0,0 +1,70 @@
|
||||
%% Common project erlang options.
|
||||
{erl_opts, [
|
||||
% mandatory
|
||||
debug_info,
|
||||
warnings_as_errors,
|
||||
warn_export_all,
|
||||
warn_missing_spec,
|
||||
warn_untyped_record,
|
||||
warn_export_vars,
|
||||
|
||||
% by default
|
||||
warn_unused_record,
|
||||
warn_bif_clash,
|
||||
warn_obsolete_guard,
|
||||
warn_unused_vars,
|
||||
warn_shadow_vars,
|
||||
warn_unused_import,
|
||||
warn_unused_function,
|
||||
warn_deprecated_function
|
||||
|
||||
% at will
|
||||
% bin_opt_info
|
||||
% no_auto_import
|
||||
% warn_missing_spec_all
|
||||
]}.
|
||||
|
||||
%% Common project dependencies.
|
||||
{deps, []}.
|
||||
|
||||
%% XRef checks
|
||||
{xref_checks, [
|
||||
undefined_function_calls,
|
||||
undefined_functions,
|
||||
deprecated_functions_calls,
|
||||
deprecated_functions
|
||||
]}.
|
||||
% at will
|
||||
% {xref_warnings, true}.
|
||||
|
||||
%% Tests
|
||||
{cover_enabled, true}.
|
||||
|
||||
%% Dialyzer static analyzing
|
||||
{dialyzer, [
|
||||
{warnings, [
|
||||
% mandatory
|
||||
unmatched_returns,
|
||||
error_handling,
|
||||
race_conditions,
|
||||
unknown
|
||||
]},
|
||||
{plt_apps, all_deps}
|
||||
]}.
|
||||
|
||||
{profiles, [
|
||||
{test, [
|
||||
{deps, [proper]}
|
||||
]}
|
||||
]}.
|
||||
|
||||
{plugins, [
|
||||
{erlfmt, "0.14.1"},
|
||||
{rebar3_proper, "0.12.1"},
|
||||
{rebar3_lint, "0.4.0"}
|
||||
]}.
|
||||
|
||||
{erlfmt, [
|
||||
{print_width, 120},
|
||||
{files, ["{src,include,test}/*.{hrl,erl}", "rebar.config", "elvis.config"]}
|
||||
]}.
|
14
library-templates/src/app.app.src
Normal file
14
library-templates/src/app.app.src
Normal file
@ -0,0 +1,14 @@
|
||||
{application, {{name}} , [
|
||||
{description, "{{description}}"},
|
||||
{vsn, "{{version}}"},
|
||||
{applications, [
|
||||
kernel,
|
||||
stdlib
|
||||
]},
|
||||
{env, []},
|
||||
{maintainers, [
|
||||
"{{author_name}} <{{author_email}}>"
|
||||
]},
|
||||
{licenses, ["Apache 2.0"]},
|
||||
{links, []}
|
||||
]}.
|
1
library-templates/src/app.erl
Normal file
1
library-templates/src/app.erl
Normal file
@ -0,0 +1 @@
|
||||
-module({{name}}).
|
13
rebar.config
Normal file
13
rebar.config
Normal file
@ -0,0 +1,13 @@
|
||||
{plugins, [
|
||||
{erlfmt, "0.10.0"}
|
||||
]}.
|
||||
|
||||
{erlfmt, [
|
||||
{print_width, 120},
|
||||
{files, [
|
||||
"rebar.config",
|
||||
"*.template",
|
||||
"service-templates/{rebar.config,elvis.config}",
|
||||
"library-templates/{rebar.config,elvis.config}"
|
||||
]}
|
||||
]}.
|
@ -21,7 +21,7 @@ BUILD_IMAGE_NAME := build-erlang
|
||||
BUILD_IMAGE_TAG := $(BUILD_IMAGE_TAG) # Replace with the current version (tag) for build image!
|
||||
|
||||
CALL_ANYWHERE := all submodules compile xref lint dialyze plt_update test \
|
||||
release clean distclean format check_format
|
||||
shell release clean distclean format check_format
|
||||
|
||||
# Hint: 'test' might be a candidate for CALL_W_CONTAINER-only target
|
||||
CALL_W_CONTAINER := $(CALL_ANYWHERE)
|
||||
@ -42,8 +42,11 @@ submodules: $(SUBTARGETS)
|
||||
compile: submodules
|
||||
$(REBAR) compile
|
||||
|
||||
shell: submodules
|
||||
$(REBAR) shell
|
||||
|
||||
lint:
|
||||
elvis rock
|
||||
$(REBAR) lint
|
||||
|
||||
check_format:
|
||||
$(REBAR) fmt -c
|
||||
@ -62,7 +65,7 @@ clean:
|
||||
|
||||
distclean:
|
||||
$(REBAR) clean -a
|
||||
rm -rfv _build _builds _cache _steps _temp
|
||||
rm -rfv _build
|
||||
|
||||
dialyze:
|
||||
$(REBAR) dialyzer
|
||||
@ -72,4 +75,3 @@ plt_update:
|
||||
|
||||
release: submodules
|
||||
$(REBAR) as prod release
|
||||
|
@ -14,17 +14,17 @@
|
||||
|
||||
> _Хозяйке на заметку._ При этом используется стандартный Erlang релиз, собранный при помощи [relx][3] в режиме разработчика.
|
||||
|
||||
Рекомендуется вести разработку и сборку проекта в рамках локальной виртуальной среды, предоставляемой [wercker][1]. Настоятельно рекомендуется прогоны тестовых сценариев проводить только в этой среде.
|
||||
Рекомендуется вести разработку и сборку проекта в рамках локальной виртуальной среды, предоставляемой локальным Makefile и Make задачами `wc_`, предоставляемыми [`build_utils`][1], которые дублируют задачи местного Makefile, но выполняются в контейнере с необходимой средой ([при условии установки `build_utils`](https://github.com/rbkmoney/erlang-service-template/blob/master/README.md)). Настоятельно рекомендуется прогоны тестовых сценариев проводить только в этой среде.
|
||||
|
||||
$ wercker dev
|
||||
$ make wc_all
|
||||
|
||||
> _Хозяйке на заметку._ В зависимости от вашего окружения и операционной системы вам может понадобиться [Docker Machine][4].
|
||||
|
||||
## Документация
|
||||
|
||||
Дальнейшую документацию можно почерпнуть, пройдясь по ссылкам в [соответствующем документе](doc/index.md).
|
||||
Дальнейшую документацию можно почерпнуть, пройдясь по ссылкам в [соответствующем документе](doc/index.md).
|
||||
|
||||
[1]: http://devcenter.wercker.com/learn/basics/the-wercker-cli.html
|
||||
[1]: https://github.com/rbkmoney/build_utils
|
||||
[2]: http://erlang.org/doc/man/shell.html
|
||||
[3]: https://github.com/erlware/relx
|
||||
[4]: https://docs.docker.com/machine/install-machine/
|
@ -7,47 +7,44 @@
|
||||
|
||||
%% API
|
||||
-export([start/0]).
|
||||
-export([stop /0]).
|
||||
-export([stop/0]).
|
||||
|
||||
%% Supervisor callbacks
|
||||
-export([init/1]).
|
||||
|
||||
%% Application callbacks
|
||||
-export([start/2]).
|
||||
-export([stop /1]).
|
||||
-export([stop/1]).
|
||||
|
||||
%%
|
||||
%% API
|
||||
%%
|
||||
-spec start() ->
|
||||
{ok, _}.
|
||||
-spec start() -> {ok, _}.
|
||||
start() ->
|
||||
application:ensure_all_started({{name}}).
|
||||
|
||||
-spec stop() ->
|
||||
ok.
|
||||
-spec stop() -> ok.
|
||||
stop() ->
|
||||
application:stop({{name}}).
|
||||
|
||||
%%
|
||||
%% Supervisor callbacks
|
||||
%%
|
||||
-spec init([]) ->
|
||||
{ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
|
||||
-spec init([]) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
|
||||
init([]) ->
|
||||
{ok, {
|
||||
{one_for_all, 0, 1}, []
|
||||
}}.
|
||||
{ok,
|
||||
{
|
||||
{one_for_all, 0, 1},
|
||||
[]
|
||||
}}.
|
||||
|
||||
%%
|
||||
%% Application callbacks
|
||||
%%
|
||||
-spec start(normal, any()) ->
|
||||
{ok, pid()} | {error, any()}.
|
||||
-spec start(normal, any()) -> {ok, pid()} | {error, any()}.
|
||||
start(_StartType, _StartArgs) ->
|
||||
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||
|
||||
-spec stop(any()) ->
|
||||
ok.
|
||||
-spec stop(any()) -> ok.
|
||||
stop(_State) ->
|
||||
ok.
|
@ -1,10 +1,10 @@
|
||||
-module({{name}}_tests_SUITE).
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
||||
-export([all /0]).
|
||||
-export([all/0]).
|
||||
-export([init_per_suite/1]).
|
||||
-export([end_per_suite /1]).
|
||||
-export([dummy_test /1]).
|
||||
-export([end_per_suite/1]).
|
||||
-export([dummy_test/1]).
|
||||
|
||||
-type test_name() :: atom().
|
||||
-type config() :: [{atom(), _}].
|
||||
@ -12,8 +12,7 @@
|
||||
%%
|
||||
%% tests descriptions
|
||||
%%
|
||||
-spec all() ->
|
||||
[test_name()].
|
||||
-spec all() -> [test_name()].
|
||||
all() ->
|
||||
[
|
||||
dummy_test
|
||||
@ -22,18 +21,16 @@ all() ->
|
||||
%%
|
||||
%% starting/stopping
|
||||
%%
|
||||
-spec init_per_suite(config()) ->
|
||||
config().
|
||||
-spec init_per_suite(config()) -> config().
|
||||
init_per_suite(C) ->
|
||||
{ok, Apps} = application:ensure_all_started({{name}}),
|
||||
[{apps, Apps}|C].
|
||||
[{apps, Apps} | C].
|
||||
|
||||
-spec end_per_suite(config()) ->
|
||||
any().
|
||||
-spec end_per_suite(config()) -> any().
|
||||
end_per_suite(C) ->
|
||||
[application_stop(App) || App <- proplists:get_value(apps, C)].
|
||||
|
||||
application_stop(App=sasl) ->
|
||||
application_stop(App = sasl) ->
|
||||
%% hack for preventing sasl deadlock
|
||||
%% http://erlang.org/pipermail/erlang-questions/2014-May/079012.html
|
||||
error_logger:delete_report_handler(cth_log_redirect),
|
||||
@ -46,7 +43,6 @@ application_stop(App) ->
|
||||
%%
|
||||
%% tests
|
||||
%%
|
||||
-spec dummy_test(config()) ->
|
||||
any().
|
||||
-spec dummy_test(config()) -> any().
|
||||
dummy_test(_C) ->
|
||||
ok.
|
@ -2,27 +2,18 @@
|
||||
{elvis, [
|
||||
{config, [
|
||||
#{
|
||||
dirs => ["apps/*/src"],
|
||||
dirs => ["apps/*/src", "apps/*/include", "apps/*/test"],
|
||||
filter => "*.erl",
|
||||
ignore => ["_thrift.erl$"],
|
||||
ruleset => erl_files,
|
||||
rules => [
|
||||
{elvis_text_style, line_length, #{limit => 120, skip_comments => false}},
|
||||
{elvis_text_style, no_tabs},
|
||||
{elvis_text_style, no_trailing_whitespace},
|
||||
{elvis_style, macro_module_names},
|
||||
{elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}},
|
||||
{elvis_style, nesting_level, #{level => 3}},
|
||||
{elvis_style, god_modules, #{limit => 25}},
|
||||
{elvis_style, no_if_expression},
|
||||
{elvis_style, invalid_dynamic_call, #{ignore => [elvis]}},
|
||||
{elvis_style, used_ignored_variable},
|
||||
{elvis_style, no_behavior_info},
|
||||
{elvis_style, module_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*(_SUITE)?$"}},
|
||||
{elvis_text_style, line_length, #{limit => 120}},
|
||||
{elvis_text_style, no_trailing_whitespace, #{ignore_empty_lines => true}},
|
||||
{elvis_style, nesting_level, #{level => 3, ignore => [genlib_trunc_io]}},
|
||||
{elvis_style, atom_naming_convention, disable},
|
||||
|
||||
{elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}},
|
||||
{elvis_style, state_record_and_type},
|
||||
{elvis_style, no_spec_with_records},
|
||||
{elvis_style, dont_repeat_yourself, #{min_complexity => 10}},
|
||||
{elvis_style, no_debug_call, #{ignore => [elvis, elvis_utils]}}
|
||||
{elvis_style, no_if_expression, disable}
|
||||
]
|
||||
},
|
||||
#{
|
||||
@ -47,6 +38,7 @@
|
||||
#{
|
||||
dirs => ["."],
|
||||
filter => "rebar.config",
|
||||
ruleset => rebar_config,
|
||||
rules => [
|
||||
{elvis_text_style, line_length, #{limit => 120, skip_comments => false}},
|
||||
{elvis_text_style, no_tabs},
|
@ -1,6 +1,5 @@
|
||||
%% Common project erlang options.
|
||||
{erl_opts, [
|
||||
|
||||
% mandatory
|
||||
debug_info,
|
||||
warnings_as_errors,
|
||||
@ -26,8 +25,7 @@
|
||||
]}.
|
||||
|
||||
%% Common project dependencies.
|
||||
{deps, [
|
||||
]}.
|
||||
{deps, []}.
|
||||
|
||||
%% XRef checks
|
||||
{xref_checks, [
|
||||
@ -81,7 +79,8 @@
|
||||
]}.
|
||||
|
||||
{plugins, [
|
||||
{erlfmt, "0.10.0"}
|
||||
{erlfmt, "0.14.1"},
|
||||
{rebar3_lint, "0.4.0"}
|
||||
]}.
|
||||
|
||||
{erlfmt, [
|
Loading…
Reference in New Issue
Block a user