Skip to content

Commit

Permalink
major refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
slogsdon committed Mar 29, 2015
1 parent 2780d1e commit 0517ee4
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 96 deletions.
3 changes: 2 additions & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use Mix.Config

config :sugar,
router: HexDepsChecker.Router
router: HexDepsChecker.Router,
show_debugger: true

config :sugar, HexDepsChecker.Router,
https_only: false,
Expand Down
30 changes: 30 additions & 0 deletions lib/hex_deps_checker/badge.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
defmodule HexDepsChecker.Badge do
@badge_base "https://img.shields.io/badge/"

def url(code) do
@badge_base <> name(code) <> ".svg"
end

defp name(code) do
status = statuses[code]
msg = status.msg
|> String.replace("_", "__")
|> String.replace("-", "--")
|> String.replace(" ", "_")
["dependencies",
msg,
status.color]
|> Enum.join("-")
end

defp statuses do
[
ok: %{color: "green",
msg: "up to date"},
available: %{color: "yellow",
msg: "update(s) available"},
unknown: %{color: "lightgrey",
msg: "unknown"}
]
end
end
38 changes: 38 additions & 0 deletions lib/hex_deps_checker/controllers/api.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
defmodule HexDepsChecker.Controllers.Api do
use Sugar.Controller
use HexDepsChecker.ErrorHandler

defmodule UnknownSCMHostError do
defexception message: "Unknown SCM host"
end

def lock(conn, loc: loc, org: org, repo: repo) do
url = get_url(loc, org, repo)
r = url |> HTTPoison.get!
eval_opts = [requires: [],
macros: [],
aliases: [],
functions: []]
json = r.body
|> Code.eval_string([], eval_opts)
|> elem(0)
|> Enum.map(fn {dep, {:hex, dep, version}} ->
%{} |> Map.put(dep, Hex.has_update?(dep, version))
end)
|> Poison.encode!
raw conn |> resp(200, json)
end

defp get_url(loc, org, repo) do
case loc do
"github" -> "https://raw.githubusercontent.com/#{org}/#{repo}/master/mix.lock"
"bitbucket" -> "https://bitbucket.org/#{org}/#{repo}/raw/master/mix.lock"
_ -> raise UnknownSCMHostError
end
end

defp handle_errors(conn, assigns) do
json conn, %{error: assigns.reason}
end
end

86 changes: 4 additions & 82 deletions lib/hex_deps_checker/controllers/main.ex
Original file line number Diff line number Diff line change
@@ -1,90 +1,12 @@
defmodule HexDepsChecker.Controllers.Main do
use Sugar.Controller
alias HexDepsChecker.Badge

defmodule UnknownHostError do
defexception message: "Unknown SCM host"
end

@badge_base "https://img.shields.io/badge/"
@headers [{"User-Agent", "HexDepsChecker (0.0.1) - slogsdon"}]

def index(conn, []) do
conn
|> send_resp(200, "Hello World")
end

def lock(conn, loc: loc, org: org, repo: repo) do
url = case loc do
"github" -> "https://raw.githubusercontent.com/#{org}/#{repo}/master/mix.lock"
"bitbucket" -> "https://bitbucket.org/#{org}/#{repo}/raw/master/mix.lock"
_ -> raise UnknownHostError
end

r = url |> HTTPoison.get!
eval_opts = [requires: [],
macros: [],
aliases: [],
functions: []]
json = r.body
|> Code.eval_string([], eval_opts)
|> elem(0)
|> Enum.map(fn {dep, {:hex, dep, version}} ->
%{} |> Map.put(dep, has_update?(dep, version))
end)
|> Poison.encode!
raw conn |> resp(200, json)
def index(conn, _) do
static conn, "index.html"
end

def image(conn, _args) do
name = get_name(:ok)
conn
|> put_resp_header("Location", @badge_base <> "#{name}.svg")
|> send_resp(302, "Found")
end

def get_name(code) do
status = statuses[code]
msg = status.msg
|> String.replace("_", "__")
|> String.replace("-", "--")
|> String.replace(" ", "_")
["dependencies",
msg,
status.color]
|> Enum.join("-")
end

def has_update?(dep, version) do
latest = HTTPoison.get!("https://hex.pm/api/packages/#{dep}", @headers)
|> Map.get(:body)
|> Poison.decode!
|> Map.get("releases")
|> hd

