Skip to content

Commit 4aaa7b3

Browse files
committed
Fix more dialyzer errors with GitHub sync/services and with emails
1 parent 75880ee commit 4aaa7b3

File tree

6 files changed

+88
-71
lines changed

6 files changed

+88
-71
lines changed

lib/code_corps/comment/service.ex

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,19 @@ defmodule CodeCorps.Comment.Service do
77
alias CodeCorps.{
88
Comment,
99
GitHub,
10+
GitHub.Sync,
1011
GithubComment,
1112
GithubIssue,
1213
Task,
1314
Repo
1415
}
15-
alias CodeCorps.GitHub.Sync.Comment.GithubComment, as: GithubCommentSyncer
1616
alias Ecto.{Changeset, Multi}
1717

1818
require Logger
1919

20+
@type record_result ::
21+
{:ok, Comment.t} | {:error, Changeset.t} | {:error, GitHub.api_error_struct()}
22+
2023
# :user, :github_issue and :github_repo are required for connecting to github
2124
# :project and :organization are required in order to add a header to the
2225
# github comment body when the user themselves are not connected to github,
@@ -42,11 +45,13 @@ defmodule CodeCorps.Comment.Service do
4245
"""
4346
@spec create(map) :: {:ok, Comment.t} | {:error, Changeset.t}
4447
def create(%{} = attributes) do
45-
Multi.new
48+
Multi.new()
4649
|> Multi.insert(:comment, %Comment{} |> Comment.create_changeset(attributes))
47-
|> Multi.run(:preload, fn %{comment: %Comment{} = comment} -> {:ok, comment |> Repo.preload(@preloads)} end)
48-
|> Multi.run(:github, (fn %{preload: %Comment{} = comment} -> comment |> create_on_github() end))
49-
|> Repo.transaction
50+
|> Multi.run(:preload, fn %{comment: %Comment{} = comment} ->
51+
{:ok, comment |> Repo.preload(@preloads)}
52+
end)
53+
|> Multi.run(:github, fn %{preload: %Comment{} = comment} -> comment |> create_on_github() end)
54+
|> Repo.transaction()
5055
|> marshall_result
5156
end
5257

@@ -55,30 +60,34 @@ defmodule CodeCorps.Comment.Service do
5560
"""
5661
@spec update(Comment.t, map) :: {:ok, Comment.t} | {:error, Changeset.t}
5762
def update(%Comment{} = comment, %{} = attributes) do
58-
Multi.new
63+
Multi.new()
5964
|> Multi.update(:comment, comment |> Comment.update_changeset(attributes))
60-
|> Multi.run(:github, (fn %{comment: %Comment{} = comment} -> comment |> update_on_github() end))
61-
|> Repo.transaction
65+
|> Multi.run(:preload, fn %{comment: %Comment{} = comment} ->
66+
{:ok, comment |> Repo.preload(@preloads)}
67+
end)
68+
|> Multi.run(:github, fn %{preload: %Comment{} = comment} -> comment |> update_on_github() end)
69+
|> Repo.transaction()
6270
|> marshall_result()
6371
end
6472

6573
@spec marshall_result(tuple) :: {:ok, Comment.t} | {:error, Changeset.t} | {:error, :github}
6674
defp marshall_result({:ok, %{github: %Comment{} = comment}}), do: {:ok, comment}
6775
defp marshall_result({:error, :comment, %Changeset{} = changeset, _steps}), do: {:error, changeset}
6876
defp marshall_result({:error, :github, result, _steps}) do
69-
Logger.info "An error occurred when creating/updating the comment with the GitHub API"
70-
Logger.info "#{inspect result}"
77+
Logger.info("An error occurred when creating/updating the comment with the GitHub API")
78+
Logger.info("#{inspect(result)}")
7179
{:error, :github}
7280
end
7381

