From 1a2e3a28a7b1bb730554125c96c2ced2fbf0799e Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Fri, 28 May 2021 16:35:21 -0500 Subject: [PATCH] chore: adds contributing.md to xtask prep --- CONTRIBUTING.md | 46 ++++++-- crates/xtask/src/commands/prep/docs.rs | 146 ++++++++++++++++--------- crates/xtask/src/commands/prep/mod.rs | 13 ++- docs/source/contributing.md | 97 +++++++++++++++- 4 files changed, 234 insertions(+), 68 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 373931a6b..b2a6ad95d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to rover +# Contributing to Rover > Rover is a project by [Apollo GraphQL] and is not currently ready for > external feature contributors, though some documentation contributions may be @@ -12,27 +12,55 @@ Rust installed. To install Rust, visit [https://www.rust-lang.org/tools/install] Rust has a build tool and package manager called [`cargo`] that you'll use to interact with Rover's code. +## Workflows + To build the CLI: ```bash cargo build ``` -To run the CLI: +To build and run the CLI with a set of arguments: ```bash cargo run -- -# e.g. 'cargo run -- help' will run the rover help command ``` -You can also install Rover to your local PATH from source with cargo by first -cloning this repository, and then building the CLI: +e.g. To build and run `rover supergraph compose`: + ```bash -cargo build +cargo run -- supergraph compose --config config.yaml ``` -And then running cargo with `install` argument: +You can also install Rover to your local PATH from source with cargo by first +cloning this repository, and then running: ```bash cargo run -- install ``` + +To run tests: +```bash +cargo test --workspace +``` + +To format your code: +```bash +cargo fmt --all +``` + +To lint your code: +```bash +cargo clippy +``` + +To run the lint checker that is run in CI: +```bash +cargo xtask lint +``` + +To run the tests that are run in CI: +```bash +cargo xtask test +``` + [Apollo GraphQL]: https://www.apollographql.com [Rust]: https://www.rust-lang.org/ [`cargo`]: https://doc.rust-lang.org/cargo/index.html @@ -73,9 +101,7 @@ npm start This will start up a development server with live reload enabled. You can see the docs by opening [localhost:8000](http://localhost:8000) in your browser. -To see how the sidebar is built and how pages are grouped and named, see [this section](https://github.com/apollographql/gatsby-theme-apollo/tree/master/packages/gatsby-theme-apollo-docs#sidebarcategories) of the gatsby-theme-apollo-docs docs. There is also a [creating pages section](https://github.com/apollographql/gatsby-theme-apollo/tree/master/packages/gatsby-theme-apollo-docs#creating-pages) if you're interesed in adding new pages. -======= -For info on how to contribute to Rover, see the [docs](https://go.apollo.dev/r/contributing). +To see how the sidebar is built and how pages are grouped and named, see [this section](https://github.com/apollographql/gatsby-theme-apollo/tree/master/packages/gatsby-theme-apollo-docs#sidebarcategories) of the gatsby-theme-apollo-docs docs. There is also a [creating pages section](https://github.com/apollographql/gatsby-theme-apollo/tree/master/packages/gatsby-theme-apollo-docs#creating-pages) if you're interested in adding new pages. ## Code of Conduct The project has a [Code of Conduct] that *all* contributors are expected to diff --git a/crates/xtask/src/commands/prep/docs.rs b/crates/xtask/src/commands/prep/docs.rs index 8ce9e98ac..a005ffb5a 100644 --- a/crates/xtask/src/commands/prep/docs.rs +++ b/crates/xtask/src/commands/prep/docs.rs @@ -5,65 +5,111 @@ use std::{convert::TryFrom, fs}; use crate::utils; -pub(crate) fn build_error_code_reference() -> Result<()> { - utils::info("updating error reference material."); - let project_root = utils::project_root()?; - let docs_path = project_root.join("docs").join("source").join("errors.md"); - let codes_dir = project_root - .join("src") - .join("error") - .join("metadata") - .join("codes"); - - // sort code files alphabetically - let raw_code_files = fs::read_dir(&codes_dir)?; - - let mut code_files = Vec::new(); - for raw_code_file in raw_code_files { - let raw_code_file = raw_code_file?; - if raw_code_file.file_type()?.is_dir() { - return Err(anyhow!("Error code directory {} contains a directory {:?}. It must only contain markdown files.", &codes_dir, raw_code_file.file_name())); - } else { - code_files.push(raw_code_file); - } +pub(crate) struct DocsRunner { + pub(crate) project_root: Utf8PathBuf, + pub(crate) docs_root: Utf8PathBuf, +} + +impl DocsRunner { + pub(crate) fn new() -> Result { + let project_root = utils::project_root()?; + let docs_root = project_root.join("docs"); + Ok(Self { + project_root, + docs_root, + }) } - code_files.sort_by_key(|f| f.path()); - let mut all_descriptions = String::new(); + pub(crate) fn build_error_code_reference(&self) -> Result<()> { + utils::info("updating error reference material."); + let docs_path = &self.docs_root.join("source").join("errors.md"); + let codes_dir = &self + .project_root + .join("src") + .join("error") + .join("metadata") + .join("codes"); - // for each code description, get the name of the code from the filename, - // and add it as a header. Then push the header and description to the - // all_descriptions string - for code in code_files { - let path = Utf8PathBuf::try_from(code.path())?; + // sort code files alphabetically + let raw_code_files = fs::read_dir(&codes_dir)?; - let contents = fs::read_to_string(&path)?; - let code_name = path - .file_name() - .ok_or_else(|| anyhow!("Path {} doesn't have a file name", &path))? - .replace(".md", ""); + let mut code_files = Vec::new(); + for raw_code_file in raw_code_files { + let raw_code_file = raw_code_file?; + if raw_code_file.file_type()?.is_dir() { + return Err(anyhow!("Error code directory {} contains a directory {:?}. It must only contain markdown files.", &codes_dir, raw_code_file.file_name())); + } else { + code_files.push(raw_code_file); + } + } + code_files.sort_by_key(|f| f.path()); - let description = format!("### {}\n\n{}\n\n", code_name, contents); + let mut all_descriptions = String::new(); - all_descriptions.push_str(&description); - } + // for each code description, get the name of the code from the filename, + // and add it as a header. Then push the header and description to the + // all_descriptions string + for code in code_files { + let path = Utf8PathBuf::try_from(code.path())?; + + let contents = fs::read_to_string(&path)?; + let code_name = path + .file_name() + .ok_or_else(|| anyhow!("Path {} doesn't have a file name", &path))? + .replace(".md", ""); + + let description = format!("### {}\n\n{}\n\n", code_name, contents); - let docs_content = fs::read_to_string(&docs_path) - .with_context(|| format!("Could not read contents of {} to a String", &docs_path))?; - - // build up a new docs page with existing content line-by-line - // and then concat the loaded code descriptions after - let mut new_content = String::new(); - for line in docs_content.lines() { - new_content.push_str(line); - new_content.push('\n'); - if line.contains("") { - break; + all_descriptions.push_str(&description); } + + self.replace_content_after_token("", &all_descriptions, &docs_path) } - new_content.push_str(&all_descriptions); - fs::write(&docs_path, new_content)?; + pub(crate) fn copy_contributing(&self) -> Result<()> { + utils::info("updating contributing.md"); + + let source_path = self.project_root.join("CONTRIBUTING.md"); + let destination_path = self.docs_root.join("source").join("contributing.md"); + + let source_content_with_header = fs::read_to_string(&source_path) + .with_context(|| format!("Could not read contents of {} to a String", &source_path))?; + // Don't include the first header and the empty newline after it. + let source_content = source_content_with_header + .splitn(3, '\n') + .collect::>()[2]; + self.replace_content_after_token( + "", + &source_content, + &destination_path, + ) + } - Ok(()) + fn replace_content_after_token( + &self, + html_comment_token: &str, + source_content: &str, + destination_path: &Utf8PathBuf, + ) -> Result<()> { + // build up a new docs page with existing content line-by-line + // and then concat the replacement content + let destination_content = fs::read_to_string(&destination_path).with_context(|| { + format!( + "Could not read contents of {} to a String", + &destination_path + ) + })?; + let mut new_content = String::new(); + for line in destination_content.lines() { + new_content.push_str(line); + new_content.push('\n'); + if line.contains(html_comment_token) { + break; + } + } + new_content.push_str(&source_content); + + fs::write(&destination_path, new_content)?; + Ok(()) + } } diff --git a/crates/xtask/src/commands/prep/mod.rs b/crates/xtask/src/commands/prep/mod.rs index ac82f3120..b355b7256 100644 --- a/crates/xtask/src/commands/prep/mod.rs +++ b/crates/xtask/src/commands/prep/mod.rs @@ -2,9 +2,11 @@ mod docs; mod installers; mod npm; -use anyhow::Result; +use anyhow::{Context, Result}; use structopt::StructOpt; +use crate::commands::prep::docs::DocsRunner; + #[derive(Debug, StructOpt)] pub struct Prep {} @@ -12,6 +14,13 @@ impl Prep { pub fn run(&self, verbose: bool) -> Result<()> { npm::prepare_package(verbose)?; installers::update_versions()?; - docs::build_error_code_reference() + let docs_runner = DocsRunner::new()?; + docs_runner + .build_error_code_reference() + .with_context(|| "Could not build error code reference")?; + docs_runner + .copy_contributing() + .with_context(|| "Could not update contributing.md in the docs.")?; + Ok(()) } } diff --git a/docs/source/contributing.md b/docs/source/contributing.md index fb8e5b4e0..5c2bca63f 100644 --- a/docs/source/contributing.md +++ b/docs/source/contributing.md @@ -3,7 +3,11 @@ title: "Contributing to Rover" sidebar_title: "Contributing" --- -> Rover is not yet ready for external feature contributors, but [documentation contributions](#documentation) are welcome. At this time, this article is intended primarily for internal contributors and partners. + + +> Rover is a project by [Apollo GraphQL] and is not currently ready for +> external feature contributors, though some documentation contributions may be +> accepted. ## Prerequisites @@ -13,17 +17,56 @@ Rust installed. To install Rust, visit [https://www.rust-lang.org/tools/install] Rust has a build tool and package manager called [`cargo`] that you'll use to interact with Rover's code. +## Workflows + To build the CLI: -``` +```bash cargo build ``` -To run the CLI: -``` +To build and run the CLI with a set of arguments: +```bash cargo run -- -# e.g. cargo run -- help will run the rover help command ``` +e.g. To build and run `rover supergraph compose`: + +```bash +cargo run -- supergraph compose --config config.yaml +``` + +You can also install Rover to your local PATH from source with cargo by first +cloning this repository, and then running: +```bash +cargo run -- install +``` + +To run tests: +```bash +cargo test --workspace +``` + +To format your code: +```bash +cargo fmt --all +``` + +To lint your code: +```bash +cargo clippy +``` + +To run the lint checker that is run in CI: +```bash +cargo xtask lint +``` + +To run the tests that are run in CI: +```bash +cargo xtask test +``` + +[Apollo GraphQL]: https://www.apollographql.com [Rust]: https://www.rust-lang.org/ [`cargo`]: https://doc.rust-lang.org/cargo/index.html [https://www.rust-lang.org/tools/install]: https://www.rust-lang.org/tools/install @@ -63,4 +106,46 @@ npm start This will start up a development server with live reload enabled. You can see the docs by opening [localhost:8000](http://localhost:8000) in your browser. -To see how the sidebar is built and how pages are grouped and named, see [this section](https://github.com/apollographql/gatsby-theme-apollo/tree/master/packages/gatsby-theme-apollo-docs#sidebarcategories) of the gatsby-theme-apollo-docs docs. There is also a [creating pages section](https://github.com/apollographql/gatsby-theme-apollo/tree/master/packages/gatsby-theme-apollo-docs#creating-pages) if you're interesed in adding new pages. +To see how the sidebar is built and how pages are grouped and named, see [this section](https://github.com/apollographql/gatsby-theme-apollo/tree/master/packages/gatsby-theme-apollo-docs#sidebarcategories) of the gatsby-theme-apollo-docs docs. There is also a [creating pages section](https://github.com/apollographql/gatsby-theme-apollo/tree/master/packages/gatsby-theme-apollo-docs#creating-pages) if you're interested in adding new pages. + +## Code of Conduct +The project has a [Code of Conduct] that *all* contributors are expected to +follow. This code describes the *minimum* behavior expectations for all +contributors. + +As a contributor, how you choose to act and interact towards your fellow +contributors, as well as to the community, will reflect back not only on +yourself but on the project as a whole. The Code of Conduct is designed and +intended, above all else, to help establish a culture within the project that +allows anyone and everyone who wants to contribute to feel safe doing so. + +Should any individual act in any way that is considered in violation of the +[Code of Conduct], corrective actions will be taken. It is possible, however, +for any individual to *act* in such a manner that is not in violation of the +strict letter of the Code of Conduct guidelines while still going completely +against the spirit of what that Code is intended to accomplish. + +Open, diverse, and inclusive communities live and die on the basis of trust. +Contributors can disagree with one another so long as they trust that those +disagreements are in good faith and everyone is working towards a common goal. + +## Bad Actors +All contributors to tacitly agree to abide by both the letter and spirit of the +[Code of Conduct]. Failure, or unwillingness, to do so will result in +contributions being respectfully declined. + +A *bad actor* is someone who repeatedly violates the *spirit* of the Code of +Conduct through consistent failure to self-regulate the way in which they +interact with other contributors in the project. In doing so, bad actors +alienate other contributors, discourage collaboration, and generally reflect +poorly on the project as a whole. + +Being a bad actor may be intentional or unintentional. Typically, unintentional +bad behavior can be easily corrected by being quick to apologize and correct +course *even if you are not entirely convinced you need to*. Giving other +contributors the benefit of the doubt and having a sincere willingness to admit +that you *might* be wrong is critical for any successful open collaboration. + +Don't be a bad actor. + +[Code of Conduct]: https://github.com/apollographql/.github/blob/main/CODE_OF_CONDUCT.md