ElixirProjectChecklist Is a checklist to follow to create new Elixir projects to add things like, formating, versioning, debuging, documentation, code coverage, package publishing, testing etc. You can follow the checklist in project or clone the project if your creating a barebose project.
- accepting
- documentation
- new checklist items
- Skip the Installation and go to
Core Checklist
if your using the checklist to start a new project.
If available in Hex, the package can be installed
by adding elixir_project_checklist
to your list of dependencies in mix.exs
:
def deps do
[
{:elixir_project_checklist, "~> 0.1.0"}
]
end
make # see all commands
make setup # setup project
make build # build project
- setup README.md - create README
- setup LICENSE file - create LICENSE pick Apache
- automated build - makefile automated help
- build configuration - elixir mix.exs setup
- code formatter - elixir formatter and configuration setup
- style check - elixir credo
- static analysis - elixir dialyzer
- project documentation - elixir ex_doc setup with makefile
- code coverage - elixir code coverage with excoveralls
- publish the package - publish to hex
See more below
- security checks with
sobelow
https://github.com/nccgroup/sobelow - debugging with
recon
https://github.com/ferd/recon - launch observer
- launch web observer
wobserver
https://github.com/shinyscorpion/wobserver - install
observer_cli
: https://github.com/zhongwencool/observer_cli - Crash on incorrect formatting in CI
mix format --check-formatted
- Crash on warnings (warnings as errors) in CI
mix do clean, compile --force --warning-as-errors
- change
mix clean
to not remove all the downloaded deps which may not be needed. - Check recommendation using
preferred_cli_env
: https://github.com/parroty/excoveralls#mixexs for commonly used tasks instead of prefixing with MIX_ENV=test - article describing this at https://medium.com/elixircommons
- upgrade wrk to wrk2
- automate process - cookie cutter clone? https://github.com/audreyr/cookiecutter
- deployment package - erlang release with distillery
- phx configuration 4 package - config.exs setup with aliases
- distillery config - update config/prod.exs with "config :phoenix, :serve_endpoints, true"
- benchmarking setup - elixir benchee setup
- load testing setup - elixir wrk
- logging - elixir logging TODO: Add example logging and checklist
- create README
- add project description
- add main project source reference: github_url_to_self
- add contributors section
- select licence from: https://choosealicense.com/
- create LICENSE file
- update template with things like name, description and copyright as necessary
- copy makefile from https://github.com/ElixirCommons/ElixirProjectChecklist
- update in the makefile variable
app-name := elixir_project_checklist
to be the value ofmix.exs:def project[app:]
- test makefile see below
- update
def project do
withaliases: aliases()
, - automatic version management for non hex packages
# make sure you use tags for MAJOR.MINOR versions
# e.g. git tag --annotate v1.4 --message v1.4
# this goes in your mix.exs
def app_version do
# get suffix
build_number = System.get_env("BUILD_NUMBER")
suffix = if build_number, do: ".build-#{build_number}", else: build_number # => .build-443
# get git version
{git_desc, 0} = System.cmd("git", ~w[describe --long])
["v" <> major_minor, patch, git_commit_id] = git_desc |> String.trim |> String.split("-") # => ["v1.4", "270", "fa78ab71e"]
"#{major_minor}.#{patch}+ref-#{git_commit_id}#{suffix}" # => 1.4.270+ref-fa78ab71e.build-443
end
- create
defp aliases
see below - update
def project do
withdefault_task: "help_make"
,
defp aliases do
[
help_make: "cmd make"
]
end
- test alias
mix
you should see make commands
- create
.formatter.exs
[
inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
- test
make format
- add to deps
{:credo, "~> 0.9.1", only: [:dev, :test], runtime: false}
- test
make style-checks
- add to deps
{:dialyxir, "~> 1.0.0-rc.2", only: [:dev], runtime: false}
- test
make static-analysis
- check after setting up
code formatter
,style check
andstatic analysis
withmake setup build
- add to deps
{:ex_doc, "~> 0.16", only: :dev, runtime: false}
- update
def project do
with- name: "project_name",
- source_url: "https://github.com/USER/PROJECT",
- homepage_url: "http://YOUR_PROJECT_HOMEPAGE",
- description: """ ADD YOUR DESCRIPTION """
- add to
def project do [ docs: docs(),]
anddefp docs
see below - Reference configs here: https://hexdocs.pm/ex_doc/Mix.Tasks.Docs.html#content
- add to
defp docs
- main: "ModuleName_or_Page" - Main page of the documentation. It may be a module or a generated page
- logo: "path/to/file.png_or_jpg"
- extras:
"README.md": [filename: "readme", title: "README"]]
- extra_section: "Name of Extra Section in docs"
- optionally add groups_for_extras:
[ Introduction: Path.wildcard("guides/introduction/*.md") ]
- optionally add groups_for_modules:
[ Controllers: [ Module.Name ] ]
- optionally add assets: "path/to/dir"
- test documentation
make docs open-docs
### --
# all configuration required by ex_doc to configure the generation of documents
### --
defp docs do
[
main: "ModuleName_or_Page",
logo: "guides/assets/image.png_or_jpg",
extras: ["README.md": [filename: "readme", title: "README"]],
extra_section: "GUIDES",
groups_for_extras: [
Introduction: Path.wildcard("guides/introduction/*.md")
],
# Ungrouped Modules:
#
# OtherModules
groups_for_modules: [
Controllers: [
Module.Name
]
]
]
end
- add to deps
{:excoveralls, "~> 0.8", only: [:dev, :test]}
- update
def project do
withtest_coverage: [tool: ExCoveralls]
, - test
make coverage-report
- Install hex
mix local.hex
- Register hex user run:
mix hex.user register
- Confirm your account via email
- update
def project do
withpackage: package()
, see below - mix.exs add fill out
defp package
keyssee below
- check no git dependencies
- run:
mix hex.publish
- if first publish update references to hexdocs in readme and mix.exs
- test published package
defp package() do
[
# This option is only needed when you don't want to use the OTP application name
name: "package_name",
organization: "hexpm",
# These are the default files included in the package
files: ["lib", "priv", "mix.exs", "README*", "readme*", "LICENSE*", "license*"],
licenses: ["GNU 3.0"],
links: %{"GitHub" => "https://github.com/USERNAME/PROJECTNAME", "HexDocs" => "https://hexdocs.pm/PACKAGE/"},
maintainers: ["NAME and EMAIL"]
]
end
- add to deps
{:distillery, "~> 1.5", runtime: false}
- setup by running
mix release.init
- create bin/version_check.exs
- test package
make package package-run
try do
# if no args submitted and exception is raised
if hd(System.argv()) =~ ~r{^(\d+\.)(\d+\.)(\d+)$} do
System.stop(0)
else
System.stop(1)
end
rescue
# if exception it's a invalid version
_ -> System.stop(1)
end
# Believe the receive block prevents the race condition so
# that halt will work correctly
receive do
{:hello, msg} -> msg
after
10_000 -> "nothing after 1s"
end
- add to deps
{:benchee, "~> 0.11", only: :dev}
, - add to deps
{:benchee_html, "~> 0.4", only: :dev}
, - create
benchmarks/sample.exs
see below - test
make run-benchmarks
# https://github.com/PragTob/benchee
map_fun = fn(i) -> i + 1 end
inputs = %{
"Small (1 Thousand)" => Enum.to_list(1..1_000),
"Middle (100 Thousand)" => Enum.to_list(1..100_000),
"Big (10 Million)" => Enum.to_list(1..10_000_000),
}
Benchee.run %{
"flat_map" => fn(_) -> 1+1 end,
"map.flatten" => fn(list) -> list |> IO.inspect |> Enum.map(map_fun) |> List.flatten end
}, time: 15, warmup: 5, inputs: inputs, formatters: [
Benchee.Formatters.HTML,
Benchee.Formatters.Console
],
formatter_options: [html: [file: "_benchmarks/sample.html"]]
- install wrk
brew install wrk
- test
IP=127.0.0.1 PORT=8080 URLPATH=hello/world make load-test
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/elixir_project_checklist.
- https://github.com/parroty/excoveralls
- https://github.com/jeremyjh/dialyxir
- https://github.com/rrrene/credo
- https://github.com/bitwalker/distillery
- https://github.com/elixir-lang/ex_doc
- https://github.com/wg/wrk
- https://github.com/elixir-lang/elixir/tree/master/lib/logger
- https://github.com/PragTob/benchee
- Steve Morin - https://github.com/smorin
- Khaja Minhajuddin - https://github.com/minhajuddin