74-
@spec create_on_github(Comment.t) :: {:ok, Comment.t} :: {:error, GitHub.api_error_struct}
82+
@spec create_on_github(Comment.t) :: record_result
7583
defp create_on_github(%Comment{task: %Task{github_issue_id: nil}} = comment), do: {:ok, comment}
7684
defp create_on_github(%Comment{task: %Task{github_issue: github_issue}} = comment) do
77-
with {:ok, payload} <- comment |> GitHub.API.Comment.create,
78-
{:ok, %GithubComment{} = github_comment} <- GithubCommentSyncer.create_or_update_comment(github_issue, payload)do
79-
comment |> link_with_github_changeset(github_comment) |> Repo.update
85+
with {:ok, payload} <- comment |> GitHub.API.Comment.create(),
86+
{:ok, %GithubComment{} = github_comment} <-
87+
Sync.Comment.GithubComment.create_or_update_comment(github_issue, payload) do
88+
comment |> link_with_github_changeset(github_comment) |> Repo.update()
8089
else
81-
{:error, github_error} -> {:error, github_error}
90+
{:error, error} -> {:error, error}
8291
end
8392
end
8493

@@ -87,16 +96,17 @@ defmodule CodeCorps.Comment.Service do
8796
comment |> Changeset.change(%{github_comment: github_comment})
8897
end
8998

90-
@spec update_on_github(Comment.t) :: {:ok, Comment.t} :: {:error, GitHub.api_error_struct}
99+
@spec update_on_github(Comment.t) :: record_result
91100
defp update_on_github(%Comment{github_comment_id: nil} = comment), do: {:ok, comment}
92-
defp update_on_github(%Comment{} = comment) do
93-
with %Comment{task: %Task{github_issue: %GithubIssue{} = github_issue}} = comment <- comment |> Repo.preload(@preloads),
94-
{:ok, payload} <- comment |> GitHub.API.Comment.update,
95-
{:ok, %GithubComment{}} <- GithubCommentSyncer.create_or_update_comment(github_issue, payload) do
96-
101+
defp update_on_github(
102+
%Comment{task: %Task{github_issue: %GithubIssue{} = github_issue}} = comment
103+
) do
104+
with {:ok, payload} <- comment |> GitHub.API.Comment.update(),
105+
{:ok, %GithubComment{}} <-
106+
Sync.Comment.GithubComment.create_or_update_comment(github_issue, payload) do
97107
{:ok, comment}
98108
else
99-
{:error, github_error} -> {:error, github_error}
109+
{:error, error} -> {:error, error}
100110
end
101111
end
102112
end

lib/code_corps/emails/receipt_email.ex

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ defmodule CodeCorps.Emails.ReceiptEmail do
77

88
@spec create(StripeConnectCharge.t, Stripe.Invoice.t) :: Bamboo.Email.t
99
def create(%StripeConnectCharge{} = charge, %Stripe.Invoice{} = invoice) do
10-
with %StripeConnectCharge{} = charge <- preload(charge),
10+
with %StripeConnectCharge{} = charge <- Repo.preload(charge, :user),
1111
%Project{} = project <- get_project(invoice.subscription),
1212
{:ok, %DonationGoal{} = current_donation_goal} <- get_current_donation_goal(project),
1313
template_model <- build_model(charge, project, current_donation_goal)
@@ -21,9 +21,6 @@ defmodule CodeCorps.Emails.ReceiptEmail do
2121
end
2222
end
2323

24-
@spec preload(Project.t) :: Project.t
25-
defp preload(%StripeConnectCharge{} = charge), do: Repo.preload(charge, :user)
26-
2724
@spec get_project(String.t) :: Project.t | {:error, :subscription_not_found}
2825
defp get_project(subscription_id_from_stripe) do
2926
with %StripeConnectSubscription{} = subscription <- get_subscription(subscription_id_from_stripe) do
@@ -79,7 +76,7 @@ defmodule CodeCorps.Emails.ReceiptEmail do
7976
"https://d3pgew4wbk2vb1.cloudfront.net/emails/images/emoji-1f64c-1f3ff@2x.png"
8077
]
8178

82-
@spec format_amount(float) :: String.t
79+
@spec format_amount(integer) :: binary
8380
defp format_amount(amount) do
8481
amount |> Money.new(:USD) |> Money.to_string()
8582
end

lib/code_corps/github/sync/comment/github_comment/github_comment.ex

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@ defmodule CodeCorps.GitHub.Sync.Comment.GithubComment do
1515
GithubUser,
1616
Repo
1717
}
18-
1918
alias Ecto.Changeset
20-
alias Sync.User.GithubUser, as: GithubUserSyncer
2119

