Skip to content

Instantly share code, notes, and snippets.

@jdfrens
Created March 27, 2019 16:42
Show Gist options
  • Save jdfrens/95113c6ded87bed4ba11ee2b8a7fc082 to your computer and use it in GitHub Desktop.
Save jdfrens/95113c6ded87bed4ba11ee2b8a7fc082 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# Generates a very opinionated `tasks.json` for Elixir projects.
#
# Usage (from the root of your project)
#
# mkdir .vscode
# cp .vscode/tasks.json .vscode/tasks.backup.json
# task-maker > .vscode/tasks.json
#
# Creates build tasks:
# Deps.get
# Compile (MIX_ENV=test)
# Clean
# Clobber
# Dialyzer (MIX_ENV=test)
# Credo (MIX_ENV=test)
#
# Creates test tasks:
# All unit tests -- runs `mix test` in root
# ExCoveralls -- runs `mix coveralls.html --umbrella`
# Everything -- runs `mix all_tests`
# component-app-1 tests
# component-app-2 tests
# ...
# component-app-n tests
#
# The component-app-i tests run the tests in the component directories (e.g., apps/component-app-i)
#
require 'json'
class ComponentApp
def self.list
Dir.glob("apps/*").map do |dir|
ComponentApp.new(dir)
end
end
def initialize(dir)
@dir = dir
end
def directory
@dir
end
def name
@dir.gsub("apps/", "")
end
end
class TaskJSON
def self.generate
new.generate
end
def generate
puts JSON.generate(json, indent: " ", space: " ", object_nl: "\n", array_nl: "\n")
end
def json
{
"version": "2.0.0",
"tasks": tasks
}
end
def tasks
umbrella_tasks +
component_app_tasks +
build_tasks
end
def build_tasks
pm = ["$mixCompileError", "$mixCompileWarning"]
[
mix_task(label: "Deps.get", args: "deps.get", group: "build"),
mix_task(label: "Compile", args: ["compile", "--force", "--warnings-as-errors"], group: "build", options: {"env": test_env}, problem_matcher: pm),
mix_task(label: "Clean", args: "clean", group: "build", problem_matcher: pm),
mix_task(label: "Clobber", args: do_args("clean", "deps.clean -all"), group: "build", problem_matcher: pm),
mix_task(label: "Dialyzer", args: "dialyzer", group: "build", options: {"env": test_env}, problem_matcher: pm),
mix_task(label: "Credo", args: ["credo", "--strict"], group: "build", options: {"env": test_env}, problem_matcher: pm)
]
end
def do_args(*args)
["do"] + args.map {|a| "#{a},"}
end
def umbrella_tasks
[
mix_task(label: "All unit tests", args: ["test"], group: "test"),
mix_task(label: "ExCoveralls", args: ["coveralls.html", "--umbrella"], group: "test"),
mix_task(label: "Everything", args: ["all_tests"], group: "test"),
]
end
def component_app_tasks
ComponentApp.list.map do |app|
component_app_test(app)
end
end
def component_app_test(app)
mix_task(label: "#{app.name} tests", args: ["test"], group: "test", options: {cwd: app.directory})
end
def mix_task(label:, args:, group:, problem_matcher: [], options: {})
base = {
label: label,
type: "shell",
command: "mix",
args: Array(args),
group: group,
presentation: {
reveal: "always",
panel: "new"
},
problemMatcher: problem_matcher
}
base = merge_not_empty(base, :options, options)
base
end
def merge_not_empty(base, field, value)
if value.empty?
base
else
base.merge(field => value)
end
end
def test_env
{"MIX_ENV": "test"}
end
end
TaskJSON.generate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment