Skip to content

Commit

Permalink
Merge pull request #68 from haldihri3/develop
Browse files Browse the repository at this point in the history
refactor: typespec #16
  • Loading branch information
Kit Plummer authored Jul 6, 2020
2 parents 89d1712 + aa1e534 commit 3d551f6
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 5 deletions.
6 changes: 5 additions & 1 deletion lib/analyzer_module.ex
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ defmodule AnalyzerModule do
```
"""
# @defaults %{start_time: DateTime.utc_now()}
@spec analyze([binary], any, any, any) :: {:ok, map}
def analyze(urls, source \\ "lei", start_time \\ DateTime.utc_now(), options \\ %{})
when is_list(urls) do
## Concurrency for parallelizing the analysis. This is the magic.
Expand Down Expand Up @@ -304,6 +305,7 @@ defmodule AnalyzerModule do
produces the repo report object to be returned immediately by asynchronous
requestors (e.g. LowEndInsight-Get HTTP endpoint)
"""
@spec create_empty_report(String.t, [String.t], any) :: map
def create_empty_report(uuid, urls, start_time \\ DateTime.utc_now()) do
%{
:metadata => %{
Expand All @@ -325,9 +327,10 @@ defmodule AnalyzerModule do
determine_risk_counts/1: takes in a full report of n-repo reports, and calculates
the number or risk ratings, given the number of repos. It returns a new report
with the risk_counts object populated with the count table. Have to accommodate
both the atom and string elements, becuse the JSON gets parsed into the string
both the atom and string elements, because the JSON gets parsed into the string
format - so caching can be supported (as reports are stored in JSON).
"""
@spec determine_risk_counts(RepoReport.t) :: map
def determine_risk_counts(report) do
count_map =
report[:report][:repos]
Expand All @@ -342,6 +345,7 @@ defmodule AnalyzerModule do
determine_toplevel_risk/1: takes in a report and determines the highest
criticality, and assigns it to the "risk" element for the repo report.
"""
@spec determine_toplevel_risk(RepoReport.t) :: map
def determine_toplevel_risk(report) do
values = Map.values(report[:data][:results])

Expand Down
5 changes: 4 additions & 1 deletion lib/git_helper.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ defmodule GitHelper do
@doc """
parse_diff/1: returns the relevant information contained in the last array position of a diff array
"""
@spec parse_diff([String.t]) :: {:ok, non_neg_integer, non_neg_integer, non_neg_integer}
def parse_diff(list) do
last = List.last(list)
last_trimmed = String.trim(last)
Expand Down Expand Up @@ -91,7 +92,7 @@ defmodule GitHelper do
{:ok, length, filtered_list}
end

@spec parse_shortlog(binary) :: [Contributor.t()]
@spec parse_shortlog(String.t) :: [Contributor.t()]
def parse_shortlog(log) do
split_shortlog(log)
|> Enum.map(fn contributor ->
Expand Down Expand Up @@ -197,6 +198,7 @@ defmodule GitHelper do
end
end

@spec get_contributor_counts([], non_neg_integer) :: {:ok, non_neg_integer}
defp get_contributor_counts([], accumulator) do
{:ok, accumulator}
end
Expand All @@ -206,6 +208,7 @@ defmodule GitHelper do
10 * length(String.split(x, " ")) + String.length(x)
end

@spec filter_contributors([any]) :: [any]
defp filter_contributors([]) do
[]
end
Expand Down
21 changes: 18 additions & 3 deletions lib/git_module.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ defmodule GitModule do
@doc """
clone_repo/2: clones the repo
"""

@spec clone_repo(String.t, String.t) :: {:ok, String.t} | {:error, String.t}
def clone_repo(url, tmp_path) do
{:ok, slug} = url |> Helpers.get_slug()
{:ok, _, repo_name} = Helpers.split_slug(slug)
Expand All @@ -30,20 +30,22 @@ defmodule GitModule do
@doc """
get_repo/1: gets a repo by path, returns Repository struct
"""
@spec get_repo(String.t) :: {:ok, Git.Repository.t()} | {:error, String.t}
def get_repo(path) do
with repo <- Git.new(path),
{:ok, _} <- Git.status(repo)
do
{:ok, repo}
else
error -> error
{:error, msg} -> {:error, msg}
end
end

@doc """
get_contributors_count/1: returns the number of contributors for
a given Git repo
"""
@spec get_contributor_count(Git.Repository.t()) :: {:ok, non_neg_integer}
def get_contributor_count(repo) do
count =
Git.shortlog!(repo, ["-s", "-n", "HEAD", "--"])
Expand All @@ -57,19 +59,21 @@ defmodule GitModule do
@doc """
get_last_commit_date/1: returns the date of the last commit
"""

@spec get_last_commit_date(Git.Repository.t()) :: {:ok, String.t}
def get_last_commit_date(repo) do
date = Git.log!(repo, ["-1", "--pretty=format:%cI"])
{:ok, date}
end

@spec delete_repo(Git.Repository.t()) :: String.t
def delete_repo(repo) do
File.rm_rf!(repo.path)
end

@doc """
get_current_hash/1: returns the hash of the repo's HEAD
"""
@spec get_hash(Git.Repository.t()) :: {:ok, String.t}
def get_hash(repo) do
hash = Git.rev_parse!(repo, "HEAD") |> String.trim()
{:ok, hash}
Expand All @@ -78,6 +82,7 @@ defmodule GitModule do
@doc """
get_default_branch/1: returns the default branch of the remote repo
"""
@spec get_default_branch(Git.Repository.t()) :: {:ok, String.t}
def get_default_branch(repo) do
try do
default_branch = Git.symbolic_ref!(repo, "refs/remotes/origin/HEAD") |> String.trim()
Expand All @@ -90,6 +95,7 @@ defmodule GitModule do
@doc """
get_commit_dates/1: returns a list of unix timestamps representing commit times
"""
@spec get_commit_dates(Git.Repository.t()) :: {:ok, [non_neg_integer]}
def get_commit_dates(repo) do
dates =
Git.log!(repo, ["--pretty=format:%ct"])
Expand All @@ -103,6 +109,7 @@ defmodule GitModule do
get_tag_and_commit_dates/1: returns a list of lists of unix timestamps
representing commit times with each lsit belonging to a different tag
"""
@spec get_tag_and_commit_dates(Git.Repository.t()) :: [any]
def get_tag_and_commit_dates(repo) do
tag_and_date =
Git.log!(repo, ["--pretty=format:%d$%ct"])
Expand All @@ -125,6 +132,7 @@ defmodule GitModule do
@doc """
get_last_n_commits/1: returns a list of the short hashes of the last n commits
"""
@spec get_last_n_commits(Git.Repository.t(), non_neg_integer) :: {:ok, [any]}
def get_last_n_commits(repo, n) do
output = Git.log!(repo, ["--pretty=format:%h", "--no-merges", "-#{n}"])
{:ok, String.split(output, "\n")}
Expand All @@ -133,6 +141,7 @@ defmodule GitModule do
@doc """
get_last_n_commits/2: returns a list of lines generated from the diff of two commits
"""
@spec get_diff_2_commits(Git.Repository.t(), [any]) :: {:ok, [String.t]} | []
def get_diff_2_commits(repo, [commit1 | [commit2 | []]]) do
with {:ok, diff} <- Git.diff(repo, ["--stat", commit1, commit2]) do
{:ok, String.split(String.trim_trailing(diff, "\n"), "\n")}
Expand All @@ -144,6 +153,7 @@ defmodule GitModule do
@doc """
get_total_lines/1: returns the total lines and files contained in a repo as of the latest commit
"""
@spec get_total_lines(Git.Repository.t()) :: {:ok, non_neg_integer, non_neg_integer}
def get_total_lines(repo) do
{:ok, hash} = Git.hash_object(repo, ["-t", "tree", "/dev/null"])
{:ok, diff} = Git.diff(repo, ["--shortstat", String.replace_suffix(hash, "\n", "")])
Expand All @@ -156,6 +166,7 @@ defmodule GitModule do
@doc """
get_recent_changes/1: returns the percentage of changed lines in the last commit by the total lines in the repo
"""
@spec get_recent_changes(Git.Repository.t()) :: {:ok, float}
def get_recent_changes(repo) do
with {:ok, total_lines, total_files_changed} <- get_total_lines(repo),
{:ok, file_num, insertions, deletions} = get_last_2_delta(repo)
Expand All @@ -168,6 +179,7 @@ defmodule GitModule do
@doc """
get_last_2_delta/1: returns the lines changed, files changed, additions and deletions in the last commit
"""
@spec get_last_2_delta(Git.Repository.t()) :: {:ok, non_neg_integer, non_neg_integer, non_neg_integer}
def get_last_2_delta(repo) do
{:ok, commits} = get_last_n_commits(repo, 2)

Expand Down Expand Up @@ -234,6 +246,7 @@ defmodule GitModule do
{:ok, map}
end

@spec get_clean_contributions_map(Git.Repositories.t()) :: {:ok, map}
def get_clean_contributions_map(repo) do
map =
Git.shortlog!(repo, ["-n", "-e", "HEAD", "--"])
Expand Down Expand Up @@ -279,6 +292,7 @@ defmodule GitModule do
{:ok, map10}
end

@spec get_repo_size(Git.Repository.t()) :: {:ok, String.t}
def get_repo_size(repo) do
space =
elem(System.cmd("du", ["-sh", "#{repo.path}"]), 0)
Expand All @@ -289,6 +303,7 @@ defmodule GitModule do
{:ok, space}
end

@spec raw_binary_to_string(binary) :: String.t
defp raw_binary_to_string(raw) do
String.codepoints(raw)
|> Enum.reduce(fn w, result ->
Expand Down
8 changes: 8 additions & 0 deletions lib/helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ defmodule Helpers do
iex(2)> slug
"kitplummer/xmpprails"
"""
@spec get_slug(String.t) :: {:ok, String.t} | {:error, String.t}
def get_slug(url) do
uri = URI.parse(url)

Expand All @@ -42,6 +43,7 @@ defmodule Helpers do
"xmpprails"
"""
@spec split_slug(String.t) :: {:ok, String.t, String.t} | {:error, String.t}
def split_slug(slug) do
if String.contains?(slug, "/") do
v = String.split(slug, "/")
Expand All @@ -51,6 +53,7 @@ defmodule Helpers do
end
end

@spec count_forward_slashes(String.t) :: non_neg_integer
def count_forward_slashes(url) do
url |> String.graphemes() |> Enum.count(&(&1 == "/"))
end
Expand Down Expand Up @@ -79,6 +82,7 @@ defmodule Helpers do
...> |> Helpers.validate_url()
{:error, "invalid URI host"}
"""
@spec validate_url(String.t) :: :ok | {:error, String.t}
def validate_url(url) do
try do
with :ok <- validate_scheme(url),
Expand Down Expand Up @@ -107,6 +111,7 @@ defmodule Helpers do
...> |> Helpers.validate_urls()
{:error, "invalid URI"}
"""
@spec validate_urls([String.t]) :: :ok | {:error, String.t}
def validate_urls(urls) do
try do
if !is_list(urls), do: throw(:break)
Expand All @@ -127,6 +132,7 @@ defmodule Helpers do
# {:hostent, 'https.cust.blueprintrf.com', [], :inet, 4,
# [{23, 202, 231, 167}, {23, 217, 138, 108}]}}
# oh well i guess, will handle the issue downstream i guess.
@spec validate_host(String.t) :: :ok | {:error, String.t}
defp validate_host(url) do
case URI.parse(url) do
%URI{host: host, path: path} ->
Expand All @@ -152,6 +158,7 @@ defmodule Helpers do
end
end

@spec validate_scheme(String.t) :: :ok | {:error, String.t}
defp validate_scheme(url) do
case URI.parse(url) do
%URI{scheme: nil} ->
Expand All @@ -172,6 +179,7 @@ defmodule Helpers do
maps, to be encoded as JSON. Since JSON doesn't have an equivalent tuple type the
libs all bonk on encoding config values.
"""
@spec convert_config_to_list([any]) :: map
def convert_config_to_list(config) do
Enum.into(config, %{})
|> Map.delete(:jobs_per_core_max)
Expand Down
4 changes: 4 additions & 0 deletions lib/risk_logic.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule RiskLogic do
@doc """
contributor_risk/1: returns text enumeration for count
"""
@spec contributor_risk(non_neg_integer) :: {:ok, String.t}
def contributor_risk(contributor_count) do
critical_contributor_level =
if Application.fetch_env(:lowendinsight, :critical_contributor_level) == :error,
Expand Down Expand Up @@ -45,6 +46,7 @@ defmodule RiskLogic do
@doc """
commit_currency_risk/1: returns text enumeration for commit currency risk
"""
@spec commit_currency_risk(non_neg_integer) :: {:ok, String.t}
def commit_currency_risk(delta_in_weeks) do
medium_currency_level =
if Application.fetch_env(:lowendinsight, :medium_currency_level) == :error,
Expand Down Expand Up @@ -79,6 +81,7 @@ defmodule RiskLogic do
@doc """
last_commit_size_risk/1: returns a text enumeration for the risk based on the size of the last commit
"""
@spec commit_change_size_risk(non_neg_integer) :: {:ok, String.t}
def commit_change_size_risk(change_percent) do
medium_large_commit_level =
if Application.fetch_env(:lowendinsight, :medium_large_commit_level) == :error,
Expand Down Expand Up @@ -113,6 +116,7 @@ defmodule RiskLogic do
@doc """
functional_contributors_risk/1: returns the enumerated risk based on input contributors list
"""
@spec functional_contributors_risk(non_neg_integer) :: {:ok, String.t}
def functional_contributors_risk(contributors) do
medium_functional_contributors_level =
if Application.fetch_env(:lowendinsight, :medium_functional_contributors_level) == :error,
Expand Down
7 changes: 7 additions & 0 deletions lib/time_helper.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ defmodule TimeHelper do
```
"""
@spec sec_to_str(non_neg_integer) :: String.t
def sec_to_str(sec) do
{_, [s, m, h, d, w]} =
Enum.reduce(@divisor, {sec, []}, fn divisor, {n, acc} ->
Expand All @@ -38,20 +39,23 @@ defmodule TimeHelper do
@doc """
sec_to_weeks/1: returns a roll-up of weeks from a number of secs
"""
@spec sec_to_weeks(non_neg_integer) :: non_neg_integer
def sec_to_weeks(sec) do
Kernel.trunc(sec / @week)
end

@doc """
sec_to_days/1: returns a roll-up of days from a number of secs
"""
@spec sec_to_days(non_neg_integer) :: non_neg_integer
def sec_to_days(sec) do
Kernel.trunc(sec / @day)
end

@doc """
get_commit_delta/1: returns the time between now and the last commit in seconds
"""
@spec get_commit_delta(String.t) :: {:ok, String.t} | {:error, String.t}
def get_commit_delta(last_commit_date) do
case DateTime.from_iso8601(last_commit_date) do
{:error, error} ->
Expand All @@ -66,13 +70,15 @@ defmodule TimeHelper do
@doc """
sum_ts_diff/2
"""
@spec sum_ts_diff([any], non_neg_integer) :: {:ok, non_neg_integer}
def sum_ts_diff([_head | []], accumulator) do
{:ok, accumulator}
end

@doc """
sum_ts_diff/2
"""
@spec sum_ts_diff([any], non_neg_integer) :: {:ok, non_neg_integer}
def sum_ts_diff([head_1 | tail], accumulator) do
[head_2 | _next_tail] = tail
[_ | timestamp_1] = head_1
Expand All @@ -83,6 +89,7 @@ defmodule TimeHelper do
@doc """
sum_ts_diff/1
"""
@spec sum_ts_diff([any]) :: {:ok, non_neg_integer}
def sum_ts_diff(list) do
sum_ts_diff(list, 0)
end
Expand Down

0 comments on commit 3d551f6

Please sign in to comment.