22-
@typep linking_result :: {:ok, GithubComment.t} | {:error, Changeset.t}
20+
@type result :: {:ok, GithubComment.t} | {:error, Changeset.t}
2321

2422
@doc ~S"""
2523
Finds or creates a `CodeCorps.GithubComment` using the data in a GitHub
@@ -34,7 +32,7 @@ defmodule CodeCorps.GitHub.Sync.Comment.GithubComment do
3432
`CodeCorps.GitHub.Adapters.Comment.to_github_comment/1` is used to adapt the
3533
payload data.
3634
"""
37-
@spec create_or_update_comment(GithubIssue.t, map) :: linking_result
35+
@spec create_or_update_comment(GithubIssue.t, map) :: result
3836
def create_or_update_comment(%GithubIssue{} = github_issue, %{} = %{"id" => github_comment_id} = attrs) do
3937
params = to_params(attrs, github_issue)
4038
case Repo.get_by(GithubComment, github_id: github_comment_id) do
@@ -50,19 +48,18 @@ defmodule CodeCorps.GitHub.Sync.Comment.GithubComment do
5048
The comment is matched with an existing GithubIssue record using the
5149
`issue_url` property of the payload.
5250
"""
53-
@spec create_or_update_comment(GithubRepo.t, map) :: linking_result
51+
@spec create_or_update_comment(GithubRepo.t, map) :: result
5452
def create_or_update_comment(%GithubRepo{} = github_repo, %{"id" => _, "issue_url" => _} = attrs) do
55-
with {:ok, %GithubUser{} = github_user} <- GithubUserSyncer.create_or_update_github_user(attrs),
56-
{:ok, %GithubComment{} = github_comment} <- do_create_or_update_comment(github_repo, attrs, github_user)
57-
do
53+
with {:ok, %GithubUser{} = github_user} <- Sync.User.GithubUser.create_or_update_github_user(attrs),
54+
{:ok, %GithubComment{} = github_comment} <- do_create_or_update_comment(github_repo, attrs, github_user) do
5855
{:ok, github_comment}
5956
else
6057
{:error, error} -> {:error, error}
6158
end
6259
end
6360

6461
defp do_create_or_update_comment(
65-
%GithubRepo{} = github_repo,
62+
%GithubRepo{} = github_repo,
6663
%{"id" => github_id, "issue_url" => issue_url} = attrs,
6764
%GithubUser{} = github_user) do
6865

@@ -100,14 +97,14 @@ defmodule CodeCorps.GitHub.Sync.Comment.GithubComment do
10097
end
10198
end
10299

103-
@spec create_comment(map) :: linking_result
100+
@spec create_comment(map) :: result
104101
defp create_comment(params) do
105102
%GithubComment{}
106103
|> GithubComment.create_changeset(params)
107104
|> Repo.insert
108105
end
109106

110-
@spec update_comment(GithubComment.t, map) :: linking_result
107+
@spec update_comment(GithubComment.t, map) :: result
111108
defp update_comment(%GithubComment{} = github_comment, %{} = params) do
112109
github_comment
113110
|> GithubComment.update_changeset(params)

lib/code_corps/github/sync/issue/github_issue/github_issue.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ defmodule CodeCorps.GitHub.Sync.Issue.GithubIssue do
1818

1919
alias Ecto.Changeset
2020

21-
@typep linking_result :: {:ok, GithubIssue.t} | {:error, Changeset.t}
21+
@type result :: {:ok, GithubIssue.t} | {:error, Changeset.t}
2222

2323
@doc ~S"""
2424
Creates or updates a `CodeCorps.GithubIssue` from a github issue API payload.
@@ -29,16 +29,16 @@ defmodule CodeCorps.GitHub.Sync.Issue.GithubIssue do
2929
The created record is also associated with a matched `CodeCorps.GithubUser`, which is
3030
created if necessary.
3131
"""
32-
@spec create_or_update_issue(map, GithubRepo.t, GithubPullRequest.t | nil) :: linking_result
32+
@spec create_or_update_issue(map, GithubRepo.t, GithubPullRequest.t | nil) :: result
3333
def create_or_update_issue(%{} = payload, %GithubRepo{} = github_repo, github_pull_request \\ nil) do
3434
with {:ok, %GithubUser{} = github_user} <- Sync.User.GithubUser.create_or_update_github_user(payload) do
3535
payload
3636
|> find_or_init()
37-
|> GithubIssue.changeset(payload |> Adapters.Issue.to_issue)
37+
|> GithubIssue.changeset(payload |> Adapters.Issue.to_issue())
3838
|> Changeset.put_assoc(:github_user, github_user)
3939
|> Changeset.put_assoc(:github_repo, github_repo)
4040
|> Changeset.put_assoc(:github_pull_request, github_pull_request)
41-
|> Repo.insert_or_update
41+
|> Repo.insert_or_update()
4242
else
4343
{:error, error} -> {:error, error}
4444
end

lib/code_corps/github/sync/user/record_linker.ex

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ defmodule CodeCorps.GitHub.Sync.User.RecordLinker do
1818
User
1919
}
2020

21-
@typep linking_result :: {:ok, User.t} |
22-
{:error, Ecto.Changeset.t} |
23-
{:error, :multiple_users}
21+
@type result :: {:ok, User.t} |
22+
{:error, Ecto.Changeset.t} |
23+
{:error, :multiple_users}
2424

2525
@doc ~S"""
2626
Finds or creates a user using information in the resource and the GitHub API
@@ -38,7 +38,7 @@ defmodule CodeCorps.GitHub.Sync.User.RecordLinker do
3838
- If there are multiple matching users, this is an unexpected scenario and
3939
should error out.
4040
"""
41-
@spec link_to(GithubComment.t | GithubIssue.t, map) :: linking_result
41+
@spec link_to(GithubComment.t | GithubIssue.t, map) :: result
4242
def link_to(%GithubComment{} = comment, %{"user" => user}), do: do_link_to(comment, user)
4343
def link_to(%GithubIssue{} = issue, %{"user" => user}), do: do_link_to(issue, user)
4444

@@ -65,7 +65,7 @@ defmodule CodeCorps.GitHub.Sync.User.RecordLinker do
6565
query |> Repo.all
6666
end
6767

68-
@spec marshall_response(list, map) :: linking_result
68+
@spec marshall_response(list, map) :: result
6969
defp marshall_response([%User{} = single_user], %{}), do: {:ok, single_user}
7070
defp marshall_response([], %{} = user_attrs) do
7171
user_attrs |> find_or_create_disassociated_user()

lib/code_corps/task/service.ex

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,37 @@ defmodule CodeCorps.Task.Service do
33
Handles special CRUD operations for `CodeCorps.Task`.
44
"""
55

