diff --git a/.formatter.exs b/.formatter.exs index 525446d..d2cda26 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,4 +1,4 @@ # Used by "mix format" [ - inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}"] + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] ] diff --git a/.gitignore b/.gitignore index 008b35d..5767825 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,26 @@ -/_build -/cover -/deps -/doc +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). *.ez + +# Ignore package tarball (built via "mix hex.build"). +fuzzyurl-*.tar + +# Temporary files, for example, from tests. +/tmp/ diff --git a/LICENSE.txt b/LICENSE.md similarity index 98% rename from LICENSE.txt rename to LICENSE.md index 9cb29fa..279ff21 100644 --- a/LICENSE.txt +++ b/LICENSE.md @@ -1,3 +1,5 @@ +# The MIT License + Copyright (c) 2015 Pete Gamache. Permission is hereby granted, free of charge, to any person obtaining a @@ -18,4 +20,3 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/README.md b/README.md index 5c43f33..26737b7 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,16 @@ # Fuzzyurl -Non-strict parsing, manipulation, and fuzzy matching of URLs in Elixir. - [![Build Status](https://travis-ci.org/gamache/fuzzyurl.ex.svg?branch=master)](https://travis-ci.org/gamache/fuzzyurl.ex) -[![Hex.pm Version](http://img.shields.io/hexpm/v/fuzzyurl.svg?style=flat)](https://hex.pm/packages/fuzzyurl) [![Coverage Status](https://coveralls.io/repos/gamache/fuzzyurl.ex/badge.svg?branch=master&service=github)](https://coveralls.io/github/gamache/fuzzyurl.ex?branch=master) +[![Module Version](https://img.shields.io/hexpm/v/fuzzyurl.svg)](https://hex.pm/packages/fuzzyurl) +[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/fuzzyurl/) +[![Total Download](https://img.shields.io/hexpm/dt/fuzzyurl.svg)](https://hex.pm/packages/fuzzyurl) +[![License](https://img.shields.io/hexpm/l/fuzzyurl.svg)](https://github.com/gamache/fuzzyurl/blob/master/LICENSE.md) +[![Last Updated](https://img.shields.io/github/last-commit/gamache/fuzzyurl.svg)](https://github.com/gamache/fuzzyurl/commits/master) +Non-strict parsing, manipulation, and fuzzy matching of URLs in Elixir. -[The full documentation for Fuzzyurl is -here.](http://hexdocs.pm/fuzzyurl/Fuzzyurl.html) +[The full documentation for Fuzzyurl is here.](http://hexdocs.pm/fuzzyurl/Fuzzyurl.html) ## Adding Fuzzyurl to Your Project @@ -18,7 +20,9 @@ add it as a dependency: ```elixir defp deps do - [{:fuzzyurl, "~> 0.9.0"}] + [ + {:fuzzyurl, "~> 0.9.0"} + ] end ``` @@ -41,22 +45,26 @@ wildcard if you wish to use the Fuzzyurl as a URL mask. ## Parsing URLs - iex> f = Fuzzyurl.from_string("https://api.example.com/users/123?full=true") - %Fuzzyurl{fragment: nil, hostname: "api.example.com", password: nil, path: "/users/123", port: nil, protocol: "https", query: "full=true", username: nil} - iex> f.protocol - "https" - iex> f.hostname - "api.example.com" - iex> f.query - "full=true" +```elixir +iex> f = Fuzzyurl.from_string("https://api.example.com/users/123?full=true") +%Fuzzyurl{fragment: nil, hostname: "api.example.com", password: nil, path: "/users/123", port: nil, protocol: "https", query: "full=true", username: nil} +iex> f.protocol +"https" +iex> f.hostname +"api.example.com" +iex> f.query +"full=true" +``` ## Constructing URLs - iex> f = Fuzzyurl.new(hostname: "example.com", protocol: "http", port: "8080") - %Fuzzyurl{fragment: nil, hostname: "example.com", password: nil, path: nil, port: "8080", protocol: "http", query: nil, username: nil} - iex> Fuzzyurl.to_string(f) - "http://example.com:8080" +```elixir +iex> f = Fuzzyurl.new(hostname: "example.com", protocol: "http", port: "8080") +%Fuzzyurl{fragment: nil, hostname: "example.com", password: nil, path: nil, port: "8080", protocol: "http", query: nil, username: nil} +iex> Fuzzyurl.to_string(f) +"http://example.com:8080" +``` ## Matching URLs @@ -80,37 +88,44 @@ addition to the naive wildcard `*`: The `Fuzzyurl.mask/0` and `Fuzzyurl.mask/1` functions aid in the creation of URL masks. - iex> m = Fuzzyurl.mask - %Fuzzyurl{fragment: "*", hostname: "*", password: "*", path: "*", port: "*", protocol: "*", query: "*", username: "*"} - iex> Fuzzyurl.matches?(m, "http://example.com/a/b/c") - true - - iex> m2 = Fuzzyurl.mask(path: "/a/b/**") - %Fuzzyurl{fragment: "*", hostname: "*", password: "*", path: "/a/b/**", port: "*", protocol: "*", query: "*", username: "*"} - iex> Fuzzyurl.matches?(m2, "https://example.com/a/b/") - true - iex> Fuzzyurl.matches?(m2, "git+ssh://jen@example.com/a/b") - true - iex> Fuzzyurl.matches?(m2, "https://example.com/a/bar") - false +```elixir +iex> m = Fuzzyurl.mask +%Fuzzyurl{fragment: "*", hostname: "*", password: "*", path: "*", port: "*", protocol: "*", query: "*", username: "*"} +iex> Fuzzyurl.matches?(m, "http://example.com/a/b/c") +true + +iex> m2 = Fuzzyurl.mask(path: "/a/b/**") +%Fuzzyurl{fragment: "*", hostname: "*", password: "*", path: "/a/b/**", port: "*", protocol: "*", query: "*", username: "*"} +iex> Fuzzyurl.matches?(m2, "https://example.com/a/b/") +true +iex> Fuzzyurl.matches?(m2, "git+ssh://jen@example.com/a/b") +true +iex> Fuzzyurl.matches?(m2, "https://example.com/a/bar") +false +``` `Fuzzyurl.best_match`, given a list of URL masks and a URL, will return the mask which most closely matches the URL: - iex> masks = ["/foo/*", "/foo/bar", Fuzzyurl.mask] - iex> Fuzzyurl.best_match(masks, "http://example.com/foo/bar") - "/foo/bar" +```elixir +iex> masks = ["/foo/*", "/foo/bar", Fuzzyurl.mask] +iex> Fuzzyurl.best_match(masks, "http://example.com/foo/bar") +"/foo/bar" +``` If you'd prefer the list index of the best-matching URL mask, use `Fuzzyurl.best_match_index` instead: - iex> masks = ["/foo/*", "/foo/bar", Fuzzyurl.mask] - iex> Fuzzyurl.best_match_index(masks, "http://example.com/foo/bar") - 1 +```elixir +iex> masks = ["/foo/*", "/foo/bar", Fuzzyurl.mask] +iex> Fuzzyurl.best_match_index(masks, "http://example.com/foo/bar") +1 +``` -## Authorship and License -Fuzzyurl is copyright 2014-2016, Pete Gamache. +## Copyright and License -Fuzzyurl is released under the MIT License, available at LICENSE.txt. +Copyright (c) 2014 Pete Gamache +This work is free. You can redistribute it and/or modify it under the +terms of the MIT License. See the [LICENSE.md](./LICENSE.md) file for more details. diff --git a/lib/fuzzyurl/match.ex b/lib/fuzzyurl/match.ex index 0fea145..08539b9 100644 --- a/lib/fuzzyurl/match.ex +++ b/lib/fuzzyurl/match.ex @@ -92,7 +92,7 @@ defmodule Fuzzyurl.Match do best matches `url`. Returns nil if none of `masks` match. iex> masks = [Fuzzyurl.mask(path: "/foo/*"), Fuzzyurl.mask(path: "/foo/bar"), Fuzzyurl.mask] - iex> Fuzzyurl.Match.best_match_index(masks, Fuzzyurl.from_string("http://exmaple.com/foo/bar")) + iex> Fuzzyurl.Match.best_match_index(masks, Fuzzyurl.from_string("http://example.com/foo/bar")) 1 """ def best_match_index(masks, url) do diff --git a/mix.exs b/mix.exs index 0664ff3..8ebde51 100644 --- a/mix.exs +++ b/mix.exs @@ -1,25 +1,26 @@ defmodule Fuzzyurl.Mixfile do use Mix.Project + @source_url "https://github.com/gamache/fuzzyurl.ex" + @version "1.0.1" + def project do [ app: :fuzzyurl, - description: ~S""" - Fuzzyurl is a library for non-strict parsing, construction, and - fuzzy-matching of URLs. - """, - package: [ - maintainers: ["pete gamache"], - licenses: ["Apache 2.0"], - links: %{"GitHub" => "https://github.com/gamache/fuzzyurl.ex"} - ], - version: "1.0.1", + version: @version, elixir: "~> 1.0", build_embedded: Mix.env() == :prod, start_permanent: Mix.env() == :prod, + deps: deps(), + docs: docs(), + package: package(), test_coverage: [tool: ExCoveralls], - preferred_cli_env: [coveralls: :test, "coveralls.detail": :test, "coveralls.post": :test], - deps: deps() + preferred_cli_env: [ + coveralls: :test, + "coveralls.detail": :test, + "coveralls.post": :test, + docs: :docs + ] ] end @@ -29,11 +30,36 @@ defmodule Fuzzyurl.Mixfile do defp deps do [ - {:ex_doc, "~> 0.18", only: :dev}, + {:ex_doc, ">= 0.0.0", only: :docs, runtime: false}, {:ex_spec, "~> 2.0", only: :test}, {:jason, "~> 1.0", only: :test}, {:excoveralls, "~> 0.8", only: :test}, {:dialyxir, "~> 0.5", only: :dev, runtime: false} ] end + + defp docs do + [ + extras: [ + "LICENSE.md": [title: "License"], + "README.md": [title: "Overview"] + ], + main: "readme", + source_url: @source_url, + source_ref: @version, + formatters: ["html"] + ] + end + + defp package do + [ + description: ~S""" + Fuzzyurl is a library for non-strict parsing, construction, and + fuzzy-matching of URLs. + """, + maintainers: ["Pete Gamache"], + licenses: ["Apache-2.0"], + links: %{"GitHub" => @source_url} + ] + end end diff --git a/mix.lock b/mix.lock index 59e2c0c..a3930e7 100644 --- a/mix.lock +++ b/mix.lock @@ -1,21 +1,26 @@ %{ - "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm"}, + "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm", "fdc6066ceeccb3aa14049ab6edf0b9af3b64ae1b0db2a92d5c52146f373bbb1c"}, "coverex": {:hex, :coverex, "1.4.7"}, - "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"}, - "earmark": {:hex, :earmark, "1.2.4", "99b637c62a4d65a20a9fb674b8cffb8baa771c04605a80c911c4418c69b75439", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.18.3", "f4b0e4a2ec6f333dccf761838a4b253d75e11f714b85ae271c9ae361367897b7", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, - "ex_spec": {:hex, :ex_spec, "2.0.1", "8bdbd6fa85995fbf836ed799571d44be6f9ebbcace075209fd0ad06372c111cf", [:mix], [], "hexpm"}, - "excoveralls": {:hex, :excoveralls, "0.8.1", "0bbf67f22c7dbf7503981d21a5eef5db8bbc3cb86e70d3798e8c802c74fa5e27", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, - "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, - "hackney": {:hex, :hackney, "1.11.0", "4951ee019df102492dabba66a09e305f61919a8a183a7860236c0fde586134b6", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm", "6c32a70ed5d452c6650916555b1f96c79af5fc4bf286997f8b15f213de786f73"}, + "earmark": {:hex, :earmark, "1.2.4", "99b637c62a4d65a20a9fb674b8cffb8baa771c04605a80c911c4418c69b75439", [:mix], [], "hexpm", "1b34655872366414f69dd987cb121c049f76984b6ac69f52fff6d8fd64d29cfd"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.17", "6f3c7e94170377ba45241d394389e800fb15adc5de51d0a3cd52ae766aafd63f", [:mix], [], "hexpm", "f93ac89c9feca61c165b264b5837bf82344d13bebc634cd575cb711e2e342023"}, + "ex_doc": {:hex, :ex_doc, "0.26.0", "1922164bac0b18b02f84d6f69cab1b93bc3e870e2ad18d5dacb50a9e06b542a3", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2775d66e494a9a48355db7867478ffd997864c61c65a47d31c4949459281c78d"}, + "ex_spec": {:hex, :ex_spec, "2.0.1", "8bdbd6fa85995fbf836ed799571d44be6f9ebbcace075209fd0ad06372c111cf", [:mix], [], "hexpm", "b44fe5054497411a58341ece5bf7756c219d9d6c1303b5ac467f557a0a4c31ac"}, + "excoveralls": {:hex, :excoveralls, "0.8.1", "0bbf67f22c7dbf7503981d21a5eef5db8bbc3cb86e70d3798e8c802c74fa5e27", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "5292c8501901f7a3d0eaf6599cabacaa4ddbf61cc1f1e5fe7200d6e07ee1d33d"}, + "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"}, + "hackney": {:hex, :hackney, "1.11.0", "4951ee019df102492dabba66a09e305f61919a8a183a7860236c0fde586134b6", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "bb3cc62ecc10145f8f0965c05083a5278eae7ef1853d340cc9a7a3e27609b9bd"}, "httpoison": {:hex, :httpoison, "0.8.0"}, - "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, - "jason": {:hex, :jason, "1.0.0", "0f7cfa9bdb23fed721ec05419bcee2b2c21a77e926bce0deda029b5adc716fe2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, - "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, + "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fc1a2f7340c422650504b1662f28fdf381f34cbd30664e8491744e52c9511d40"}, + "jason": {:hex, :jason, "1.0.0", "0f7cfa9bdb23fed721ec05419bcee2b2c21a77e926bce0deda029b5adc716fe2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b96c400e04b7b765c0854c05a4966323e90c0d11fee0483b1567cda079abb205"}, + "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm", "fc3499fed7a726995aa659143a248534adc754ebd16ccd437cd93b649a95091f"}, + "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.15.2", "dc72dfe17eb240552857465cc00cce390960d9a0c055c4ccd38b70629227e97c", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "fd23ae48d09b32eff49d4ced2b43c9f086d402ee4fd4fcb2d7fad97fa8823e75"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm", "7a4c8e1115a2732a67d7624e28cf6c9f30c66711a9e92928e745c255887ba465"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.2.0", "b44d75e2a6542dcb6acf5d71c32c74ca88960421b6874777f79153bbbbd7dccc", [:mix], [], "hexpm", "52b2871a7515a5ac49b00f214e4165a40724cf99798d8e4a65e4fd64ebd002c1"}, "poison": {:hex, :poison, "1.5.0", "f2f4f460623a6f154683abae34352525e1d918380267cdbd949a07ba57503248", [:mix], []}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm", "4f8805eb5c8a939cf2359367cb651a3180b27dfb48444846be2613d79355d65e"}, "ssl_verify_hostname": {:hex, :ssl_verify_hostname, "1.0.5", "2e73e068cd6393526f9fa6d399353d7c9477d6886ba005f323b592d389fb47be", [:make], []}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm", "da1d9bef8a092cc7e1e51f1298037a5ddfb0f657fe862dfe7ba4c5807b551c29"}, }