diff options
| author | Laszlo Toth <Laszlo.Toth@otpbank.hu> | 2018-04-11 17:03:34 +0200 | 
|---|---|---|
| committer | Laszlo Toth <Laszlo.Toth@otpbank.hu> | 2018-04-11 17:03:34 +0200 | 
| commit | 97c48e86bb7ca8969fd19c999f55259e88d4a6db (patch) | |
| tree | 6244d5991de8a5c6a041eb131ea4e0b4fb71973d | |
| parent | a03da56fb39bddcf6b5ef75cb5b5e40b5b5ab1d9 (diff) | |
(#1743): Add specs for dialyzer
| -rw-r--r-- | src/rebar_pkg_resource.erl | 121 | 
1 files changed, 118 insertions, 3 deletions
| diff --git a/src/rebar_pkg_resource.erl b/src/rebar_pkg_resource.erl index f77a81a..8806c8b 100644 --- a/src/rebar_pkg_resource.erl +++ b/src/rebar_pkg_resource.erl @@ -19,9 +19,26 @@  -include("rebar.hrl").  -include_lib("public_key/include/OTP-PUB-KEY.hrl"). +-type cached_result()   :: {'bad_checksum',string()} | +                           {'bad_registry_checksum',string()} | +                           {'failed_extract',string()} | +                           {'ok','true'} | +                           {'unexpected_hash',string(),_,binary()}. + +-type download_result() :: {bad_download, binary() | string()} | +                           {fetch_fail, _, _} | cached_result(). + +-spec lock(AppDir, Source) -> Res when +      AppDir :: file:name(), +      Source :: tuple(), +      Res :: {atom(), string(), any()}.  lock(_AppDir, Source) ->      Source. +-spec needs_update(Dir, Pkg) -> Res when +      Dir :: file:name(), +      Pkg :: {pkg, Name :: binary(), Vsn :: binary(), Hash :: binary()}, +      Res :: boolean().  needs_update(Dir, {pkg, _Name, Vsn, _Hash}) ->      [AppInfo] = rebar_app_discover:find_apps([Dir], all),      case rebar_app_info:original_vsn(AppInfo) =:= rebar_utils:to_list(Vsn) of @@ -31,9 +48,20 @@ needs_update(Dir, {pkg, _Name, Vsn, _Hash}) ->              true      end. +-spec download(TmpDir, Pkg, State) -> Res when +      TmpDir :: file:name(), +      Pkg :: {pkg, Name :: binary(), Vsn :: binary(), Hash :: binary()}, +      State :: rebar_state:t(), +      Res :: {'error',_} | {'ok',_} | {'tarball',binary() | string()}.  download(TmpDir, Pkg, State) ->      download(TmpDir, Pkg, State, true). +-spec download(TmpDir, Pkg, State, UpdateETag) -> Res when +      TmpDir :: file:name(), +      Pkg :: {pkg, Name :: binary(), Vsn :: binary(), Hash :: binary()}, +      State :: rebar_state:t(), +      UpdateETag :: boolean(), +      Res :: download_result().  download(TmpDir, Pkg={pkg, Name, Vsn, _Hash}, State, UpdateETag) ->      CDN = rebar_state:get(State, rebar_packages_cdn, ?DEFAULT_CDN),      {ok, PackageDir} = rebar_packages:package_dir(State), @@ -48,6 +76,16 @@ download(TmpDir, Pkg={pkg, Name, Vsn, _Hash}, State, UpdateETag) ->              {fetch_fail, Name, Vsn}      end. +-spec cached_download(TmpDir, CachePath, Pkg, Url, ETag, State, ETagPath, UpdateETag) -> Res when +      TmpDir :: file:name(), +      CachePath :: file:name(), +      Pkg :: {pkg, Name :: binary(), Vsn :: binary(), Hash :: binary()}, +      Url :: string(), +      ETag :: false | string(), +      State :: rebar_state:t(), +      ETagPath :: file:name(), +      UpdateETag :: boolean(), +      Res :: download_result().  cached_download(TmpDir, CachePath, Pkg={pkg, Name, Vsn, _Hash}, Url, ETag, State, ETagPath, UpdateETag) ->      case request(Url, ETag) of          {ok, cached} -> @@ -65,6 +103,12 @@ cached_download(TmpDir, CachePath, Pkg={pkg, Name, Vsn, _Hash}, Url, ETag, State              {fetch_fail, Name, Vsn}      end. +-spec serve_from_cache(TmpDir, CachePath, Pkg, State) -> Res when +      TmpDir :: file:name(), +      CachePath :: file:name(), +      Pkg :: {pkg, Name :: binary(), Vsn :: binary(), Hash :: binary()}, +      State :: rebar_state:t(), +      Res :: cached_result().  serve_from_cache(TmpDir, CachePath, Pkg, State) ->      {Files, Contents, Version, Meta} = extract(TmpDir, CachePath),      case checksums(Pkg, Files, Contents, Version, Meta, State) of @@ -85,6 +129,15 @@ serve_from_cache(TmpDir, CachePath, Pkg, State) ->              {bad_checksum, CachePath}      end. +-spec serve_from_download(TmpDir, CachePath, Package, ETag, Binary, State, ETagPath) -> Res when +      TmpDir :: file:name(), +      CachePath :: file:name(), +      Package :: {pkg, Name :: binary(), Vsn :: binary(), Hash :: binary()}, +      ETag :: string(), +      Binary :: binary(), +      State :: rebar_state:t(), +      ETagPath :: file:name(), +      Res :: download_result().  serve_from_download(TmpDir, CachePath, Package, ETag, Binary, State, ETagPath) ->      ?DEBUG("Writing ~p to cache at ~ts", [Package, CachePath]),      file:write_file(CachePath, Binary), @@ -96,6 +149,14 @@ serve_from_download(TmpDir, CachePath, Package, ETag, Binary, State, ETagPath) -              {bad_download, CachePath}      end. +-spec extract(TmpDir, CachePath) -> Res when +      TmpDir :: file:name(), +      CachePath :: file:name(), +      Res :: {Files, Contents, Version, Meta}, +      Files :: list({file:name(), binary()}), +      Contents :: binary(), +      Version :: binary(), +      Meta :: binary().  extract(TmpDir, CachePath) ->      ec_file:mkdir_p(TmpDir),      {ok, Files} = erl_tar:extract(CachePath, [memory]), @@ -104,6 +165,18 @@ extract(TmpDir, CachePath) ->      {"metadata.config", Meta} = lists:keyfind("metadata.config", 1, Files),      {Files, Contents, Version, Meta}. +-spec checksums(Pkg, Files, Contents, Version, Meta, State) -> Res when +      Pkg :: {pkg, Name :: binary(), Vsn :: binary(), Hash :: binary()}, +      Files :: list({file:name(), binary()}), +      Contents :: binary(), +      Version :: binary(), +      Meta :: binary(), +      State :: rebar_state:t(), +      Res :: {Hash, BinChecksum, RegistryChecksum, TarChecksum}, +      Hash :: binary(), +      BinChecksum :: binary(), +      RegistryChecksum :: any(), +      TarChecksum :: binary().  checksums(Pkg={pkg, _Name, _Vsn, Hash}, Files, Contents, Version, Meta, State) ->      Blob = <<Version/binary, Meta/binary, Contents/binary>>,      <<X:256/big-unsigned>> = crypto:hash(sha256, Blob), @@ -112,12 +185,18 @@ checksums(Pkg={pkg, _Name, _Vsn, Hash}, Files, Contents, Version, Meta, State) -      {"CHECKSUM", TarChecksum} = lists:keyfind("CHECKSUM", 1, Files),      {Hash, BinChecksum, RegistryChecksum, TarChecksum}. +-spec make_vsn(Vsn) -> Res when +      Vsn :: any(), +      Res :: {'error',[1..255,...]}.  make_vsn(_) ->      {error, "Replacing version of type pkg not supported."}. +-spec request(Url, ETag) -> Res when +      Url :: string(), +      ETag :: false | string(), +      Res :: 'error' | {ok, cached} | {ok, any(), string()}.  request(Url, ETag) ->      HttpOptions = [{ssl, ssl_opts(Url)}, {relaxed, true} | rebar_utils:get_proxy_auth()], -      case httpc:request(get, {Url, [{"if-none-match", "\"" ++ ETag ++ "\""} || ETag =/= false]++                               [{"User-Agent", rebar_utils:user_agent()}]},                         HttpOptions, @@ -138,6 +217,9 @@ request(Url, ETag) ->              error      end. +-spec etag(Path) -> Res when +      Path :: file:name(), +      Res :: false | string().  etag(Path) ->      case file:read_file(Path) of          {ok, Bin} -> @@ -148,7 +230,9 @@ etag(Path) ->  %% @doc returns the SSL options adequate for the project based on  %% its configuration, including for validation of certs. --spec ssl_opts(string()) -> [term()]. +-spec ssl_opts(Url) -> Res when +      Url :: string(), +      Res :: proplists:proplist().  ssl_opts(Url) ->      case get_ssl_config() of          ssl_verify_enabled -> @@ -159,7 +243,10 @@ ssl_opts(Url) ->  %% @doc returns the SSL options adequate for the project based on  %% its configuration, including for validation of certs. --spec ssl_opts(atom(), string()) -> [term()]. +-spec ssl_opts(Enabled, Url) -> Res when +      Enabled :: atom(), +      Url :: string(), +      Res :: proplists:proplist().  ssl_opts(ssl_verify_enabled, Url) ->      case check_ssl_version() of          true -> @@ -173,6 +260,9 @@ ssl_opts(ssl_verify_enabled, Url) ->              [{verify, verify_none}]      end. +-spec partial_chain(Certs) -> Res when +      Certs :: list(any()), +      Res :: unknown_ca | {trusted_ca, any()}.  partial_chain(Certs) ->      Certs1 = [{Cert, public_key:pkix_decode_cert(Cert, otp)} || Cert <- Certs],      CACerts = certifi:cacerts(), @@ -187,14 +277,23 @@ partial_chain(Certs) ->              unknown_ca      end. +-spec extract_public_key_info(Cert) -> Res when +      Cert :: #'OTPCertificate'{tbsCertificate::#'OTPTBSCertificate'{}}, +      Res :: any().  extract_public_key_info(Cert) ->      ((Cert#'OTPCertificate'.tbsCertificate)#'OTPTBSCertificate'.subjectPublicKeyInfo). +-spec check_cert(CACerts, Cert) -> Res when +      CACerts :: list(any()), +      Cert :: any(), +      Res :: boolean().  check_cert(CACerts, Cert) ->      lists:any(fun(CACert) ->                        extract_public_key_info(CACert) == extract_public_key_info(Cert)                end, CACerts). +-spec check_ssl_version() -> +      boolean().  check_ssl_version() ->      case application:get_key(ssl, vsn) of          {ok, Vsn} -> @@ -203,6 +302,8 @@ check_ssl_version() ->              false      end. +-spec get_ssl_config() -> +      ssl_verify_disabled | ssl_verify_enabled.  get_ssl_config() ->      GlobalConfigFile = rebar_dir:global_config(),      Config = rebar_config:consult_file(GlobalConfigFile), @@ -213,9 +314,14 @@ get_ssl_config() ->              ssl_verify_enabled      end. +-spec parse_vsn(Vsn) -> Res when +      Vsn :: string(), +      Res :: {integer(), integer(), integer()}.  parse_vsn(Vsn) ->      version_pad(rebar_string:lexemes(Vsn, ".-")). +-spec version_pad(list(nonempty_string())) -> Res when +      Res :: {integer(), integer(), integer()}.  version_pad([Major]) ->      {list_to_integer(Major), 0, 0};  version_pad([Major, Minor]) -> @@ -225,10 +331,19 @@ version_pad([Major, Minor, Patch]) ->  version_pad([Major, Minor, Patch | _]) ->      {list_to_integer(Major), list_to_integer(Minor), list_to_integer(Patch)}. +-spec maybe_store_etag_in_cache(UpdateETag, Path, ETag) -> Res when +      UpdateETag :: boolean(), +      Path :: file:name(), +      ETag :: string(), +      Res :: ok.  maybe_store_etag_in_cache(false = _UpdateETag, _Path, _ETag) ->      ok;  maybe_store_etag_in_cache(true = _UpdateETag, Path, ETag) ->      store_etag_in_cache(Path, ETag). +-spec store_etag_in_cache(File, ETag) -> Res when +      File :: file:name(), +      ETag :: string(), +      Res :: ok.  store_etag_in_cache(Path, ETag) ->      ok = file:write_file(Path, ETag). | 