6-
alias CodeCorps.{GitHub, GithubIssue, Repo, Task}
6+
alias CodeCorps.{GitHub, GitHub.Sync, GithubIssue, Repo, Task}
77
alias Ecto.{Changeset, Multi}
88

99
require Logger
1010

11+
# :user, :github_issue and :github_repo are required for connecting to github
12+
# :project and :organization are required in order to add a header to the
13+
# github issue body when the user themselves are not connected to github, but
14+
# the task is
15+
#
16+
# Right now, all of these preloads are loaded at once. If there are
17+
# performance issues, we can split them up according the the information
18+
# provided here.
19+
@preloads [
20+
:github_issue,
21+
[github_repo: :github_app_installation],
22+
[project: :organization],
23+
:user
24+
]
25+
1126
@doc ~S"""
1227
Performs all actions involved in creating a task on a project
1328
"""
1429
@spec create(map) :: {:ok, Task.t} | {:error, Changeset.t} | {:error, :github}
1530
def create(%{} = attributes) do
1631
Multi.new
1732
|> Multi.insert(:task, %Task{} |> Task.create_changeset(attributes))
18-
|> Multi.run(:github, (fn %{task: %Task{} = task} -> task |> create_on_github() end))
33+
|> Multi.run(:preload, fn %{task: %Task{} = task} ->
34+
{:ok, task |> Repo.preload(@preloads)}
35+
end)
36+
|> Multi.run(:github, (fn %{preload: %Task{} = task} -> task |> create_on_github() end))
1937
|> Repo.transaction
2038
|> marshall_result()
2139
end
@@ -24,7 +42,10 @@ defmodule CodeCorps.Task.Service do
2442
def update(%Task{} = task, %{} = attributes) do
2543
Multi.new
2644
|> Multi.update(:task, task |> Task.update_changeset(attributes))
27-
|> Multi.run(:github, (fn %{task: %Task{} = task} -> task |> update_on_github() end))
45+
|> Multi.run(:preload, fn %{task: %Task{} = task} ->
46+
{:ok, task |> Repo.preload(@preloads)}
47+
end)
48+
|> Multi.run(:github, (fn %{preload: %Task{} = task} -> task |> update_on_github() end))
2849
|> Repo.transaction
2950
|> marshall_result()
3051
end
@@ -39,25 +60,16 @@ defmodule CodeCorps.Task.Service do
3960
{:error, :github}
4061
end
4162