Version.compare(latest["version"], version) == :gt
end

def get_raw(package) do
HTTPoison.get!("https://hex.pm/api/packages/#{package}", @headers)
|> Map.get(:body)
|> Poison.decode!
|> Map.get("releases")
|> hd
|> Map.get("url")
|> HTTPoison.get!
|> Map.get(:body)
|> Poison.decode!
|> Map.get("requirements")
end

defp statuses do
[
ok: %{color: "green",
msg: "up to date"},
available: %{color: "yellow",
msg: "update(s) available"},
unknown: %{color: "lightgrey",
msg: "unknown"}
]
redirect conn, Badge.url(:ok)
end
end
51 changes: 51 additions & 0 deletions lib/hex_deps_checker/error_handler.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
defmodule HexDepsChecker.ErrorHandler do
@doc false
defmacro __using__(_) do
quote location: :keep do
@before_compile unquote(__MODULE__)

defp handle_errors(conn, assigns) do
Plug.Conn.send_resp(conn, conn.status, "Something went wrong")
end

defoverridable [handle_errors: 2]
end
end

@doc false
defmacro __before_compile__(_env) do
quote location: :keep do
def call(conn, opts) do
try do
super(conn, opts)
catch
kind, reason ->
unquote(__MODULE__).__catch__(conn, kind, reason, System.stacktrace, &handle_errors/2)
end
end
end
end

@already_sent {:plug_conn, :sent}

@doc false
def __catch__(conn, kind, reason, stack, handle_errors) do
receive do
@already_sent ->
send self(), @already_sent
after
0 ->
reason = Exception.normalize(kind, reason, stack)

conn
|> Plug.Conn.put_status(status(kind, reason))
|> handle_errors.(%{kind: kind, reason: reason, stack: stack})
end

:erlang.raise(kind, reason, stack)
end

defp status(:error, error), do: Plug.Exception.status(error)
defp status(:throw, _throw), do: 500
defp status(:exit, _exit), do: 500
end
26 changes: 26 additions & 0 deletions lib/hex_deps_checker/hex.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
defmodule HexDepsChecker.Hex do
@headers [{"User-Agent", "HexDepsChecker (0.0.1) - slogsdon"}]

def has_update?(dep, version) do
latest = HTTPoison.get!("https://hex.pm/api/packages/#{dep}", @headers)
|> Map.get(:body)
|> Poison.decode!
|> Map.get("releases")
|> hd

Version.compare(latest["version"], version) == :gt
end

def get_raw(package) do
HTTPoison.get!("https://hex.pm/api/packages/#{package}", @headers)
|> Map.get(:body)
|> Poison.decode!
|> Map.get("releases")
|> hd
|> Map.get("url")
|> HTTPoison.get!
|> Map.get(:body)
|> Poison.decode!
|> Map.get("requirements")
end
end
21 changes: 9 additions & 12 deletions lib/hex_deps_checker/router.ex
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
defmodule HexDepsChecker.Router do
use Sugar.Router
plug Sugar.Plugs.HotCodeReload
use HexDepsChecker.ErrorHandler
alias HexDepsChecker.Controllers.Main
alias HexDepsChecker.Controllers.Api

if Sugar.Config.get(:sugar, :show_debugger, false) do
plug Plug.Debugger, otp_app: :hex_deps_checker
end
plug Plug.Static, at: "/", from: :hex_deps_checker

plug Plug.Static, at: "/static", from: :hex_deps_checker
# Main routes
get "/", Main, :index
get "/image", Main, :image

# Uncomment the following line for session store
# plug Plug.Session, store: :ets, key: "sid", secure: true, table: :session

# Define your routes here
get "/", HexDepsChecker.Controllers.Main, :index
get "/image", HexDepsChecker.Controller.Main, :image
get "/:loc/:org/:repo", HexDepsChecker.Controllers.Main, :lock
# Api routes
get "/api/:loc/:org/:repo", Api, :lock
end
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!doctype html>
<html lang="en-US">
<head>
<title>main/index - HexDepsChecker</title>
<title>HexDepsChecker</title>
</head>
<body>
Hello World
Expand Down

0 comments on commit 0517ee4

Please sign in to comment.