diff --git a/lib/excoveralls.ex b/lib/excoveralls.ex index 0c84667..1fbfcd2 100644 --- a/lib/excoveralls.ex +++ b/lib/excoveralls.ex @@ -12,6 +12,7 @@ defmodule ExCoveralls do alias ExCoveralls.Circle alias ExCoveralls.Semaphore alias ExCoveralls.Drone + alias ExCoveralls.Cirrus alias ExCoveralls.Local alias ExCoveralls.Html alias ExCoveralls.Json @@ -22,6 +23,7 @@ defmodule ExCoveralls do @type_circle "circle" @type_semaphore "semaphore" @type_drone "drone" + @type_cirrus "cirrus" @type_local "local" @type_html "html" @type_json "json" @@ -89,6 +91,13 @@ defmodule ExCoveralls do Drone.execute(stats, options) end + @doc """ + Logic for posting from cirrus-ci server + """ + def analyze(stats, @type_cirrus, options) do + Cirrus.execute(stats, options) + end + @doc """ Logic for local stats display, without posting server """ diff --git a/lib/excoveralls/cirrus.ex b/lib/excoveralls/cirrus.ex new file mode 100644 index 0000000..6ed855d --- /dev/null +++ b/lib/excoveralls/cirrus.ex @@ -0,0 +1,54 @@ +defmodule ExCoveralls.Cirrus do + @moduledoc """ + Handles cirrus-ci integration with coveralls. + """ + alias ExCoveralls.Poster + + def execute(stats, options) do + json = generate_json(stats, Enum.into(options, %{})) + if options[:verbose] do + IO.puts json + end + Poster.execute(json) + end + + def generate_json(stats, options \\ %{}) + def generate_json(stats, _options) do + Jason.encode!(%{ + service_job_id: get_job_id(), + service_name: "cirrus", + repo_token: get_repo_token(), + source_files: stats, + git: generate_git_info() + }) + end + + defp generate_git_info do + %{head: %{ + message: get_message(), + id: get_sha() + }, + branch: get_branch() + } + end + + defp get_branch do + System.get_env("CIRRUS_BRANCH") + end + + defp get_job_id do + System.get_env("CIRRUS_BUILD_ID") + end + + defp get_sha do + System.get_env("CIRRUS_CHANGE_IN_REPO") + end + + defp get_message do + System.get_env("CIRRUS_CHANGE_MESSAGE") + end + + defp get_repo_token do + System.get_env("COVERALLS_REPO_TOKEN") + end +end diff --git a/lib/mix/tasks.ex b/lib/mix/tasks.ex index bbdadc1..c10309c 100644 --- a/lib/mix/tasks.ex +++ b/lib/mix/tasks.ex @@ -200,6 +200,20 @@ defmodule Mix.Tasks.Coveralls do end end + defmodule Cirrus do + @moduledoc """ + Provides an entry point for CirrusCI's script. + """ + + use Mix.Task + + @preferred_cli_env :test + + def run(args) do + Mix.Tasks.Coveralls.do_run(args, [type: "cirrus"]) + end + end + defmodule Post do @moduledoc """ Provides an entry point for posting test coverage to diff --git a/test/cirrus_test.exs b/test/cirrus_test.exs new file mode 100644 index 0000000..5980bda --- /dev/null +++ b/test/cirrus_test.exs @@ -0,0 +1,64 @@ +defmodule ExCoveralls.CirrusTest do + use ExUnit.Case + import Mock + alias ExCoveralls.Cirrus + + @content "defmodule Test do\n def test do\n end\nend\n" + @counts [0, 1, nil, nil] + @source_info [%{name: "test/fixtures/test.ex", source: @content, coverage: @counts}] + + setup do + # Capture existing values + orig_vars = + ~w(CIRRUS_BRANCH CIRRUS_BUILD_ID CIRRUS_CHANGE_IN_REPO CIRRUS_CHANGE_MESSAGE COVERALLS_REPO_TOKEN) + |> Enum.map(fn var -> {var, System.get_env(var)} end) + + on_exit(fn -> + # Reset env vars + for {k, v} <- orig_vars do + if v != nil do + System.put_env(k, v) + else + System.delete_env(k) + end + end + end) + + # No additional context + {:ok, []} + end + + test_with_mock "execute", ExCoveralls.Poster, execute: fn _ -> "result" end do + assert(Cirrus.execute(@source_info, []) == "result") + end + + test "generate json for cirrus" do + json = Cirrus.generate_json(@source_info) + assert(json =~ ~r/service_job_id/) + assert(json =~ ~r/service_name/) + assert(json =~ ~r/source_files/) + assert(json =~ ~r/git/) + end + + test "generate from env vars" do + System.put_env("CIRRUS_BRANCH", "branch") + System.put_env("CIRRUS_BUILD_ID", "id") + System.put_env("CIRRUS_CHANGE_MESSAGE", "Initial commit") + System.put_env("CIRRUS_CHANGE_IN_REPO", "sha1") + System.put_env("COVERALLS_REPO_TOKEN", "token") + + {:ok, payload} = Jason.decode(Cirrus.generate_json(@source_info)) + %{"git" => %{"branch" => branch, "head" => %{"message" => message, "id" => id}}} = payload + + assert(branch == "branch") + assert(id == "sha1") + assert(message == "Initial commit") + assert(payload["service_job_id"] == "id") + assert(payload["repo_token"] == "token") + end + + test "submits as `cirrus`" do + parsed = Cirrus.generate_json(@source_info) |> Jason.decode!() + assert(%{"service_name" => "cirrus"} = parsed) + end +end diff --git a/test/excoveralls_test.exs b/test/excoveralls_test.exs index 4f13372..fa2dfc7 100644 --- a/test/excoveralls_test.exs +++ b/test/excoveralls_test.exs @@ -29,6 +29,11 @@ defmodule ExCoverallsTest do assert called ExCoveralls.Drone.execute(@stats,[]) end + test_with_mock "analyze cirrus", ExCoveralls.Cirrus, [execute: fn(_,_) -> nil end] do + ExCoveralls.analyze(@stats, "cirrus", []) + assert called ExCoveralls.Cirrus.execute(@stats,[]) + end + test_with_mock "analyze local", ExCoveralls.Local, [execute: fn(_,_) -> nil end] do ExCoveralls.analyze(@stats, "local", []) assert called ExCoveralls.Local.execute(@stats,[])