42-
# :user, :github_issue and :github_repo are required for connecting to github
43-
# :project and :organization are required in order to add a header to the
44-
# github issue body when the user themselves are not connected to github, but
45-
# the task is
46-
#
47-
# Right now, all of these preloads are loaded at once. If there are
48-
# performance issues, we can split them up according the the information
49-
# provided here.
50-
@preloads [:github_issue, [github_repo: :github_app_installation], :user, [project: :organization]]
51-
52-
@spec create_on_github(Task.t) :: {:ok, Task.t} :: {:error, GitHub.api_error_struct}
63+
@spec create_on_github(Task.t) :: {:ok, Task.t} | {:error, Changeset.t} | {:error, GitHub.api_error_struct}
5364
defp create_on_github(%Task{github_repo_id: nil} = task) do
5465
# Don't create: no GitHub repo was selected
5566
{:ok, task}
5667
end
57-
defp create_on_github(%Task{github_repo: _} = task) do
58-
with %Task{github_repo: github_repo} = task <- task |> Repo.preload(@preloads),
59-
{:ok, payload} <- GitHub.API.Issue.create(task),
60-
{:ok, %GithubIssue{} = github_issue} <- payload |> GitHub.Sync.Issue.GithubIssue.create_or_update_issue(github_repo) do
68+
defp create_on_github(%Task{github_repo: github_repo} = task) do
69+
with {:ok, payload} <- GitHub.API.Issue.create(task),
70+
{:ok, %GithubIssue{} = github_issue} <-
71+
payload
72+
|> Sync.Issue.GithubIssue.create_or_update_issue(github_repo) do
6173
task |> link_with_github_changeset(github_issue) |> Repo.update
6274
else
6375
{:error, error} -> {:error, error}
@@ -69,16 +81,17 @@ defmodule CodeCorps.Task.Service do
6981
task |> Changeset.change(%{github_issue: github_issue})
7082
end
7183

72-
@spec update_on_github(Task.t) :: {:ok, Task.t} :: {:error, GitHub.api_error_struct}
84+
@spec update_on_github(Task.t) :: {:ok, Task.t} | {:error, Changeset.t} | {:error, GitHub.api_error_struct}
7385
defp update_on_github(%Task{github_repo_id: nil, github_issue_id: nil} = task), do: {:ok, task}
7486
defp update_on_github(%Task{github_repo_id: _, github_issue_id: nil} = task), do: task |> create_on_github()
75-
defp update_on_github(%Task{github_repo_id: _} = task) do
76-
with %Task{github_repo: github_repo} = task <- task |> Repo.preload(@preloads),
77-
{:ok, payload} <- GitHub.API.Issue.update(task),
78-
{:ok, %GithubIssue{}} <- payload |> GitHub.Sync.Issue.GithubIssue.create_or_update_issue(github_repo) do
87+
defp update_on_github(%Task{github_repo: github_repo} = task) do
88+
with {:ok, payload} <- GitHub.API.Issue.update(task),
89+
{:ok, %GithubIssue{}} <-
90+
payload
91+
|> Sync.Issue.GithubIssue.create_or_update_issue(github_repo) do
7992
{:ok, Task |> Repo.get(task.id)}
8093
else
81-
{:error, github_error} -> {:error, github_error}
94+
{:error, error} -> {:error, error}
8295
end
8396
end
8497
end

0 commit comments

Comments
 (0)