├── .deliver └── config.example ├── .gitignore ├── LICENSE ├── README.md ├── bin ├── .gitkeep └── setup_history ├── config └── config.exs ├── doc └── README_TEMPLATE.md ├── lib ├── cli.ex ├── elixir_base.ex ├── elixir_base │ └── supervisor.ex └── mix │ └── tasks │ ├── deploy.ex │ └── run_espec.ex ├── mix.exs ├── mix.lock └── spec ├── elixir_base └── supervisor_spec.exs ├── spec_helper.exs └── support └── supervisor_spec.exs /.deliver/config.example: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # PLEASE, ADD FOLLOWING LINES TO YOUR SSH CONFIG BEFORE START WORKING 4 | # Host ec2 5 | # Hostname ec2-[ip].compute.amazonaws.com 6 | # User ec2-user 7 | # IdentityFile ~/.ssh/ec2-key.pem 8 | 9 | APP="ec2" # name of your release 10 | 11 | GIT_CLEAN_PATHS="_build rel priv/generated" 12 | 13 | BUILD_HOST="ec2" # host where to build the release 14 | BUILD_USER="ec2-user" # local user at build host 15 | BUILD_AT="/tmp/elixir/ec2/builds" # build directory on build host 16 | 17 | STAGING_HOSTS="ec2" # staging / test hosts separated by space 18 | STAGING_USER="ec2-user" # local user at staging hosts 19 | # TEST_AT="/test/ec2" # deploy directory on staging hosts. default is DELIVER_TO 20 | 21 | PRODUCTION_HOSTS="ec2" # deploy / production hosts separated by space 22 | PRODUCTION_USER="ec2" # local user at deploy hosts 23 | DELIVER_TO="/opt" # deploy directory on production hosts 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Elixir ### 2 | /_build 3 | /cover 4 | /deps 5 | erl_crash.dump 6 | *.ez 7 | log 8 | *.log 9 | doc/app 10 | .deliver/config 11 | 12 | 13 | ### Phoenix ### 14 | # Phoenix: a web framework for Elixir 15 | _build/ 16 | /db 17 | /deps 18 | /*.ez 19 | node_modules/ 20 | erl_crash.dump 21 | /priv/static/ 22 | /config/prod.secret.exs 23 | /rel 24 | 25 | 26 | ### Git ### 27 | *.orig 28 | 29 | 30 | ### OSX ### 31 | *.DS_Store 32 | .AppleDouble 33 | .LSOverride 34 | 35 | # Icon must end with two \r 36 | Icon 37 | 38 | 39 | # Thumbnails 40 | ._* 41 | 42 | # Files that might appear in the root of a volume 43 | .DocumentRevisions-V100 44 | .fseventsd 45 | .Spotlight-V100 46 | .TemporaryItems 47 | .Trashes 48 | .VolumeIcon.icns 49 | .com.apple.timemachine.donotpresent 50 | 51 | # Directories potentially created on remote AFP share 52 | .AppleDB 53 | .AppleDesktop 54 | Network Trash Folder 55 | Temporary Items 56 | .apdisk 57 | 58 | 59 | ### Linux ### 60 | *~ 61 | 62 | # temporary files which can be created if a process still has a handle open of a deleted file 63 | .fuse_hidden* 64 | 65 | # KDE directory preferences 66 | .directory 67 | 68 | # Linux trash folder which might appear on any partition or disk 69 | .Trash-* 70 | 71 | 72 | ### Vim ### 73 | # swap 74 | [._]*.s[a-w][a-z] 75 | [._]s[a-w][a-z] 76 | # session 77 | Session.vim 78 | # temporary 79 | .netrwhist 80 | *~ 81 | # auto-generated tag files 82 | tags 83 | 84 | 85 | ### SublimeText ### 86 | # cache files for sublime text 87 | *.tmlanguage.cache 88 | *.tmPreferences.cache 89 | *.stTheme.cache 90 | 91 | # workspace files are user-specific 92 | *.sublime-workspace 93 | 94 | # project files should be checked into the repository, unless a significant 95 | # proportion of contributors will probably not be using SublimeText 96 | # *.sublime-project 97 | 98 | # sftp configuration file 99 | sftp-config.json 100 | 101 | # Package control specific files 102 | Package Control.last-run 103 | Package Control.ca-list 104 | Package Control.ca-bundle 105 | Package Control.system-ca-bundle 106 | Package Control.cache/ 107 | Package Control.ca-certs/ 108 | bh_unicode_properties.cache 109 | 110 | # Sublime-github package stores a github token in this file 111 | # https://packagecontrol.io/packages/sublime-github 112 | GitHub.sublime-settings 113 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Flatstack 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Elixir Base 2 | 3 | [![Build Status](https://semaphoreci.com/api/v1/fs/elixir-base/branches/master/badge.svg)](https://semaphoreci.com/fs/elixir-base) 4 | [![Test Coverage](https://codeclimate.com/github/fs/elixir-base/badges/coverage.svg)](https://codeclimate.com/github/fs/elixir-base) 5 | [![Code Climate](https://codeclimate.com/github/fs/elixir-base.png)](https://codeclimate.com/github/fs/elixir-base) 6 | 7 | Elixir Base is the base Elixir library template used at Flatstack. 8 | It's based on Elixir 1.6. 9 | 10 | ## Application libs 11 | 12 | * [ErlExec](https://github.com/saleyn/erlexec) execute and control OS processes from Erlang/OTP 13 | * [Elixir release manager](https://github.com/bitwalker/exrm) for Elixir's apps release management 14 | * [ExtensibleEffects](https://github.com/metalabdesign/effects) Monadic, softly-typed, extensible effect handling 15 | * [Guardsafe](https://github.com/DevL/guardsafe) macros expanding into code that can be safely used in guard clauses 16 | * [LoggerFileBackend](https://github.com/onkel-dirtus/logger_file_backend) for writing logs into file 17 | * [Monadex](https://github.com/rob-brown/MonadEx) improve pipelines with monads 18 | * [OK](https://github.com/CrowdHailer/OK) macros for [elegant error handling in elixir pipelines](http://insights.workshop14.io/2015/10/18/handling-errors-in-elixir-no-one-say-monad.html) 19 | * [ProgressBar](https://github.com/henrik/progress_bar) for CLI progress bars 20 | * [TableRex](https://github.com/djm/table_rex) for CLI tables 21 | * [Timex](https://github.com/bitwalker/timex) date and time operations 22 | 23 | ## Development libs 24 | 25 | * [Credo](https://github.com/rrrene/credo) for reporting violations of the Elixir style guide 26 | * [Dialyzer](https://github.com/jeremyjh/dialyxir) for static analyse 27 | * [Eper](https://github.com/massemanet/eper) Erlang performance related tools 28 | * [EDeliver](https://github.com/boldpoker/edeliver) provides a bash script to build and deploy Elixir and Erlang applications and perform hot-code upgrades 29 | * [ExDoc](https://github.com/elixir-lang/ex_doc) tool to generate documentation for your Elixir projects 30 | * [Observer-CLI](https://github.com/zhongwencool/observer_cli) visualize Erlang nodes on the command line 31 | 32 | ## Testing libs 33 | 34 | * [ExMachina](https://github.com/thoughtbot/ex_machina) makes it easy to create test data and associations 35 | * [ESpec](https://github.com/antonmi/espec) for unit testing 36 | * [Faker](https://github.com/igas/faker) pure Elixir library for generating fake data 37 | 38 | ## Initializers 39 | 40 | ## Scripts 41 | 42 | * `mix setup` - setup required libraries and stuff 43 | * `mix quality` - runs code style check tools 44 | * `mix ci` - should be used in the CI or locally 45 | * `mix build` - to build application release 46 | * `mix server` - to run server locally 47 | * `mix docs` - to generate local docs 48 | * `mix deploy [production]` - to deploy using EDeliver 49 | * `bin/setup_history` - to install [erlang-history](https://github.com/ferd/erlang-history) 50 | 51 | ## Getting Started 52 | 53 | ### Prepare dependencies 54 | 55 | Elixir v1.6 should be installed. 56 | 57 | ### Bootstrap application 58 | 59 | 1. Clone application as new project with original repository named "elixir-base". 60 | 61 | ```bash 62 | git clone git://github.com/fs/elixir-base.git --origin elixir-base [MY-NEW-PROJECT] 63 | ``` 64 | 65 | 2. Create your new repo on GitHub and push master into it. Make sure master branch is tracking origin repo. 66 | 67 | ```bash 68 | git remote add origin git@github.com:[MY-GITHUB-ACCOUNT]/[MY-NEW-PROJECT].git 69 | git push -u origin master 70 | ``` 71 | 72 | 3. Run setup script 73 | 74 | ```bash 75 | mix setup 76 | ``` 77 | 78 | 4. Run test and quality suits to make sure all dependencies are satisfied and applications works correctly before making changes. 79 | 80 | ```bash 81 | mix ci 82 | ``` 83 | 84 | 5. Run app 85 | 86 | ```bash 87 | mix server 88 | ``` 89 | 90 | 6. Update README 91 | 92 | Do not forget to update application `README.md` file with detailed information based on the 93 | existing template. 94 | 95 | ```bash 96 | mv doc/README_TEMPLATE.md README.md 97 | # update README.md 98 | git commit -am "Update README.md" 99 | ``` 100 | 101 | ## Deployment 102 | 103 | ### Elixir Release Manager 104 | 105 | Use `mix build` task to build Elixir application release. 106 | 107 | ### Heroku 108 | 109 | You can use [Elixir buildpack](https://github.com/HashNuke/heroku-buildpack-elixir) for Heroku to be deployed: 110 | 111 | * [Heroku Postgres](https://www.heroku.com/postgres) add-on will be used for database. 112 | * [SendGrid](https://devcenter.heroku.com/articles/sendgrid) add-on required to be able to send emails. 113 | * [Rollbar](https://elements.heroku.com/addons/rollbar) add-on could be used to application errors. 114 | 115 | ```bash 116 | heroku create --addons=heroku-postgresql,sendgrid,newrelic,rollbar --remote staging elixir-base-example --buildpack "https://github.com/HashNuke/heroku-buildpack-elixir.git" 117 | heroku config:add HOST="elixir-base-example.herokuapp.com" 118 | git push staging master 119 | heroku open 120 | ``` 121 | 122 | ### EDeliver 123 | 124 | You can use [EDeliver](https://github.com/boldpoker/edeliver) to deploy Erlang releases on remote hosts. Provide .deliver/config configuration first: 125 | 126 | ```bash 127 | cp ~./.deliver/config.example ~/.deliver/config 128 | mix deploy 129 | ``` 130 | 131 | ## Code style 132 | 133 | All Elixir code should be written following [Elixir Style Guide](https://github.com/levionessa/elixir_style_guide). 134 | 135 | ## Architecture 136 | 137 | Please follow the next project structure: 138 | 139 | * `lib` - application sources 140 | * `lib/workers` - app workers 141 | * `lib/servers` - app GenServers 142 | * `lib/macroses` - your custom macroses or sigils 143 | * `lib/structs` - your structs 144 | * `config` - app configuration 145 | * `spec/lib` - application tests 146 | 147 | ## Debugging 148 | 149 | * Use *IEx.pry* with *Erlang-history* for interactive console 150 | * *Observer* to observe started Erlang processes 151 | * Use Erlang's [dbg](http://erlang.org/doc/man/dbg.html) for debugging function calls 152 | * Use Erlang's *Debugger* with graphical interface 153 | 154 | ## Testing 155 | 156 | Use ESpec to write RSpec-like tests. 157 | 158 | ## Credits 159 | 160 | Elixir base was written and maintained by by [Flatstack](http://www.flatstack.com) with the help of our 161 | [contributors](http://github.com/fs/elixir-base/contributors). 162 | 163 | [](http://www.flatstack.com) 164 | -------------------------------------------------------------------------------- /bin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fs/elixir-base/581b23ac789bcbff7cbcefd913193565842df881/bin/.gitkeep -------------------------------------------------------------------------------- /bin/setup_history: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | HIST_DIR="~/.erlang-history/" 4 | 5 | set -e 6 | 7 | if [ ! -d "$HIST_DIR" ]; then 8 | git clone https://github.com/ferd/erlang-history.git $HIST_DIR 9 | cd $HIST_DIR 10 | sudo make install 11 | cd - 12 | fi 13 | -------------------------------------------------------------------------------- /config/config.exs: -------------------------------------------------------------------------------- 1 | # This file is responsible for configuring your application 2 | # and its dependencies with the aid of the Mix.Config module. 3 | use Mix.Config 4 | 5 | # This configuration is loaded before any dependency and is restricted 6 | # to this project. If another project depends on this project, this 7 | # file won't be loaded nor affect the parent project. For this reason, 8 | # if you want to provide default values for your application for 9 | # 3rd-party users, it should be done in your "mix.exs" file. 10 | 11 | # You can configure for your application as: 12 | # 13 | # config :elixir_base, key: :value 14 | # 15 | # And access this configuration in your application as: 16 | # 17 | # Application.get_env(:elixir_base, :key) 18 | # 19 | # Or configure a 3rd-party app: 20 | # 21 | config :logger, backends: [:console, {LoggerFileBackend, :file_log}] 22 | 23 | config :logger, :console, 24 | level: :info, 25 | format: "$date $time [$node][$metadata][$level] $message\n", 26 | metadata: [:pid], 27 | colors: [info: :green] 28 | 29 | config :logger, :file_log, 30 | path: "./log/elixir_base.log", 31 | format: "$date $time [$node][$metadata][$level] $message\n", 32 | level: :debug, 33 | metadata: [:pid] 34 | 35 | # It is also possible to import configuration files, relative to this 36 | # directory. For example, you can emulate configuration per environment 37 | # by uncommenting the line below and defining dev.exs, test.exs and such. 38 | # Configuration from the imported file will override the ones defined 39 | # here (which is why it is important to import them last). 40 | # 41 | # import_config "#{Mix.env}.exs" 42 | -------------------------------------------------------------------------------- /doc/README_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Project name 2 | 3 | Third-party service badges (if available) 4 | 5 | [![Build Status](https://semaphoreapp.com/api/v1/projects/31b68af8b073708a56e4e005bbcba2af4802816d/76140/shields_badge.png)](https://semaphoreapp.com/fs/elixir-base) 6 | [![Test Coverage](https://codeclimate.com/github/fs/elixir-base/badges/coverage.svg)](https://codeclimate.com/github/fs/elixir-base) 7 | [![Code Climate](https://codeclimate.com/github/fs/elixir-base.png)](https://codeclimate.com/github/fs/elixir-base) 8 | 9 | ## Project description 10 | 11 | Some short project description. Link to Basecamp project will be fine too. 12 | 13 | ## Dependencies 14 | 15 | * Elixir 1.6 16 | 17 | Setup required dependencies from `Brewfile`: 18 | ```bash 19 | brew install elixir 20 | ``` 21 | 22 | ## Quick Start 23 | 24 | ```bash 25 | # clone repo 26 | git clone git@github.com:account/repo.git 27 | cd repo 28 | 29 | # run setup script 30 | mix setup 31 | 32 | # configure ENV variables in .env 33 | vim .env 34 | 35 | # run server 36 | mix server 37 | ``` 38 | 39 | ## Scripts 40 | 41 | * `mix setup` - setup required libraries and stuff 42 | * `mix quality` - runs code style check tools 43 | * `mix ci` - should be used in the CI or locally 44 | * `mix build` - to build application release 45 | * `mix server` - to run server locally 46 | 47 | ## Staging 48 | 49 | * http://fs-elixir-base.herokuapp.com 50 | 51 | ## Production 52 | 53 | * http://fs-elixir-base.herokuapp.com 54 | 55 | ## Credits 56 | 57 | Elixir base was written and maintained by by [Flatstack](http://www.flatstack.com) with the help of our 58 | [contributors](http://github.com/fs/elixir-base/contributors). 59 | 60 | [](http://www.flatstack.com) 61 | -------------------------------------------------------------------------------- /lib/cli.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirBase.CLI do 2 | @moduledoc """ 3 | CLI entry point 4 | """ 5 | 6 | @spec main([binary()]) :: :ignore | {:error, any()} | {:ok, pid} 7 | def main(args) do 8 | args 9 | |> parse_args 10 | |> process 11 | end 12 | 13 | defp parse_args(args) do 14 | parse = OptionParser.parse args, 15 | switches: [help: :boolean], 16 | aliases: [h: :help] 17 | 18 | case parse do 19 | {[help: true], _, _} -> :help 20 | _ -> :help 21 | end 22 | end 23 | 24 | defp process(:help) do 25 | IO.puts """ 26 | usage: elixir-base 27 | provide custom options 28 | """ 29 | ElixirBase.Supervisor.start_link 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/elixir_base.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirBase do 2 | require Logger 3 | 4 | @moduledoc """ 5 | Entry point of library/application. 6 | """ 7 | 8 | @spec start(any(), any()) :: :ignore | {:error, any()} | {:ok, pid} 9 | def start(_type \\ nil, _args \\ nil) do 10 | _ = Logger.info("Start Elixir Base app") 11 | ElixirBase.Supervisor.start_link 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/elixir_base/supervisor.ex: -------------------------------------------------------------------------------- 1 | defmodule ElixirBase.Supervisor do 2 | require Logger 3 | 4 | @moduledoc """ 5 | Main app supervisor 6 | """ 7 | 8 | use Supervisor 9 | 10 | def start_link, 11 | do: Supervisor.start_link(__MODULE__, :ok, name: ElixirBase.Supervisor) 12 | 13 | @spec init(:ok) :: 14 | {:ok, {:supervisor.sup_flags, [Supervisor.Spec.spec]}} 15 | def init(:ok) do 16 | _ = Logger.info("Start Elixir Base supervisor") 17 | children = [] 18 | supervise(children, strategy: :one_for_one) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/mix/tasks/deploy.ex: -------------------------------------------------------------------------------- 1 | defmodule Mix.Tasks.Deploy do 2 | require Logger 3 | 4 | use Mix.Task 5 | alias Mix.Shell 6 | 7 | @moduledoc """ 8 | Deploys project using EDeliver. Accepts target environment as an argument. 9 | """ 10 | 11 | @spec run(any()) :: any() 12 | @doc """ 13 | Deploys to `production` env from `production` branch 14 | """ 15 | def run(["production"|_]), do: deploy("production", "production") 16 | @doc """ 17 | Default: deploys to `staging` env from `master` branch 18 | """ 19 | def run(_), do: deploy("staging", "master") 20 | 21 | defp deploy(dest, branch) do 22 | _ = Logger.info("Deploying #{dest} to #{branch}") 23 | 24 | dest |> build(branch) |> release(dest) |> start(dest) 25 | end 26 | 27 | defp build(dest, branch), do: execute("mix edeliver build release #{dest} --branch=#{branch} --verbose") 28 | 29 | defp release(0, dest), do: execute("mix edeliver deploy release #{dest} --verbose") 30 | defp release(prev_status, _), do: prev_status 31 | 32 | defp start(0, dest), do: execute("mix edeliver start #{dest} --verbose") 33 | defp start(prev_status, _), do: prev_status 34 | 35 | defp execute(command), do: command |> Shell.cmd([], &IO.write/1) 36 | end 37 | -------------------------------------------------------------------------------- /lib/mix/tasks/run_espec.ex: -------------------------------------------------------------------------------- 1 | defmodule Mix.Tasks.RunEspec do 2 | use Mix.Task 3 | alias Mix.Shell 4 | 5 | @moduledoc false 6 | 7 | @spec run(any()) :: any() 8 | def run(_), do: "MIX_ENV='test' mix espec --format=doc" |> Shell.cmd([], &IO.write/1) 9 | end 10 | -------------------------------------------------------------------------------- /mix.exs: -------------------------------------------------------------------------------- 1 | defmodule ElixirBase.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :elixir_base, 7 | version: "0.0.1", 8 | elixir: "~> 1.6", 9 | name: "Elixir Base", 10 | homepage_url: "https://github.com/fs/elixir-base", 11 | build_embedded: Mix.env == :prod, 12 | start_permanent: Mix.env == :prod, 13 | escript: [main_module: ElixirBase.CLI], 14 | docs: [extras: ["README.md"], output: "./doc/app"], 15 | deps: deps(), 16 | aliases: aliases(), 17 | dialyzer: [ 18 | plt_add_apps: [:mix], 19 | flags: [ 20 | :unmatched_returns, :error_handling, :race_conditions, :underspecs 21 | ] 22 | ] 23 | ] 24 | end 25 | 26 | # Configuration for the OTP application 27 | # 28 | # Type "mix help compile.app" for more information 29 | def application do 30 | [applications: ~w(erlexec effects guardsafe monadex timex)a, 31 | mod: {ElixirBase, []}, 32 | elixirc_paths: elixirc_paths(Mix.env)] 33 | end 34 | 35 | # This makes sure your factory and any other modules in test/support are compiled 36 | # when in the test environment. 37 | defp elixirc_paths(:test), do: ~w(lib web test/support) 38 | defp elixirc_paths(_), do: ~w(lib web) 39 | 40 | # Dependencies can be Hex packages: 41 | # 42 | # {:mydep, "~> 0.3.0"} 43 | # 44 | # Or git/path repositories: 45 | # 46 | # {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"} 47 | # 48 | # Type "mix help deps" for more examples and options 49 | defp deps do 50 | [ 51 | {:erlexec, "~> 1.2.1"}, 52 | {:distillery, "~> 1.5"}, 53 | {:effects, "~> 0.1.0"}, 54 | {:guardsafe, "~> 0.5.0"}, 55 | {:monadex, "~> 1.0.2"}, 56 | {:ok, "~> 1.0.0"}, 57 | {:logger_file_backend, "~> 0.0.9"}, 58 | {:progress_bar, "> 0.0.0"}, 59 | {:table_rex, "~> 0.8.0"}, 60 | {:timex, "~> 3.0"}, 61 | {:credo, "~> 0.9", only: ~w(dev test)a}, 62 | {:dialyxir, "~> 0.5", only: :dev}, 63 | {:edeliver, ">= 1.2.9", only: :dev}, 64 | {:eper, "~> 0.94.0", only: :dev}, 65 | {:ex_machina, "~> 0.6.1", only: ~w(dev test)a}, 66 | {:ex_doc, "~> 0.11", only: :dev}, 67 | {:observer_cli, "~> 1.0.5", only: :dev}, 68 | {:espec, "~> 1.1.0", only: :test}, 69 | {:faker, "~> 0.5", only: :test,} 70 | ] 71 | end 72 | 73 | defp aliases do 74 | [ 75 | build: "release", 76 | server: "run", 77 | quality: ["dialyzer", "credo --strict"], 78 | ci: ~w(run_espec quality), 79 | setup: [ 80 | "local.hex --force", 81 | "local.rebar --force", 82 | "deps.get", 83 | "compile" 84 | ] 85 | ] 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /mix.lock: -------------------------------------------------------------------------------- 1 | %{ 2 | "bbmustache": {:hex, :bbmustache, "1.0.4", "7ba94f971c5afd7b6617918a4bb74705e36cab36eb84b19b6a1b7ee06427aa38", [:rebar], []}, 3 | "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []}, 4 | "certifi": {:hex, :certifi, "0.4.0", "a7966efb868b179023618d29a407548f70c52466bf1849b9e8ebd0e34b7ea11f", [:rebar3], []}, 5 | "cf": {:hex, :cf, "0.2.2", "7f2913fff90abcabd0f489896cfeb0b0674f6c8df6c10b17a83175448029896c", [:rebar3], [], "hexpm"}, 6 | "combine": {:hex, :combine, "0.9.2", "cd3c8721f378ebe032487d8a4fa2ced3181a456a3c21b16464da8c46904bb552", [:mix], []}, 7 | "conform": {:hex, :conform, "0.16.0", "f6d6b207c693f2f939af8edeab7c735c4fd48552c63c0a019a52b6d2d98a1ca4", [:mix], [{:neotoma, "~> 1.7.3", [hex: :neotoma, optional: false]}]}, 8 | "credo": {:hex, :credo, "0.9.0", "5d1b494e4f2dc672b8318e027bd833dda69be71eaac6eedd994678be74ef7cb4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, 9 | "dialyxir": {:hex, :dialyxir, "0.5.0", "5bc543f9c28ecd51b99cc1a685a3c2a1a93216990347f259406a910cf048d1d7", [:mix], []}, 10 | "distillery": {:hex, :distillery, "1.5.2", "eec18b2d37b55b0bcb670cf2bcf64228ed38ce8b046bb30a9b636a6f5a4c0080", [:mix], [], "hexpm"}, 11 | "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], []}, 12 | "edeliver": {:hex, :edeliver, "1.4.0", "c1713b3fabfa75d64770a28b715379be6631442b5d288fc92d45e037757dc9c8", [:mix], [{:distillery, ">= 0.8.0", [hex: :distillery, optional: true]}, {:exrm, ">= 0.16.0", [hex: :exrm, optional: true]}]}, 13 | "effects": {:hex, :effects, "0.1.1", "1daab8e5bda97452910c7fb21ad167a406f71e428d0aad8acb99f775bf14fd0f", [:mix], []}, 14 | "eper": {:hex, :eper, "0.94.0", "f5fb2daa0df8878748e1c598428eda942a173e5121ff35c1d632129b84593a3a", [:rebar], []}, 15 | "erlexec": {:hex, :erlexec, "1.2.2", "122edf6be532475dd44d2c99653439528e3b3799e2ee0125f2560bcca60a6716", [:rebar3], [], "hexpm"}, 16 | "erlware_commons": {:hex, :erlware_commons, "1.0.5", "fc23d8e304140b65a811f653a76b2fb10b0ce744608caf86e9125ceb349c9442", [:rebar3], [{:cf, "0.2.2", [hex: :cf, repo: "hexpm", optional: false]}], "hexpm"}, 17 | "espec": {:hex, :espec, "1.1.2", "d1cf60ee8f6fb8b0f1593097958762f870949238b0aa15788201728cb6e672dd", [:mix], [{:meck, "~> 0.8.4", [hex: :meck, optional: false]}]}, 18 | "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]}, 19 | "ex_machina": {:hex, :ex_machina, "0.6.2", "2d25802d269b21ecb3df478c3609f3b162ef6d1c952d75770e0969f8971611de", [:mix], []}, 20 | "exrm": {:hex, :exrm, "1.0.8", "5aa8990cdfe300282828b02cefdc339e235f7916388ce99f9a1f926a9271a45d", [:mix], [{:relx, "~> 3.5", [hex: :relx, repo: "hexpm", optional: false]}], "hexpm"}, 21 | "faker": {:hex, :faker, "0.7.0", "2c42deeac7be717173c78c77fb3edc749fb5d5e460e33d01fe592ae99acc2f0d", [:mix], []}, 22 | "getopt": {:hex, :getopt, "1.0.1", "c73a9fa687b217f2ff79f68a3b637711bb1936e712b521d8ce466b29cbf7808a", [:rebar3], [], "hexpm"}, 23 | "gettext": {:hex, :gettext, "0.11.0", "80c1dd42d270482418fa158ec5ba073d2980e3718bacad86f3d4ad71d5667679", [:mix], []}, 24 | "guardsafe": {:hex, :guardsafe, "0.5.1", "36008b1e052399c805528ad01daec7dbd58c28fbca7a50d7a62fb909ff95a6f1", [:mix], []}, 25 | "hackney": {:hex, :hackney, "1.6.1", "ddd22d42db2b50e6a155439c8811b8f6df61a4395de10509714ad2751c6da817", [:rebar3], [{:certifi, "0.4.0", [hex: :certifi, optional: false]}, {:idna, "1.2.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.0", [hex: :ssl_verify_fun, optional: false]}]}, 26 | "idna": {:hex, :idna, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], []}, 27 | "logger_file_backend": {:hex, :logger_file_backend, "0.0.9", "5c2f7d4a28431e695cdf94d191523dbafe609321a67bb654254897f546c393db", [:mix], []}, 28 | "meck": {:hex, :meck, "0.8.4", "59ca1cd971372aa223138efcf9b29475bde299e1953046a0c727184790ab1520", [:make, :rebar], []}, 29 | "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, 30 | "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []}, 31 | "mock": {:hex, :mock, "0.1.3", "657937b03f88fce89b3f7d6becc9f1ec1ac19c71081aeb32117db9bc4d9b3980", [:mix], [{:meck, "~> 0.8.2", [hex: :meck, optional: false]}]}, 32 | "monadex": {:hex, :monadex, "1.0.2", "a35438e5b6224d5149d4578c7163681754bdabbc3183f15962296d50ef5ec7f7", [:mix], []}, 33 | "neotoma": {:hex, :neotoma, "1.7.3", "d8bd5404b73273989946e4f4f6d529e5c2088f5fa1ca790b4dbe81f4be408e61", [:rebar], []}, 34 | "observer_cli": {:hex, :observer_cli, "1.0.7", "54013653c72e75ff3b4b487342dfe56715c9749ff9c31a7de8f84d18a09e1c3c", [:mix, :rebar], [{:recon, "~> 2.3.1", [hex: :recon, optional: false]}]}, 35 | "ok": {:hex, :ok, "1.0.0", "6cdc2f0fa0c27614918ff4ea465e2fdb94042dd2c88bfdbdc6a4f9aca29129bc", [:mix], []}, 36 | "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, 37 | "progress_bar": {:hex, :progress_bar, "1.5.0", "22fd314c28bcc825b69ebad7c55ff72c9d3677adb475e03a5afbae1c356ca747", [:mix], []}, 38 | "providers": {:hex, :providers, "1.7.0", "bbf730563914328ec2511d205e6477a94831db7297de313b3872a2b26c562eab", [:rebar3], [{:getopt, "1.0.1", [hex: :getopt, repo: "hexpm", optional: false]}], "hexpm"}, 39 | "recon": {:hex, :recon, "2.3.2", "4444c879be323b1b133eec5241cb84bd3821ea194c740d75617e106be4744318", [:rebar3], []}, 40 | "relx": {:hex, :relx, "3.24.4", "2132f0abfa93db3177e66768db5a3d4141d4683bb4864b9dd4452ee7123ded07", [:rebar3], [{:bbmustache, "1.0.4", [hex: :bbmustache, repo: "hexpm", optional: false]}, {:cf, "0.2.2", [hex: :cf, repo: "hexpm", optional: false]}, {:erlware_commons, "1.0.5", [hex: :erlware_commons, repo: "hexpm", optional: false]}, {:getopt, "1.0.1", [hex: :getopt, repo: "hexpm", optional: false]}, {:providers, "1.7.0", [hex: :providers, repo: "hexpm", optional: false]}], "hexpm"}, 41 | "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.0", "edee20847c42e379bf91261db474ffbe373f8acb56e9079acb6038d4e0bf414f", [:make, :rebar], []}, 42 | "table_rex": {:hex, :table_rex, "0.8.3", "1c68dfc6886d6f118f5047b0449d6402ae0ac5709064789e578c2f4659f4064b", [:mix], []}, 43 | "timex": {:hex, :timex, "3.1.5", "413d6d8d6f0162a5d47080cb8ca520d790184ac43e097c95191c7563bf25b428", [:mix], [{:combine, "~> 0.7", [hex: :combine, optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, optional: false]}]}, 44 | "tzdata": {:hex, :tzdata, "0.5.16", "13424d3afc76c68ff607f2df966c0ab4f3258859bbe3c979c9ed1606135e7352", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, 45 | } 46 | -------------------------------------------------------------------------------- /spec/elixir_base/supervisor_spec.exs: -------------------------------------------------------------------------------- 1 | Code.require_file("spec/support/supervisor_spec.exs") 2 | 3 | defmodule ElixirBase.SupervisorSpec do 4 | use ESpec 5 | 6 | before described_module: described_module, strategy: :one_for_one 7 | it_behaves_like SupervisorSharedSpec 8 | end 9 | -------------------------------------------------------------------------------- /spec/spec_helper.exs: -------------------------------------------------------------------------------- 1 | Faker.start 2 | {:ok, _} = Application.ensure_all_started(:elixir_base) 3 | 4 | ESpec.configure fn(config) -> 5 | config.before fn(tags) -> 6 | {:shared, hello: :world, tags: tags} 7 | end 8 | 9 | config.finally fn(_shared) -> 10 | :ok 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/supervisor_spec.exs: -------------------------------------------------------------------------------- 1 | defmodule SupervisorSharedSpec do 2 | use ESpec, shared: true 3 | 4 | subject do: shared.described_module.init(init_value) 5 | 6 | describe ".init" do 7 | context "on OK value" do 8 | let :init_value, do: :ok 9 | 10 | it do: is_expected |> to(be_ok_result) 11 | 12 | it "returns specification" do 13 | {:ok, {spec, _}} = subject 14 | expect(spec) |> to(eq {shared.strategy, 3, 5}) 15 | end 16 | end 17 | end 18 | end 19 | --------------------------------------------------------------------------------