diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..d0a6e1b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,60 @@ +# How to Contribute + +## Adding a New API Function + +1. Figure out what you want to do + - Go to https://hexdocs.pm/hex/Mix.Tasks.Hex.html and find what you want to do +2. Once you find the page, click on the code icon on the top-right to go to the corresponding source code like so: https://github.com/hexpm/hex/blob/main/lib/mix/tasks/hex.owner.ex#L125 +```elixir + defp transfer_owner(organization, package, owner) do + auth = Mix.Tasks.Hex.auth_info(:write) + Hex.Shell.info("Transferring ownership to #{owner} for #{package}") + + case Hex.API.Package.Owner.add(organization, package, owner, "full", true, auth) do + {:ok, {code, _body, _headers}} when code in 200..299 -> + :ok + + other -> + Hex.Shell.error("Transferring ownership failed") + Hex.Utils.print_error_result(other) + end + end +``` + +3. The API function this is calling is `Hex.API.Package.Owner.add` so we go to https://github.com/hexpm/hex/blob/main/lib/hex/api/package.ex, scroll down to the defmodule for Owner and then find the `add` function: +```elixir + def add(repo, package, owner, level, transfer, auth) when package != "" do + Hex.API.check_write_api() + + owner = URI.encode_www_form(owner) + path = "packages/#{URI.encode(package)}/owners/#{URI.encode(owner)}" + params = %{level: level, transfer: transfer} + API.erlang_put_request(repo, path, params, auth) + end +``` +`path` tells us what path and variables we will be using while `params` tells us what the body of the request should contain. The `API.erlang_put_request` at the bottom of this tells us the method of our request needs to be `PUT`. Now we have all of the information we need to create our request function like so: +```elixir +pub fn transfer_owner_request( + package_name: &str, + owner: &str, + api_key: &str, + config: &Config, +) -> http::Request> { + let body = json!({ + "level": OwnerLevel::Full.to_string(), + "transfer": true, + }); + + config + .api_request( + Method::PUT, + &format!("packages/{}/owners/{}", package_name, owner), + Some(api_key), + ) + .body(body.to_string().into_bytes()) + .expect("transfer_owner_request request") +} +``` +Note that the `api_key` and `config` fields will always be present in these request functions while the other fields are tailored to the specific request we want to make. + +4. TODO: How to figure out what to write for the response function? \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 2f54431..8eb130b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,6 +88,12 @@ fn make_request( } /// Create a request that creates a Hex API key. +/// +/// API Docs: +/// +/// https://github.com/hexpm/hex/blob/main/lib/mix/tasks/hex.ex#L137 +/// +/// https://github.com/hexpm/hex/blob/main/lib/hex/api/key.ex#L6 pub fn create_api_key_request( username: &str, password: &str, @@ -125,6 +131,12 @@ pub fn create_api_key_response(response: http::Response>) -> Result>) -> Result<(), } /// Retire an existing package release from Hex. +/// +/// API Docs: +/// +/// https://github.com/hexpm/hex/blob/main/lib/mix/tasks/hex.retire.ex#L75 +/// +/// https://github.com/hexpm/hex/blob/main/lib/hex/api/release.ex#L28 pub fn retire_release_request( package: &str, version: &str, @@ -171,7 +189,7 @@ pub fn retire_release_request( Some(api_key), ) .body(body.to_string().into_bytes()) - .expect("require_release_request request") + .expect("retire_release_request request") } /// Parses a request that retired a release. @@ -186,6 +204,12 @@ pub fn retire_release_response(response: http::Response>) -> Result<(), } /// Un-retire an existing retired package release from Hex. +/// +/// API Docs: +/// +/// https://github.com/hexpm/hex/blob/main/lib/mix/tasks/hex.retire.ex#L89 +/// +/// https://github.com/hexpm/hex/blob/main/lib/hex/api/release.ex#L35 pub fn unretire_release_request( package: &str, version: &str, @@ -199,7 +223,7 @@ pub fn unretire_release_request( Some(api_key), ) .body(vec![]) - .expect("require_release_request request") + .expect("unretire_release_request request") } /// Parses a request that un-retired a package version. @@ -215,7 +239,7 @@ pub fn unretire_release_response(response: http::Response>) -> Result<() /// Create a request that get the names and versions of all of the packages on /// the package registry. -/// +/// TODO: Where are the API docs for this? pub fn get_repository_versions_request( api_key: Option<&str>, config: &Config, @@ -224,7 +248,7 @@ pub fn get_repository_versions_request( .repository_request(Method::GET, "versions", api_key) .header("accept", "application/json") .body(vec![]) - .expect("create_api_key_request request") + .expect("get_repository_versions_request request") } /// Parse a request that get the names and versions of all of the packages on @@ -269,6 +293,11 @@ pub fn get_repository_versions_response( /// Create a request to get the information for a package in the repository. /// +/// API Docs: +/// +/// https://github.com/hexpm/hex/blob/main/lib/mix/tasks/hex.package.ex#L348 +/// +/// https://github.com/hexpm/hex/blob/main/lib/hex/api/package.ex#L36 pub fn get_package_request( name: &str, api_key: Option<&str>, @@ -321,7 +350,7 @@ pub fn get_package_response( } /// Create a request to download a version of a package as a tarball -/// +/// TODO: Where are the API docs for this? pub fn get_package_tarball_request( name: &str, version: &str, @@ -358,6 +387,11 @@ pub fn get_package_tarball_response( Ok(body) } +/// API Docs: +/// +/// https://github.com/hexpm/hex/blob/main/lib/mix/tasks/hex.publish.ex#L384 +/// +/// https://github.com/hexpm/hex/blob/main/lib/hex/api/release_docs.ex#L19 pub fn remove_docs_request( package_name: &str, version: &str, @@ -373,7 +407,7 @@ pub fn remove_docs_request( Some(api_key), ) .body(vec![]) - .expect("get_package_tarball_request request")) + .expect("remove_docs_request request")) } pub fn remove_docs_response(response: http::Response>) -> Result<(), ApiError> { @@ -388,6 +422,11 @@ pub fn remove_docs_response(response: http::Response>) -> Result<(), Api } } +/// API Docs: +/// +/// https://github.com/hexpm/hex/blob/main/lib/mix/tasks/hex.publish.ex#L429 +/// +/// https://github.com/hexpm/hex/blob/main/lib/hex/api/release_docs.ex#L11 pub fn publish_docs_request( package_name: &str, version: &str, @@ -421,6 +460,11 @@ pub fn publish_docs_response(response: http::Response>) -> Result<(), Ap } } +/// API Docs: +/// +/// https://github.com/hexpm/hex/blob/main/lib/mix/tasks/hex.publish.ex#L512 +/// +/// https://github.com/hexpm/hex/blob/main/lib/hex/api/release.ex#L13 pub fn publish_package_request( release_tarball: Vec, api_key: &str, @@ -459,6 +503,11 @@ pub fn publish_package_response(response: http::Response>) -> Result<(), } } +/// API Docs: +/// +/// https://github.com/hexpm/hex/blob/main/lib/mix/tasks/hex.publish.ex#L371 +/// +/// https://github.com/hexpm/hex/blob/main/lib/hex/api/release.ex#L21 pub fn revert_release_request( package_name: &str, version: &str,