<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>stuart crust</title>
    <link>https://stuartcrust.com/</link>
    <description>Recent content on stuart crust</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Thu, 03 Jan 2019 00:00:00 -0500</lastBuildDate><atom:link href="https://stuartcrust.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Lints, Syntax Parsing, and You</title>
      <link>https://stuartcrust.com/2019/01/lints-syntax-parsing-and-you/</link>
      <pubDate>Thu, 03 Jan 2019 00:00:00 -0500</pubDate>
      
      <guid>https://stuartcrust.com/2019/01/lints-syntax-parsing-and-you/</guid>
      <description>&lt;p&gt;In my &lt;a href=&#34;https://stuartcrust.com/2018/12/yak-shaving-in-f/&#34;&gt;previous post&lt;/a&gt; I ran into a number of issues and confusion around &lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s &lt;code&gt;#[clippy::author]&lt;/code&gt; annotation and autogenerated code.
Instead of continuing with &lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s documentation, I&amp;rsquo;m going to jump over to &lt;a href=&#34;https://llogiq.github.io/&#34;&gt;llogiq&lt;/a&gt;&amp;rsquo;s blogpost on &lt;a href=&#34;https://llogiq.github.io/2015/06/04/workflows.html&#34;&gt;writing &lt;code&gt;clippy&lt;/code&gt; lints&lt;/a&gt; and see what I can learn about lint implementation and the necessary datatypes.&lt;/p&gt;
&lt;p&gt;Because &lt;code&gt;clippy&lt;/code&gt; is a Rust toolchain component, and the &lt;a href=&#34;https://crates.io/crates/clippy&#34;&gt;&lt;code&gt;clippy&lt;/code&gt; version on https://crates.io&lt;/a&gt; is no longer maintained, documentation tools like &lt;a href=&#34;https://docs.rs&#34;&gt;docs.rs&lt;/a&gt; are unavailable for browsing &lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s types.
Fortunately, Rust has a very strong offline documentation story, and generating documentation for a project is as simple as &lt;code&gt;cargo doc --open&lt;/code&gt;.
This can be a little tricky to get set up when you&amp;rsquo;re halfway through implementing a feature and looking for information in the documentation though, because the project has to successfully compile as part of generating the offline documentation.&lt;/p&gt;
&lt;p&gt;Since &lt;code&gt;clippy&lt;/code&gt; uses Rust compiler types to implement lints, we also need to have access to the documentation for &lt;code&gt;rustc&lt;/code&gt;, Rust&amp;rsquo;s compiler, on the &lt;code&gt;nightly&lt;/code&gt; toolchain; this can be accessed at &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/rustc/index.html&#34;&gt;https://doc.rust-lang.org/nightly/nightly-rustc/rustc/index.html&lt;/a&gt;.
Unfortunately this set of compiler documentation is not available offline which seems like a gap in Rust&amp;rsquo;s documentation story.&lt;/p&gt;
&lt;h2 id=&#34;steps-to-writing-a-clippy-lint&#34;&gt;Steps to Writing a Clippy Lint&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve broken the process I went through to implement this lint into steps to more clearly separate the different parts of a lint, the tools and processes involved at each stage, and problems and errors I encountered along the way as well as solutions I found where applicable.&lt;/p&gt;
&lt;p&gt;For quick reference, here is a list of the steps involved:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#step-one-write-an-example&#34;&gt;Step One: Write an Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#step-two-declare-the-lint&#34;&gt;Step Two: Declare the Lint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#step-three-register-the-lint-with-clippy&#34;&gt;Step Three: Register the Lint with Clippy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#step-four-start-implementing-lint-passes&#34;&gt;Step Four: Start Implementing Lint Passes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#step-five-inspect-and-interpret-the-ast&#34;&gt;Step Five: Inspect and Interpret the AST&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#step-six-implement-earlylintpass&#34;&gt;Step Six: Implement EarlyLintPass&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#step-seven-generate-the-stderr-file-for-the-new-lint&#34;&gt;Step Seven: Generate the .stderr File for the New Lint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#step-eight-iterate&#34;&gt;Step Eight: Iterate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#step-nine-run-the-full-test-suite&#34;&gt;Step Nine: Run the Full Test Suite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#step-ten-linting-clippy-with-local-changes&#34;&gt;Step Ten: Linting Clippy with Local Changes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;step-one-write-an-example&#34;&gt;Step One: Write an Example&lt;/h3&gt;
&lt;p&gt;The first step in writing a lint, as with most code, is to write the piece that &lt;em&gt;uses&lt;/em&gt; the code you&amp;rsquo;re going to write.
If we were writing regular code this might take the form of one or more test cases, but because we&amp;rsquo;re writing a lint we want to instead write an example of the code we&amp;rsquo;re trying to lint against.
I&amp;rsquo;ve already done this earlier when I tried to use the &lt;code&gt;#[clippy::author]&lt;/code&gt; directive, so I&amp;rsquo;m going to reuse the same example while using llogiq&amp;rsquo;s blogpost as a guide for my own lint.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the small code example we want to lint against:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MyStruct&lt;/span&gt; {
    id: &lt;span style=&#34;color:#66d9ef&#34;&gt;usize&lt;/span&gt;
}

&lt;span style=&#34;color:#66d9ef&#34;&gt;impl&lt;/span&gt; MyStruct {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_id&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;self) -&amp;gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;usize&lt;/span&gt; {
        self.id
    }
}

&lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {
   &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; s &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; MyStruct { id: &lt;span style=&#34;color:#ae81ff&#34;&gt;42&lt;/span&gt; };
   s.get_id();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;step-two-declare-the-lint&#34;&gt;Step Two: Declare the Lint&lt;/h3&gt;
&lt;p&gt;After writing the example to lint against, we need to actually define the lint; this is done using the &lt;code&gt;declare_clippy_lint!&lt;/code&gt; macro from the &lt;code&gt;clippy_lints&lt;/code&gt; crate.
I tried compiling &lt;code&gt;clippy&lt;/code&gt; after declaring the lint and ran into the following error:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;cargo check
   Compiling clippy_lints v0.0.212
error: cannot find macro `declare_tool_lint!` in this scope
  --&amp;gt; clippy_lints/src/lib.rs:53:9
   |
53 |           declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
   |           ^^^^^^^^^^^^^^^^^
   |
  ::: clippy_lints/src/getter_prefix.rs:3:1
   |
3  | / declare_clippy_lint! {
4  | |     pub GETTER_PREFIX,
5  | |     style,
6  | |     &amp;#34;prefixing a getter with `get_`, which does not follow convention&amp;#34;
7  | | }
   | |_- in this macro invocation

error: aborting due to previous error

error: Could not compile `clippy_lints`.
warning: build failed, waiting for other jobs to finish...
error: cannot find macro `declare_tool_lint!` in this scope
  --&amp;gt; clippy_lints/src/lib.rs:53:9
   |
53 |           declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
   |           ^^^^^^^^^^^^^^^^^
   |
  ::: clippy_lints/src/getter_prefix.rs:3:1
   |
3  | / declare_clippy_lint! {
4  | |     pub GETTER_PREFIX,
5  | |     style,
6  | |     &amp;#34;prefixing a getter with `get_`, which does not follow convention&amp;#34;
7  | | }
   | |_- in this macro invocation

error: aborting due to previous error

error: Could not compile `clippy_lints`.

To learn more, run the command again with --verbose.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;cargo&lt;/code&gt; can&amp;rsquo;t find the &lt;code&gt;declare_tool_lint!&lt;/code&gt; macro in the current scope, which is not an error I was expecting to see because I didn&amp;rsquo;t think I was using that macro in my lint definition.
It turns out that the definition of the &lt;code&gt;declare_clippy_lint!&lt;/code&gt; macro uses the &lt;code&gt;declare_tool_lint!&lt;/code&gt; macro, so this second macro must be brought into scope before the first can be used.
I&amp;rsquo;m not very familiar with macros or metaprogramming in Rust, but after looking at a number of other lints it seems like all of them &lt;code&gt;use&lt;/code&gt; the &lt;code&gt;declare_tool_lint!&lt;/code&gt; macro so I will too.&lt;/p&gt;
&lt;p&gt;Here is the lint code so far, including the first line which imports the dependent lint:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;crate&lt;/span&gt;::rustc::declare_tool_lint;

declare_clippy_lint&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt; {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; GETTER_PREFIX,
    style,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;prefixing a getter with `get_`, which does not follow convention&amp;#34;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As part of declaring the lint, we also want to document the lint by describing what it does and include some examples of code that will not pass the lint and alternatives that &lt;em&gt;will&lt;/em&gt; pass the lint rules.
By following a standard convention, documentation written for each lint can be extracted and added to the &lt;a href=&#34;https://rust-lang.github.io/rust-clippy/master/&#34;&gt;lint list&lt;/a&gt; which provides a filterable list of all of &lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s lints.&lt;/p&gt;
&lt;p&gt;Rust provides a lot of tools for documenting Rust code, the cornerstone of which is &lt;a href=&#34;https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html#making-useful-documentation-comments&#34;&gt;documentation comments&lt;/a&gt;. Documentation comments support Markdown syntax for formatting and are used to generate browsable HTML pages, without requiring the author to maintain separate written documentation. Documentation comments also drive other tools such as &lt;a href=&#34;https://docs.rs/&#34;&gt;docs.rs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here is a (very rough) initial documentation comment for the lint, including examples of bad and good code samples:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// **What it does:** Checks for the `get_` prefix on getters.
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// **Why is this bad?** The Rust API Guidelines section on naming
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// [specifies](https://rust-lang-nursery.github.io/api-guidelines/naming.html#getter-names-follow-rust-convention-c-getter)
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// that the `get_` prefix is not used for getters in Rust code unless
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// there is a single and obvious thing that could reasonably be gotten by
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// a getter.
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// **Known problems:** Exceptions not yet implemented.
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// **Example:**
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// ```rust
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// // Bad
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// impl B {
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///     fn get_id(&amp;amp;self) -&amp;gt; usize {
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///         ..
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///     }
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///}
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// // Good
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// impl G {
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///     fn id(&amp;amp;self) -&amp;gt; usize {
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///         ..
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///     }
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// }
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// ```
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;step-three-register-the-lint-with-clippy&#34;&gt;Step Three: Register the Lint with Clippy&lt;/h3&gt;
&lt;p&gt;This is a largely automated process thanks to some &lt;code&gt;clippy&lt;/code&gt; tooling as described in the &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md#how-clippy-works&#34;&gt;How Clippy Works&lt;/a&gt; section of the contribution documentation.
Simply (re-)run &lt;code&gt;util/dev update_lints&lt;/code&gt; as necessary, which autogenerates the majority of &lt;code&gt;clippy_lints/src/lib.rs&lt;/code&gt; to declare lints and lint groups.&lt;/p&gt;
&lt;p&gt;Alternatively, this can be done manually by adding the lint to the correct lint group inside the &lt;code&gt;register_plugins&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;Regardless of how the lint is added to the lint groups, the lint must be registered with the lint registry by introducing the lint as either an early or late lint pass.
In the case of this lint, which will be implemented as an early lint pass, the following line adds it to the lint registry as declared inside the &lt;code&gt;register_plugins&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;reg.register_early_lint_pass(&lt;span style=&#34;color:#66d9ef&#34;&gt;box&lt;/span&gt; naming::GetterPrefix);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;step-four-start-implementing-lint-passes&#34;&gt;Step Four: Start Implementing Lint Passes&lt;/h3&gt;
&lt;p&gt;Now that the lint is defined and registered with &lt;code&gt;clippy&lt;/code&gt;, we can start implementing the logic to lint against the example we implemented in &lt;a href=&#34;#step-one-write-an-example&#34;&gt;Step One&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For most lints there are two traits that need to be implemented so the lint can be registered with &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/rustc_plugin/registry/struct.Registry.html&#34;&gt;&lt;code&gt;rustc_plugin::registry::Registry&lt;/code&gt;&lt;/a&gt;: the &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.LintPass.html&#34;&gt;&lt;code&gt;LintPass&lt;/code&gt;&lt;/a&gt; trait and one of either the &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.EarlyLintPass.html&#34;&gt;&lt;code&gt;EarlyLintPass&lt;/code&gt;&lt;/a&gt; or the &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.LateLintPass.html&#34;&gt;&lt;code&gt;LateLintPass&lt;/code&gt;&lt;/a&gt; trait.
&lt;code&gt;LintPass&lt;/code&gt; is apparently necessary to &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.LintPass.html#tymethod.get_lints&#34;&gt;provide descriptions of the possible lints the lint can emit&lt;/a&gt;, but in all of the lints I have looked at, the &lt;code&gt;LintPass&lt;/code&gt; implementation always takes the form:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;impl&lt;/span&gt; LintPass &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; Pass {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_lints&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;self) -&amp;gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;LintArray&lt;/span&gt; {
        lint_array&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;(LINT_NAME)
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;so I&amp;rsquo;m surprised there hasn&amp;rsquo;t been a &lt;code&gt;#[derive]&lt;/code&gt; annotation written for it or some kind of macro that would reduce the repetition.&lt;/p&gt;
&lt;p&gt;As for &lt;code&gt;EarlyLintPass&lt;/code&gt; or &lt;code&gt;LateLintPass&lt;/code&gt;, the choice of which trait to implement comes down to the kind of information a given lint needs about the code it is linting: &lt;code&gt;EarlyLintPass&lt;/code&gt; methods only provide &lt;a href=&#34;https://en.wikipedia.org/wiki/Abstract_syntax_tree&#34;&gt;abstract syntax tree (AST)&lt;/a&gt; information, whereas &lt;code&gt;LateLintPass&lt;/code&gt; methods are, as the name implies, executed later in the compilation process and contain type information.
Since this lint is only interested in function names and checking them against known patterns, I&amp;rsquo;ve decided to implement the &lt;code&gt;EarlyLintPass&lt;/code&gt; trait.
There seems to be a lot of overlap in method signatures between the two types of lint pass, so if I need to switch to &lt;code&gt;LateLintPass&lt;/code&gt; to get access to additional type information it should not be too difficult to transition over.&lt;/p&gt;
&lt;h3 id=&#34;step-five-inspect-and-interpret-the-ast&#34;&gt;Step Five: Inspect and Interpret the AST&lt;/h3&gt;
&lt;p&gt;Most everything up until now has been boilerplate for getting the lint set up and correctly registered with &lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s infrastructure.
Now that we have everything set up, we need to figure out how to tell the lint to match against the undesired function names we&amp;rsquo;ve already written in our test.
To do this, we need to first understand how the &lt;code&gt;rustc&lt;/code&gt; compiler sees the code we have written, which for &lt;code&gt;rustc&lt;/code&gt; is represented as an &lt;a href=&#34;https://en.wikipedia.org/wiki/Abstract_syntax_tree&#34;&gt;abstract syntax tree (AST)&lt;/a&gt;, and then parse that tree to match against undesired nodes within the tree that correspond to the Rust source code.
To retrieve this representation, we can use &lt;code&gt;rustc&lt;/code&gt; to generate the AST and then inspect it manually to get a sense of the program structure; &lt;code&gt;rustc&lt;/code&gt; has the &lt;code&gt;-Z&lt;/code&gt; option for controlling various debug options (see &lt;code&gt;rustc --help&lt;/code&gt;), and one of these options tells &lt;code&gt;rustc&lt;/code&gt; to print the AST as JSON and halt compilation: &lt;code&gt;-Z ast-json&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The full command to print the AST as JSON, specifying the individual test for this lint whose code we want to inspect, is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ rustc tests/ui/naming.rs -L target/debug -Z ast-json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The initial output of this command is utterly unreadable because &lt;code&gt;rustc&lt;/code&gt; prints it as a single line of JSON, so I&amp;rsquo;m going to use &lt;a href=&#34;https://stedolan.github.io/jq/&#34;&gt;&lt;code&gt;jq&lt;/code&gt;&lt;/a&gt; to pretty-print the AST so it&amp;rsquo;s easier to read:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;module&amp;#34;&lt;/span&gt;: {
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;inner&amp;#34;&lt;/span&gt;: {
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;lo&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;426&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;hi&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;611&lt;/span&gt;
        },
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;items&amp;#34;&lt;/span&gt;: [
            [&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;snip&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1604&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;lines&lt;/span&gt;]
        ],
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;inline&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
    },
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;attrs&amp;#34;&lt;/span&gt;: [],
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;span&amp;#34;&lt;/span&gt;: {
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;lo&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;426&lt;/span&gt;,
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;hi&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;611&lt;/span&gt;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In all, the AST for my 12-line test file ended up expanding to a 1627-line (pretty-printed) JSON file.
The &lt;code&gt;items&lt;/code&gt; key and its 1604 lines are where the actually interesting AST information is in the data structure, containing information about every identifier, implementation, attribute, etc in the code.
Within the &lt;code&gt;items&lt;/code&gt; array, the name of the function in the test, &lt;code&gt;get_id&lt;/code&gt;, appears 5 times in various contexts such as &lt;code&gt;&amp;quot;variant&amp;quot;: &amp;quot;Impl&amp;quot;&lt;/code&gt; and &lt;code&gt;&amp;quot;variant&amp;quot;: &amp;quot;MethodCall&amp;quot;&lt;/code&gt;.
The following is what I believe to be the beginning of the AST for the &lt;code&gt;get_id&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt;,
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;ident&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_id&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;vis&amp;#34;&lt;/span&gt;: {
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;node&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Public&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;span&amp;#34;&lt;/span&gt;: {
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;lo&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;485&lt;/span&gt;,
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;hi&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;488&lt;/span&gt;
        }
    },
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;defaultness&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Final&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;attrs&amp;#34;&lt;/span&gt;: [],
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;generics&amp;#34;&lt;/span&gt;: {
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;params&amp;#34;&lt;/span&gt;: [],
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;where_clause&amp;#34;&lt;/span&gt;: {
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;predicates&amp;#34;&lt;/span&gt;: [],
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;span&amp;#34;&lt;/span&gt;: {
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;lo&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;hi&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
            }
        },
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;span&amp;#34;&lt;/span&gt;: {
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;lo&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;hi&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
        }
    },
    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;...&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Specifically, the following are the nodes that describe the &lt;code&gt;pub fn get_id&lt;/code&gt; text literals of the function signature:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;tokens&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; [
    {
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;variant&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Token&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fields&amp;#34;&lt;/span&gt;: [
            {
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;lo&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;485&lt;/span&gt;,
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;hi&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;488&lt;/span&gt;
            },
            {
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;variant&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Ident&amp;#34;&lt;/span&gt;,
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fields&amp;#34;&lt;/span&gt;: [
                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pub&amp;#34;&lt;/span&gt;,
                    &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
                ]
            }
        ]
    },
    {
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;variant&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Token&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fields&amp;#34;&lt;/span&gt;: [
            {
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;lo&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;489&lt;/span&gt;,
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;hi&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;491&lt;/span&gt;
            },
            {
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;variant&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Ident&amp;#34;&lt;/span&gt;,
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fields&amp;#34;&lt;/span&gt;: [
                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fn&amp;#34;&lt;/span&gt;,
                    &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
                ]
            }
        ]
    },
    {
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;variant&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Token&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fields&amp;#34;&lt;/span&gt;: [
            {
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;lo&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;492&lt;/span&gt;,
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;hi&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;498&lt;/span&gt;
            },
            {
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;variant&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Ident&amp;#34;&lt;/span&gt;,
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fields&amp;#34;&lt;/span&gt;: [
                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_id&amp;#34;&lt;/span&gt;,
                    &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
                ]
            }
        ]
    },
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now that the relevant sections of the AST have been identified, we can use this information to get a better understanding of how &lt;code&gt;rustc&lt;/code&gt; (and thus tools like &lt;code&gt;clippy&lt;/code&gt;) understand the written Rust code in the source file.
This information can be useful at many different stages of lint implementation, particularly if we need to debug out lint or we are not matching the expected nodes in our lint code.&lt;/p&gt;
&lt;h3 id=&#34;step-six-implement-earlylintpass&#34;&gt;Step Six: Implement EarlyLintPass&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;EarlyLintPass&lt;/code&gt; trait requires the implementation of one of its provided methods to perform the lint work.
Looking at the &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.EarlyLintPass.html&#34;&gt;list of provided methods&lt;/a&gt;, however, I&amp;rsquo;m not really sure where to start or which method to implement.
A lot of &lt;code&gt;rustc&lt;/code&gt;&amp;rsquo;s internals seem to be chronically under-documented, which makes it very difficult to understand how different internals are used (what&amp;rsquo;s the difference between &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.EarlyLintPass.html#method.check_item&#34;&gt;&lt;code&gt;check_item&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.EarlyLintPass.html#method.check_item_post&#34;&gt;&lt;code&gt;check_item_post&lt;/code&gt;&lt;/a&gt;, for example?) or the subtle (or not so subtle) differences between various types or methods.&lt;/p&gt;
&lt;p&gt;My strategy in learning about the &lt;code&gt;rustc&lt;/code&gt; internals so far has been a combination of looking at existing lints and trying to identify what the internals do based on the lint&amp;rsquo;s goals and existing code, as well as inspecting not the &lt;code&gt;EarlyLintPass&lt;/code&gt; methods themselves but rather the associated types such as &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/struct.Item.html&#34;&gt;&lt;code&gt;syntax::ast::Item&lt;/code&gt;&lt;/a&gt; or &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/struct.Local.html&#34;&gt;&lt;code&gt;syntax::ast::Local&lt;/code&gt;&lt;/a&gt; which are generally better documented than the methods that use them.
These associated types also match very closely if not exactly to the AST structure produced by &lt;code&gt;rustc&lt;/code&gt;, so by identifying the structure of the information in the AST as above, it is easier to choose the correct function to implement based on its associated type which contains the same information as the already-identified AST subtree(s).&lt;/p&gt;
&lt;p&gt;Based on my understanding, it looks like the method that I want to implement is &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.EarlyLintPass.html#method.check_item&#34;&gt;&lt;code&gt;check_item&lt;/code&gt;&lt;/a&gt; which will yield &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/struct.Item.html&#34;&gt;&lt;code&gt;syntax::ast::Item&lt;/code&gt;&lt;/a&gt; instances whose &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/enum.ItemKind.html&#34;&gt;&lt;code&gt;syntax::ast::ItemKind&lt;/code&gt;&lt;/a&gt; we can then match on for &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/enum.ItemKind.html#variant.Fn&#34;&gt;function declarations&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My initial implementation of the &lt;code&gt;EarlyLintPass&lt;/code&gt; trait based on the above yielded the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;impl&lt;/span&gt; EarlyLintPass &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; GetterPrefix {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;check_item&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;mut&lt;/span&gt; self, cx: &lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;EarlyContext&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;&amp;#39;_&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;, item: &lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ast&lt;/span&gt;::Item) {
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; ast::ItemKind::Fn(..) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; item.node {
            &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; item.ident.name;
            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; name.as_str().starts_with(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_&amp;#34;&lt;/span&gt;) {
                span_lint(cx, GETTER_PREFIX, item.span, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;prefixing a getter with `get_` does not follow naming conventions&amp;#34;&lt;/span&gt;);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This implementation checks each &lt;code&gt;Item&lt;/code&gt; in the AST and looks for nodes identified as &lt;code&gt;ItemKind::Fn&lt;/code&gt;; that is, functions declared in the source.
For matching nodes, the name is extracted from the &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/syntax/source_map/symbol/struct.Ident.html&#34;&gt;node identifier&lt;/a&gt; and is checked to see if it starts with the &lt;code&gt;get_&lt;/code&gt; prefix.
The &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/blob/261ebcfbb4f4c70230af0ec18d3d592a9825ecf0/clippy_lints/src/utils/mod.rs#L600-L602&#34;&gt;&lt;code&gt;span_lint&lt;/code&gt;&lt;/a&gt; function comes from &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/tree/master/clippy_lints/src/utils&#34;&gt;&lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s lint utils&lt;/a&gt; and is what actually contextualizes lint warnings and errors around the offending code and outputs the lint message.&lt;/p&gt;
&lt;p&gt;However, it turns out that &lt;code&gt;if let ast::ItemKind::Fn(..)&lt;/code&gt; only matches the &lt;code&gt;main&lt;/code&gt; function name of the test case, rather than my expectation that it would match all functions declared within the file.&lt;/p&gt;
&lt;p&gt;Instead, since we are interested in functions implemented for a type, we can use the &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.EarlyLintPass.html#method.check_impl_item&#34;&gt;&lt;code&gt;check_impl_item&lt;/code&gt;&lt;/a&gt; method which will yield &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/struct.ImplItem.html&#34;&gt;&lt;code&gt;syntax::ast::ImplItem&lt;/code&gt;&lt;/a&gt; instances whose &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/enum.ImplItemKind.html&#34;&gt;&lt;code&gt;syntax::ast::ImplItemKind&lt;/code&gt;&lt;/a&gt; we can then match on for &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/enum.ImplItemKind.html#variant.Method&#34;&gt;methods&lt;/a&gt; like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;impl&lt;/span&gt; EarlyLintPass &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; GetterPrefix {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;check_impl_item&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;mut&lt;/span&gt; self, cx: &lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;EarlyContext&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;&amp;#39;_&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;, implitem: &lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ast&lt;/span&gt;::ImplItem) {
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; ast::ImplItemKind::Method(..) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; implitem.node {
            &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; implitem.ident.name;
            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; name.as_str().starts_with(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_&amp;#34;&lt;/span&gt;) {
                span_lint(
                    cx,
                    GETTER_PREFIX,
                    implitem.span,
                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;prefixing a getter with `get_` does not follow naming conventions&amp;#34;&lt;/span&gt;
                );
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above implementation works very similarly to the initial implementation, but instead of checking &lt;code&gt;Item&lt;/code&gt;s looking for &lt;code&gt;ItemKind::Fn&lt;/code&gt;, it instead looks at &lt;code&gt;ImplItem&lt;/code&gt;s in the AST and matches &lt;code&gt;ImplItemKind::Method&lt;/code&gt; nodes (since implementation nodes also include &lt;code&gt;const&lt;/code&gt; declarations, types and type aliases, traits, and macros in addition to methods).&lt;/p&gt;
&lt;p&gt;To test an individual lint without the full &lt;code&gt;clippy&lt;/code&gt; test harness (or to see &lt;code&gt;println!&lt;/code&gt;s or other debugging statements more clearly), we can use the following &lt;code&gt;clippy-driver&lt;/code&gt; incantation and specify a single UI test file, &lt;code&gt;tests/ui/naming.rs&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ CLIPPY_TESTS&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;true cargo run --bin clippy-driver -- -L ./target/debug tests/ui/naming.rs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This lint pass implementation results in the following (successful) lint warning:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;warning: prefixing a getter with `get_` does not follow naming conventions
  --&amp;gt; tests/ui/naming.rs:15:5
   |
15 | /     pub fn get_id(&amp;amp;self) -&amp;gt; usize {
16 | |         self.id
17 | |     }
   | |_____^
   |
   = note: #[warn(clippy::getter_prefix)] on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#getter_prefix
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;step-seven-generate-the-stderr-file-for-the-new-lint&#34;&gt;Step Seven: Generate the .stderr File for the New Lint&lt;/h3&gt;
&lt;p&gt;To test its behaviour, &lt;code&gt;clippy&lt;/code&gt; uses UI tests to check that the output of the compiler is exactly as expected.
The &lt;code&gt;.stderr&lt;/code&gt; file &lt;code&gt;clippy&lt;/code&gt; will use to check the newly implemented lint is automatically generated whenever the tests are run using &lt;code&gt;cargo test&lt;/code&gt;, but rather than running all of the tests at this point we can run just the test for the individual lint by specifying &lt;code&gt;TESTNAME=ui/naming&lt;/code&gt; where &lt;code&gt;ui/naming&lt;/code&gt; is the UI test to run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ TESTNAME&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;ui/naming cargo test --test compile-test
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To update the &lt;code&gt;.stderr&lt;/code&gt; (and &lt;code&gt;.stdout&lt;/code&gt;, if applicable) files in &lt;code&gt;tests/ui/&lt;/code&gt;, we use the provided update script (the correct incantation for an individual lint can be found in the output of &lt;code&gt;cargo test&lt;/code&gt; with a specified &lt;code&gt;TESTNAME&lt;/code&gt; as we did above):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ tests/ui/update-references.sh &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;target/debug/test_build_base&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;naming.rs&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will create the &lt;code&gt;tests/ui/naming.stderr&lt;/code&gt; file for the lint.&lt;/p&gt;
&lt;h3 id=&#34;step-eight-iterate&#34;&gt;Step Eight: Iterate&lt;/h3&gt;
&lt;p&gt;Now that the bare bones of the lint is implemented and it has &lt;code&gt;stderr&lt;/code&gt; output as expected, the lint can be iterated on to add more functionality and identify possible false positives that need to be mitigated.&lt;/p&gt;
&lt;p&gt;In the case of this lint, I added test cases that cover the exceptions to the naming rule and then introduced an additional check in the lint to see if the matched function name appeared in this exceptions list:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; ALLOWED_METHOD_NAMES: [&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&amp;#39;static &lt;span style=&#34;color:#66d9ef&#34;&gt;str&lt;/span&gt;; &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_mut&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_unchecked&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_unchecked_mut&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_ref&amp;#34;&lt;/span&gt;
];

&lt;span style=&#34;color:#66d9ef&#34;&gt;impl&lt;/span&gt; EarlyLintPass &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; GetterPrefix {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;check_impl_item&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;mut&lt;/span&gt; self, cx: &lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;EarlyContext&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;&amp;#39;_&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;, implitem: &lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ast&lt;/span&gt;::ImplItem) {
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; ast::ImplItemKind::Method(..) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; implitem.node {
            &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; implitem.ident.name.as_str().get();
            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; name.starts_with(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;ALLOWED_METHOD_NAMES.contains(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;name) {
                span_lint(
                    cx,
                    GETTER_PREFIX,
                    implitem.span,
                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;prefixing a getter with `get_` does not follow naming conventions&amp;#34;&lt;/span&gt;,
                );
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;step-nine-run-the-full-test-suite&#34;&gt;Step Nine: Run the Full Test Suite&lt;/h3&gt;
&lt;p&gt;Up until now I have only been running tests for the lint I have been working on to speed up the feedback cycle.
Before moving on, I want to run the complete test suite to make sure that the tests still pass with my additions, and if any existing lints need to be changed to conform to the new lint.&lt;/p&gt;
&lt;p&gt;In doing so I discovered a &lt;code&gt;get_unit&lt;/code&gt; function defined in the &lt;a href=&#34;https://rust-lang.github.io/rust-clippy/master/index.html#unused_unit&#34;&gt;&lt;code&gt;unused_unit&lt;/code&gt;&lt;/a&gt; lint, but since this definition was localized to one lint file I was able to change the function name to pass the getter prefix lint and still maintain the lint&amp;rsquo;s original functionality.
Changing this function name also meant that the &lt;code&gt;tests/ui/unused_unit.stderr&lt;/code&gt; file was out of date, which was updated using the provided &lt;code&gt;tests/ui/update-all-references.sh&lt;/code&gt; script.&lt;/p&gt;
&lt;h3 id=&#34;step-ten-linting-clippy-with-local-changes&#34;&gt;Step Ten: Linting Clippy with Local Changes&lt;/h3&gt;
&lt;p&gt;The last step before submitting a pull request to &lt;a href=&#34;https://github.com/rust-lang/rust-clippy&#34;&gt;rust-lang/rust-clippy&lt;/a&gt; is to make sure that all lints that have already been defined pass &lt;code&gt;clippy&lt;/code&gt; (that is, there are no suggestions reported by &lt;code&gt;clippy&lt;/code&gt; for its own codebase).
Running &lt;code&gt;clippy&lt;/code&gt; locally and addressing any issues found ahead of submitting a pull request will cut down on the feedback cycle and speed up the pull request review process.
The recommended way to do this is by building &lt;code&gt;clippy&lt;/code&gt; and then running it with all lint groups (including &lt;code&gt;internal&lt;/code&gt; and &lt;code&gt;pedantic&lt;/code&gt;) turned on:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ cargo build
$ &lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;pwd&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;/target/debug/cargo-clippy clippy --all-targets --all-features -- -D clippy::all -D clippy::internal -D clippy::pedantic
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I was not able to run this command successfully, as it resulted in what appear to be dynamic linker errors on my machine:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;$ clippy/target/debug/cargo-clippy --all-targets --all-features -- -D clippy::all -D clippy::internal -D clippy::pedantic
error: failed to run `rustc` to learn about target-specific information

Caused by:
  process didn&amp;#39;t exit successfully: `clippy/target/debug/clippy-driver rustc - --crate-name ___ --print=file-names --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro` (signal: 6, SIGABRT: process abort signal)
--- stderr
dyld: Library not loaded: @rpath/librustc_driver-b630426988dbbdb0.dylib
  Referenced from: clippy/target/debug/clippy-driver
  Reason: image not found
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, even without running &lt;code&gt;clippy&lt;/code&gt; locally, in the case of this getter prefix lint &lt;code&gt;clippy&lt;/code&gt; would not pass local &lt;code&gt;clippy&lt;/code&gt;.
It turns out that there a number of &lt;code&gt;rustc&lt;/code&gt; methods that do not follow the API naming convention, and I will need to consult with other &lt;code&gt;clippy&lt;/code&gt; developers to find out if we will need to add more exceptions to the lint than we had originally identified.
The one method that is particularly problematic is &lt;a href=&#34;https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.LintPass.html#tymethod.get_lints&#34;&gt;&lt;code&gt;LintPass::get_lints&lt;/code&gt;&lt;/a&gt; because it appears in every lint that has already been defined in &lt;code&gt;clippy&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;submitting-the-lint&#34;&gt;Submitting the Lint&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s the implemented lint in its entirety:&lt;/p&gt;
&lt;p&gt;The UI test file &lt;code&gt;tests/ui/naming.rs&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// file at the top-level directory of this distribution.
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Licensed under the Apache License, Version 2.0 &amp;lt;LICENSE-APACHE or
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// http://www.apache.org/licenses/LICENSE-2.0&amp;gt; or the MIT license
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// &amp;lt;LICENSE-MIT or http://opensource.org/licenses/MIT&amp;gt;, at your
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// option. This file may not be copied, modified, or distributed
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// except according to those terms.
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MyStruct&lt;/span&gt; {
    id: &lt;span style=&#34;color:#66d9ef&#34;&gt;usize&lt;/span&gt;
}

&lt;span style=&#34;color:#66d9ef&#34;&gt;impl&lt;/span&gt; MyStruct {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_id&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;self) -&amp;gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;usize&lt;/span&gt; {
        self.id
    }

    &lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;self) -&amp;gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;usize&lt;/span&gt; {
        self.id
    }

    &lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_mut&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;mut&lt;/span&gt; self) -&amp;gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;usize&lt;/span&gt; {
        self.id
    }

    &lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_unchecked&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;self) -&amp;gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;usize&lt;/span&gt; {
        self.id
    }

    &lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_unchecked_mut&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;mut&lt;/span&gt; self) -&amp;gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;usize&lt;/span&gt; {
        self.id
    }

    &lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_ref&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;self) -&amp;gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;usize&lt;/span&gt; {
        self.id
    }
}

&lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {
   &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;mut&lt;/span&gt; s &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; MyStruct { id: &lt;span style=&#34;color:#ae81ff&#34;&gt;42&lt;/span&gt; };
   s.get_id();
   s.get();
   s.get_mut();
   s.get_unchecked();
   s.get_unchecked_mut();
   s.get_ref();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The lint implementation &lt;code&gt;clippy_lints/src/naming.rs&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// file at the top-level directory of this distribution.
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Licensed under the Apache License, Version 2.0 &amp;lt;LICENSE-APACHE or
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// http://www.apache.org/licenses/LICENSE-2.0&amp;gt; or the MIT license
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// &amp;lt;LICENSE-MIT or http://opensource.org/licenses/MIT&amp;gt;, at your
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// option. This file may not be copied, modified, or distributed
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// except according to those terms.
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;crate&lt;/span&gt;::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;crate&lt;/span&gt;::rustc::{declare_tool_lint, lint_array};
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;crate&lt;/span&gt;::syntax::ast;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;crate&lt;/span&gt;::utils::span_lint;

&lt;span style=&#34;color:#e6db74&#34;&gt;/// **What it does:** Checks for the `get_` prefix on getters.
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// **Why is this bad?** The Rust API Guidelines section on naming
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// [specifies](https://rust-lang-nursery.github.io/api-guidelines/naming.html#getter-names-follow-rust-convention-c-getter)
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// that the `get_` prefix is not used for getters in Rust code unless
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// there is a single and obvious thing that could reasonably be gotten by
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// a getter.
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// The exceptions to this naming convention are as follows:
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// - `get` (such as in
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///   [`std::cell::Cell::get`](https://doc.rust-lang.org/std/cell/struct.Cell.html#method.get))
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// - `get_mut`
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// - `get_unchecked`
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// - `get_unchecked_mut`
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// - `get_ref`
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// **Known problems:** None.
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// **Example:**
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// ```rust
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// // Bad
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// impl B {
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///     fn get_id(&amp;amp;self) -&amp;gt; usize {
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///         ..
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///     }
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// }
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// // Good
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// impl G {
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///     fn id(&amp;amp;self) -&amp;gt; usize {
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///         ..
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///     }
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// }
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// // Also allowed
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// impl A {
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///     fn get(&amp;amp;self) -&amp;gt; usize {
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///         ..
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;///     }
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// }
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/// ```
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&lt;/span&gt;declare_clippy_lint&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt; {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; GETTER_PREFIX,
    style,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;prefixing a getter with `get_`, which does not follow convention&amp;#34;&lt;/span&gt;
}

&lt;span style=&#34;color:#75715e&#34;&gt;#[derive(Copy, Clone)]&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;GetterPrefix&lt;/span&gt;;

&lt;span style=&#34;color:#75715e&#34;&gt;#[rustfmt::skip]&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; ALLOWED_METHOD_NAMES: [&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&amp;#39;static &lt;span style=&#34;color:#66d9ef&#34;&gt;str&lt;/span&gt;; &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_mut&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_unchecked&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_unchecked_mut&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_ref&amp;#34;&lt;/span&gt;
];

&lt;span style=&#34;color:#66d9ef&#34;&gt;impl&lt;/span&gt; LintPass &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; GetterPrefix {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_lints&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;self) -&amp;gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;LintArray&lt;/span&gt; {
        lint_array&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;(GETTER_PREFIX)
    }
}

&lt;span style=&#34;color:#66d9ef&#34;&gt;impl&lt;/span&gt; EarlyLintPass &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; GetterPrefix {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;check_impl_item&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;mut&lt;/span&gt; self, cx: &lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;EarlyContext&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;&amp;#39;_&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;, implitem: &lt;span style=&#34;color:#66d9ef&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ast&lt;/span&gt;::ImplItem) {
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; ast::ImplItemKind::Method(..) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; implitem.node {
            &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; implitem.ident.name.as_str().get();
            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; name.starts_with(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get_&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;ALLOWED_METHOD_NAMES.contains(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;name) {
                span_lint(
                    cx,
                    GETTER_PREFIX,
                    implitem.span,
                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;prefixing a getter with `get_` does not follow naming conventions&amp;#34;&lt;/span&gt;,
                );
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the basic lint functionality was completed, I wanted to open a pull request against &lt;a href=&#34;https://github.com/rust-lang/rust-clippy&#34;&gt;rust-lang/rust-clippy&lt;/a&gt; as soon as possible.
This is my first time writing a lint for &lt;code&gt;clippy&lt;/code&gt;, so I wanted to start getting feedback from other &lt;code&gt;clippy&lt;/code&gt; developers and incorporate their suggestions to improve the lint code as well as my understanding of how &lt;code&gt;clippy&lt;/code&gt; works.
Once I got the lint working I also realized there were a number of decisions to be made where I did not have enough Rust ecosystem or &lt;code&gt;clippy&lt;/code&gt;-specific knowledge to answer, so opening a pull request would be a great way to get those questions answered within the context of the code I had written for the lint.&lt;/p&gt;
&lt;p&gt;My pull request for this getter prefix name lint can be found at &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/pull/3616&#34;&gt;rust-lang/rust-clippy#3616&lt;/a&gt; which details the current state of the lint implementation and its progress getting merged into &lt;code&gt;clippy&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There is still some work to be done before I feel confident this lint can be merged.
First, I need to go through &lt;code&gt;clippy&lt;/code&gt; more thoroughly and identify existing lints that need to be changed to pass the newly introduced lint; resolving the error I identified in &lt;a href=&#34;#step-ten-linting-clippy-with-local-changes&#34;&gt;Step Ten&lt;/a&gt; should get me well on the way to achieving this.&lt;/p&gt;
&lt;p&gt;I would also like to implement some machine-applicable renaming suggestions that would remove the &lt;code&gt;get_&lt;/code&gt; prefix from method names so that functions that fail to meet this Rust API naming convention can be automatically fixed by &lt;code&gt;rustfix&lt;/code&gt;.
I&amp;rsquo;m looking into the mechanisms &lt;code&gt;clippy&lt;/code&gt; provides to make these kinds of suggestions, and &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/utils/mod.rs#L679&#34;&gt;&lt;code&gt;span_lint_and_sugg&lt;/code&gt;&lt;/a&gt; looks like a likely candidate for teaching &lt;code&gt;rustfix&lt;/code&gt; about these renaming rules.&lt;/p&gt;
&lt;p&gt;Lastly I will of course need to implement the feedback on the pull request from other &lt;code&gt;clippy&lt;/code&gt; developers so the lint will be accepted for inclusion in &lt;code&gt;clippy&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m really glad I was able to write this lint for &lt;code&gt;clippy&lt;/code&gt;.
I had found the original issue, &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/issues/1673&#34;&gt;rust-lang/rust-clippy#1673&lt;/a&gt;, back in October 2018 and thought it was the perfect size for getting my feet wet writing a lint.
Some parts of implementing this lint turned out to be more difficult than I had anticipated, most notably around the sparseness or complete lack of &lt;code&gt;rustc&lt;/code&gt; internals documentation which was surprising given the Rust community&amp;rsquo;s focus on writing documentation and the generally high quality documentation available across the ecosystem, but a little trial and error and some &lt;code&gt;println!&lt;/code&gt; debugging pointed me in the right direction in the end.&lt;/p&gt;
&lt;p&gt;A special thanks to &lt;a href=&#34;https://manishearth.github.io/&#34;&gt;Manish Goregaokar&lt;/a&gt;, &lt;a href=&#34;https://github.com/flip1995&#34;&gt;Philipp Krones&lt;/a&gt;, &lt;a href=&#34;https://github.com/matthiaskrgr&#34;&gt;Matthias Krüger&lt;/a&gt;, and &lt;a href=&#34;https://github.com/hcpl&#34;&gt;hcpl&lt;/a&gt; for their input, feedback, and help at various points throughout this process, and &lt;a href=&#34;https://llogiq.github.io/&#34;&gt;llogiq&lt;/a&gt; for their blog post on &lt;a href=&#34;https://llogiq.github.io/2015/06/04/workflows.html&#34;&gt;writing &lt;code&gt;clippy&lt;/code&gt; lints&lt;/a&gt; which was very helpful in finding my way to a working lint implementation.&lt;/p&gt;
&lt;p&gt;There is a particular quote by Charles H. Spurgeon that I tend to associate with new years and new beginnings: &amp;ldquo;Begin as you mean to go on, and go on as you began&amp;rdquo;.
The way that I began 2019 was writing Rust code, and I fully intend to go on writing Rust code for the rest of 2019 and beyond.
I think that&amp;rsquo;s a worth-while New Year&amp;rsquo;s resolution, don&amp;rsquo;t you?&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Yak Shaving in F♭</title>
      <link>https://stuartcrust.com/2018/12/yak-shaving-in-f/</link>
      <pubDate>Thu, 06 Dec 2018 00:00:00 -0500</pubDate>
      
      <guid>https://stuartcrust.com/2018/12/yak-shaving-in-f/</guid>
      <description>&lt;p&gt;Following on from my &lt;a href=&#34;https://stuartcrust.com/2018/11/i-see-you-are-writing-some-rust&#34;&gt;introduction to &lt;code&gt;clippy&lt;/code&gt; lints&lt;/a&gt;, this week I am beginning my journey of actually implementing a &lt;code&gt;clippy&lt;/code&gt; lint.&lt;/p&gt;
&lt;p&gt;As a refresher, I am implementing &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/issues/1673&#34;&gt;&lt;code&gt;rust-lang/rust-clippy#1673&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To summarize, if the type has a &lt;code&gt;get_foo&lt;/code&gt; method we should suggest naming it &lt;code&gt;foo&lt;/code&gt; instead to follow the API Guidelines for &lt;a href=&#34;https://rust-lang-nursery.github.io/api-guidelines/naming.html#c-getter&#34;&gt;Rust getter name conventions&lt;/a&gt; &lt;em&gt;except&lt;/em&gt; for cases of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;get&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_mut&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_unchecked&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_unchecked_mut&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_ref&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This should be enough to get me started on a style lint for this convention, I should have some time over the next couple days to start digging into this.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;clippys-author-lint&#34;&gt;&lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s Author Lint&lt;/h2&gt;
&lt;p&gt;In typical TDD fashion, I want to start with the test case, the code I want to lint against, so I can test my implementation and drive design.
I&amp;rsquo;ve started off with the simple case of detecting the invalid style rather than worrying about whitelisting the exceptions identified.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MyStruct&lt;/span&gt; {
    id: &lt;span style=&#34;color:#66d9ef&#34;&gt;u32&lt;/span&gt;
}

&lt;span style=&#34;color:#66d9ef&#34;&gt;impl&lt;/span&gt; MyStruct {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_id&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;self) -&amp;gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;u32&lt;/span&gt; {
        self.id
    }
}

&lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {
   &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; s &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; MyStruct { id: &lt;span style=&#34;color:#ae81ff&#34;&gt;42&lt;/span&gt; };

   &lt;span style=&#34;color:#75715e&#34;&gt;#[clippy::author]&lt;/span&gt;
   &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; id &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; s.get_id();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ve also added the &lt;code&gt;#[clippy::author]&lt;/code&gt; annotation as &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md#author-lint&#34;&gt;suggested by &lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s contributing documentation&lt;/a&gt; to generate a starting point for the lint.&lt;/p&gt;
&lt;p&gt;Next, I have to run the test to produce a &lt;code&gt;.stdout&lt;/code&gt; file with the code generated by the &lt;code&gt;#[clippy::author]&lt;/code&gt; lint. The instructions say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If the command was executed successfully, you can copy the code over to where you are implementing your lint.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&amp;rsquo;s try it out:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;$ TESTNAME=ui/getter_prefix cargo test --test compile-test
    Finished dev [unoptimized + debuginfo] target(s) in 0.15s
     Running target/debug/deps/compile_test-f89d0316ceade355

running 1 test

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 29 filtered out


running 1 test
test [ui] ui/getter_prefix.rs ... FAILED

failures:

---- [ui] ui/getter_prefix.rs stdout ----
normalized stdout:
if_chain! {
    if let StmtKind::Decl(ref decl, _) = stmt.node
    if let DeclKind::Local(ref local) = decl.node;
    if let Some(ref init) = local.init
    if let ExprKind::MethodCall(ref method_name, ref generics, ref args) = init.node;
    // unimplemented: `ExprKind::MethodCall` is not further destructured at the moment
    if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.node;
    if name.node.as_str() == &amp;#34;id&amp;#34;;
    then {
        // report your lint here
    }
}


expected stdout:


diff of stdout:

+if_chain! {
+    if let StmtKind::Decl(ref decl, _) = stmt.node
+    if let DeclKind::Local(ref local) = decl.node;
+    if let Some(ref init) = local.init
+    if let ExprKind::MethodCall(ref method_name, ref generics, ref args) = init.node;
+    // unimplemented: `ExprKind::MethodCall` is not further destructured at the moment
+    if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.node;
+    if name.node.as_str() == &amp;#34;id&amp;#34;;
+    then {
+        // report your lint here
+    }
+}
+

The actual stdout differed from the expected stdout.
Actual stdout saved to /Users/scrust/devel/rust-clippy/target/debug/test_build_base/getter_prefix.stdout
To update references, run this command from build directory:
tests/ui/update-references.sh &amp;#39;/Users/scrust/devel/rust-clippy/target/debug/test_build_base&amp;#39; &amp;#39;getter_prefix.rs&amp;#39;

error: 1 errors occurred comparing output.
status: exit code: 0
command: &amp;#34;target/debug/clippy-driver&amp;#34; &amp;#34;tests/ui/getter_prefix.rs&amp;#34; &amp;#34;-L&amp;#34; &amp;#34;/Users/scrust/devel/rust-clippy/target/debug/test_build_base&amp;#34; &amp;#34;--target=x86_64-apple-darwin&amp;#34; &amp;#34;-C&amp;#34; &amp;#34;prefer-dynamic&amp;#34; &amp;#34;-o&amp;#34; &amp;#34;/Users/scrust/devel/rust-clippy/target/debug/test_build_base/getter_prefix.stage-id&amp;#34; &amp;#34;-L&amp;#34; &amp;#34;target/debug&amp;#34; &amp;#34;-L&amp;#34; &amp;#34;target/debug/deps&amp;#34; &amp;#34;-Dwarnings&amp;#34; &amp;#34;-L&amp;#34; &amp;#34;/Users/scrust/devel/rust-clippy/target/debug/test_build_base/getter_prefix.stage-id.aux&amp;#34; &amp;#34;-A&amp;#34; &amp;#34;unused&amp;#34;
stdout:
------------------------------------------
if_chain! {
    if let StmtKind::Decl(ref decl, _) = stmt.node
    if let DeclKind::Local(ref local) = decl.node;
    if let Some(ref init) = local.init
    if let ExprKind::MethodCall(ref method_name, ref generics, ref args) = init.node;
    // unimplemented: `ExprKind::MethodCall` is not further destructured at the moment
    if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.node;
    if name.node.as_str() == &amp;#34;id&amp;#34;;
    then {
        // report your lint here
    }
}

------------------------------------------
stderr:
------------------------------------------

------------------------------------------

thread &amp;#39;[ui] ui/getter_prefix.rs&amp;#39; panicked at &amp;#39;explicit panic&amp;#39;, /Users/scrust/.cargo/registry/src/github.com-1ecc6299db9ec823/compiletest_rs-0.3.17/src/runtest.rs:2553:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.


failures:
    [ui] ui/getter_prefix.rs

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 225 filtered out

test compile_test ... FAILED

failures:

---- compile_test stdout ----
thread &amp;#39;compile_test&amp;#39; panicked at &amp;#39;Some tests failed&amp;#39;, /Users/scrust/.cargo/registry/src/github.com-1ecc6299db9ec823/compiletest_rs-0.3.17/src/lib.rs:89:22


failures:
    compile_test

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass &amp;#39;--test compile-test&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Wow that&amp;rsquo;s a lot out output.
More importantly, I don&amp;rsquo;t actually know if it worked.
I see&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 29 filtered out
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;but then I see&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;The actual stdout differed from the expected stdout.
Actual stdout saved to /Users/scrust/devel/rust-clippy/target/debug/test_build_base/getter_prefix.stdout
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 225 filtered out

test compile_test ... FAILED
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I also don&amp;rsquo;t see any generated &lt;code&gt;.stdout&lt;/code&gt; file, so I&amp;rsquo;m going to assume there&amp;rsquo;s something wrong with my test case.&lt;/p&gt;
&lt;p&gt;If I remove the author lint tag, I get a different result:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;$ TESTNAME=ui/getter_prefix cargo test --test compile-test
    Finished dev [unoptimized + debuginfo] target(s) in 0.16s
     Running target/debug/deps/compile_test-f89d0316ceade355

running 1 test

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 29 filtered out


running 1 test
test [ui] ui/getter_prefix.rs ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 225 filtered out


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out

test compile_test ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This all seems to pass, but I still don&amp;rsquo;t see a generated &lt;code&gt;.stdout&lt;/code&gt; file, and I&amp;rsquo;ve also lost any output the &lt;code&gt;#[clippy:author]&lt;/code&gt; annotation would have given me.&lt;/p&gt;
&lt;p&gt;I noticed a line from the earlier, possibly failed, test run:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To update references, run this command from build directory:
tests/ui/update-references.sh &amp;lsquo;/Users/scrust/devel/rust-clippy/target/debug/test_build_base&amp;rsquo; &amp;lsquo;getter_prefix.rs&amp;rsquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What does this do?
What&amp;rsquo;s a &amp;ldquo;reference&amp;rdquo;?
&lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s documentation doesn&amp;rsquo;t seem to mention &lt;code&gt;tests/ui/update-references.sh&lt;/code&gt; at all, though there is a mention of &lt;code&gt;tests/ui/update-all-references.sh&lt;/code&gt; which seems to update all of the existing &lt;code&gt;.stderr&lt;/code&gt; files that drive the UI tests.&lt;/p&gt;
&lt;p&gt;It turns out that running &lt;code&gt;tests/ui/update-references.sh&lt;/code&gt; is necessary to actually write the &lt;code&gt;.stdout&lt;/code&gt; file.
I wasn&amp;rsquo;t expecting this extra step because the way the instructions are phrased I though running the test would generate the &lt;code&gt;.stdout&lt;/code&gt; file automatically.
For the test I wrote, &lt;code&gt;#[clippy::author]&lt;/code&gt; generated a &lt;code&gt;.stdout&lt;/code&gt; file with the following code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;if_chain! {
    if let StmtKind::Decl(ref decl, _) = stmt.node
    if let DeclKind::Local(ref local) = decl.node;
    if let Some(ref init) = local.init
    if let ExprKind::MethodCall(ref method_name, ref generics, ref args) = init.node;
    // unimplemented: `ExprKind::MethodCall` is not further destructured at the moment
    if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.node;
    if name.node.as_str() == &amp;#34;id&amp;#34;;
    then {
        // report your lint here
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m not at all familiar with the &lt;code&gt;if_chain!&lt;/code&gt; macro or any of these datatypes, so I definitely have some reading to do so I can understand what this snippet actually does.
I do see &lt;code&gt;if name.node.as_str() == &amp;quot;id&amp;quot;;&lt;/code&gt; which seems to match the &lt;code&gt;id&lt;/code&gt; field on &lt;code&gt;MyStruct&lt;/code&gt; which is about the only piece I understand without delving deeper.&lt;/p&gt;
&lt;p&gt;Out of curiosity after reading a number of other lint tests, I decided to update main and added an assert statement:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {
   &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; s &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; MyStruct { id: &lt;span style=&#34;color:#ae81ff&#34;&gt;42&lt;/span&gt; };

    &lt;span style=&#34;color:#75715e&#34;&gt;#[clippy::author]&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; id &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; s.get_id();

    assert_eq&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;(id, &lt;span style=&#34;color:#ae81ff&#34;&gt;42&lt;/span&gt;);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and got yet another different result:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;$ TESTNAME=ui/getter_prefix cargo test --test compile-test
    Finished dev [unoptimized + debuginfo] target(s) in 0.16s
     Running target/debug/deps/compile_test-f89d0316ceade355

running 1 test

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 29 filtered out


running 1 test
test [ui] ui/getter_prefix.rs ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 225 filtered out


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out

test compile_test ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m not sure the &lt;code&gt;#[clippy::author]&lt;/code&gt; annotation is going to help me too much in implementing this lint.
Right now I don&amp;rsquo;t know enough about &lt;code&gt;clippy&lt;/code&gt; or the datatypes it uses to make heads or tails of the generated code, and the results of my test are inconsistent depending on various combinations of &lt;code&gt;assert_eq!&lt;/code&gt; and the author annotation.
This definitely calls for more research, so until next week it looks like I&amp;rsquo;ll be getting to grips with some of &lt;code&gt;rustc&lt;/code&gt;&amp;rsquo;s compiler internals.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>I See You Are Writing Some Rust</title>
      <link>https://stuartcrust.com/2018/11/i-see-you-are-writing-some-rust/</link>
      <pubDate>Sun, 25 Nov 2018 00:00:00 -0500</pubDate>
      
      <guid>https://stuartcrust.com/2018/11/i-see-you-are-writing-some-rust/</guid>
      <description>&lt;h1 id=&#34;would-you-like-some-help-with-that&#34;&gt;Would You Like Some Help With That?&lt;/h1&gt;
&lt;p&gt;In my &lt;a href=&#34;https://stuartcrust.com/2018/11/opinionated-formatting&#34;&gt;last post&lt;/a&gt; I wrote a bit about code linting and code formatting, particularly in more modern programming languages like Rust and Go where such tools come first-class as part of the language&amp;rsquo;s toolchain.
In addition to Rust&amp;rsquo;s &lt;code&gt;rustfmt&lt;/code&gt; tool which formats Rust code according to style guidelines, Rust&amp;rsquo;s ecosystem also has a tool called &lt;code&gt;clippy&lt;/code&gt; which is a much more opinionated tool &amp;ldquo;to catch common mistakes and improve your Rust code.&amp;rdquo;&lt;/p&gt;
&lt;h2 id=&#34;introducing-clippy&#34;&gt;Introducing &lt;code&gt;clippy&lt;/code&gt;&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt; _____________________________________
/ I see you are writing some Rust.    \
\ Would you like some help with that? /
 -------------------------------------
 \
  \
    /  \
    |  |
    @  @
    |  |
    || |/
    || ||
    |\_/|
    \___/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;clippy&lt;/code&gt; currently has &lt;a href=&#34;https://rust-lang.github.io/rust-clippy/master/index.html&#34;&gt;288 lints&lt;/a&gt; to help developers write better Rust code.
The lints are broken down into various categories such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;style: code that should be written in a more idiomatic way (e.g. &lt;code&gt;if x.len() == 0 {...}&lt;/code&gt; could be re-written as &lt;code&gt;if x.is_empty() {...}&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;correctness: code that it outright wrong of very useless (e.g. ensuring syntax when creating regexes)&lt;/li&gt;
&lt;li&gt;complexity: code that is more complex than necessary (e.g. &lt;code&gt;if x == true {...}&lt;/code&gt; could be re-written as &lt;code&gt;if x {...}&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;as well as &lt;a href=&#34;https://github.com/rust-lang/rust-clippy#clippy&#34;&gt;many others&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been interested in contributing to a Rust tooling project since I did my &lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-one/&#34;&gt;initial Rust project overview&lt;/a&gt; as part of &lt;a href=&#34;https://stuartcrust.com/categories/hacktoberfest/&#34;&gt;Hacktoberfest 2018&lt;/a&gt;.
Good tooling is a &lt;a href=&#34;https://en.wikipedia.org/wiki/Force_multiplication&#34;&gt;force multiplier&lt;/a&gt; in software development, and improving tooling - especially tooling that is &amp;ldquo;blessed&amp;rdquo; and supported by the core language team - can reach so many more people than small purpose-built tools set up for individual projects.&lt;/p&gt;
&lt;p&gt;During Hacktoberfest, I ran across &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/issues/1673&#34;&gt;&lt;code&gt;rust-lang/rust-clippy#1673&lt;/code&gt;&lt;/a&gt; but because of the time constraints on Hacktoberfest contributions along with my other coursework I didn&amp;rsquo;t have time to claim the issue.&lt;/p&gt;
&lt;p&gt;The full issue is as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is not idiomatic in Rust to have setters and getters. Make the field public instead.
If the type only has a &lt;code&gt;get_foo&lt;/code&gt; method but not a &lt;code&gt;set_foo&lt;/code&gt; method, suggest naming it &lt;code&gt;foo&lt;/code&gt; instead.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This seemed like a relatively simple lint to implement which would hopefully introduce me to a number of features &lt;code&gt;clippy&lt;/code&gt; uses when analyzing Rust code and inspecting the representation that the &lt;code&gt;rustc&lt;/code&gt; compiler sees before it generates build artifacts.
Once Hacktoberfest was over and I cleared some work off my plate, I went back and asked if the lint &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/issues/1673#issuecomment-440137309&#34;&gt;was still up for grabs&lt;/a&gt; before I invested the time to attempt an implementation.
&lt;a href=&#34;https://twitter.com/Manishearth&#34;&gt;Manish Goregaokar&lt;/a&gt; of the &lt;a href=&#34;https://www.rust-lang.org/en-US/team.html#Dev-tools-team&#34;&gt;Rust dev tools team&lt;/a&gt; got back to me almost immediately:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Actually, I&amp;rsquo;m not sure if this really is valid rust style &amp;ndash; setters and getters may be added to future proof an API, for example.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Manish raised the excellent point that getters and setters are in fact valid Rust style and I agreed, so I thought I was going to have to find another issue to work on and moved to &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/issues/1673#issuecomment-440436914&#34;&gt;close the issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I was worried that I would run into a similar situation with other issues I was interested in working on, so I reached out to Manish directly on the &lt;code&gt;wg-clippy&lt;/code&gt; Discord channel and asked about another issue I was interested in working on:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;@manishearth i was interested in picking up &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/issues/1673&#34;&gt;https://github.com/rust-lang/rust-clippy/issues/1673&lt;/a&gt; but i agree with your comment that it may not be a desirable lint to have&lt;/p&gt;
&lt;p&gt;i&amp;rsquo;m looking at &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/issues/2144&#34;&gt;https://github.com/rust-lang/rust-clippy/issues/2144&lt;/a&gt; now, or if there&amp;rsquo;s another &lt;code&gt;good first issue&lt;/code&gt; that&amp;rsquo;s up for grabs i&amp;rsquo;d definitely be interested in taking a look!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I got a response pretty quickly:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;that seems fine!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;However, activity on the original issue I was interested in had clearly caught some attention, and I got into a discussion with user &lt;a href=&#34;https://github.com/hcpl&#34;&gt;hcpl&lt;/a&gt; about other use cases for the lint, specifically:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If the type only has a &lt;code&gt;get_foo&lt;/code&gt; method but not a &lt;code&gt;set_foo&lt;/code&gt; method, suggest naming it &lt;code&gt;foo&lt;/code&gt; instead.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/issues/1673#issuecomment-440460968&#34;&gt;turned out&lt;/a&gt; that there was already some precedence for this style in the Rust standard library, and the Rust API Guidelines has an &lt;a href=&#34;https://rust-lang-nursery.github.io/api-guidelines/naming.html#c-getter&#34;&gt;entire section&lt;/a&gt; about Rust conventions for getter names. Except for the cases of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;get&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_mut&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_unchecked&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_unchecked_mut&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_ref&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;which have some special meanings in Rust related to &lt;a href=&#34;https://doc.rust-lang.org/book/second-edition/ch03-01-variables-and-mutability.html&#34;&gt;data mutability&lt;/a&gt;, references, or &lt;a href=&#34;https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html&#34;&gt;unsafe code&lt;/a&gt;, the &lt;code&gt;get_&lt;/code&gt; prefix is not generally used in Rust.
Searching for these exceptions also turned up an &lt;a href=&#34;https://github.com/rust-lang/rust/issues/27745&#34;&gt;unstable feature relating to &lt;code&gt;TypeId&lt;/code&gt;&lt;/a&gt; to support &lt;a href=&#34;https://en.wikipedia.org/wiki/Reflection_%28computer_programming%29&#34;&gt;reflection&lt;/a&gt; that &lt;em&gt;does&lt;/em&gt; include the &lt;code&gt;get_&lt;/code&gt; prefix even though it&amp;rsquo;s &lt;a href=&#34;https://github.com/rust-lang/rust/issues/27745#issuecomment-138511187&#34;&gt;not supposed to&lt;/a&gt;, which goes to show that implementing this lint could be very valuable to help maintain style even in core Rust projects and the compiler.&lt;/p&gt;
&lt;p&gt;After some good back-and-forth discussion with &lt;a href=&#34;https://github.com/hcpl&#34;&gt;hcpl&lt;/a&gt; and &lt;a href=&#34;https://github.com/flip1995&#34;&gt;Philipp Krones&lt;/a&gt;, I &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/issues/1673#issuecomment-441304062&#34;&gt;summarized the proposed refinements&lt;/a&gt; to the filed issue:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To summarize, if the type has a &lt;code&gt;get_foo&lt;/code&gt; method we should suggest naming it &lt;code&gt;foo&lt;/code&gt; instead to follow the API Guidelines for &lt;a href=&#34;https://rust-lang-nursery.github.io/api-guidelines/naming.html#c-getter&#34;&gt;Rust getter name conventions&lt;/a&gt; &lt;em&gt;except&lt;/em&gt; for cases of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;get&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_mut&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_unchecked&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_unchecked_mut&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_ref&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This should be enough to get me started on a style lint for this convention, I should have some time over the next couple days to start digging into this.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With better clarity on what the lint should implement as well as some known exceptions, I was in a position to start getting the project set up and go through all the steps of onboarding onto a new project.&lt;/p&gt;
&lt;h2 id=&#34;working-on-clippy&#34;&gt;Working on &lt;code&gt;clippy&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;To start implementing the lint, I had to go through all the usual steps of forking and cloning &lt;code&gt;clippy&lt;/code&gt; and making sure I could build the project locally before I could start digging into code.
After cloning the project, I went ahead and tried to build &lt;code&gt;clippy&lt;/code&gt; locally:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;$ cargo --version
cargo 1.32.0-nightly (1fa308820 2018-10-31)

$ cargo build

[snip]

error[E0050]: method `check_pat` has 4 parameters but the declaration in trait `rustc::lint::EarlyLintPass::check_pat` has 3
   --&amp;gt; clippy_lints/src/misc_early.rs:244:66
    |
244 |     fn check_pat(&amp;amp;mut self, cx: &amp;amp;EarlyContext&amp;lt;&amp;#39;_&amp;gt;, pat: &amp;amp;Pat, _: &amp;amp;mut bool) {
    |                                                                  ^^^^^^^^^ expected 3 parameters, found 4
    |
    = note: `check_pat` from trait: `fn(&amp;amp;mut Self, &amp;amp;rustc::lint::EarlyContext&amp;lt;&amp;#39;_&amp;gt;, &amp;amp;syntax::ast::Pat)`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0050`.
error: Could not compile `clippy_lints`.
warning: build failed, waiting for other jobs to finish...
error: build failed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Oops, that&amp;rsquo;s not good.
I knew &lt;code&gt;clippy&lt;/code&gt; relied heavily on features from the &lt;code&gt;nightly&lt;/code&gt; release channel, and, as the name implies, the &lt;code&gt;nightly&lt;/code&gt; channel is released every night with new changes and improvements.
&lt;code&gt;clippy&lt;/code&gt; must be making use of some new feature here and my &lt;code&gt;nightly&lt;/code&gt; Rust is out of date.
I updated Rust with &lt;code&gt;rustup&lt;/code&gt; and then tried again to build &lt;code&gt;clippy&lt;/code&gt; locally:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;$ rustup update

[snip]

nightly-x86_64-apple-darwin updated - rustc 1.32.0-nightly (5aff30734 2018-11-19)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;$ cargo --version
cargo 1.32.0-nightly (b3d0b2e54 2018-11-15)

$ cargo build

[snip]

Finished dev [unoptimized + debuginfo] target(s) in 2m 03s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now that I knew I really had to watch the versions and make sure everything was up to date, I was ready to start thinking about implementing the lint.&lt;/p&gt;
&lt;h3 id=&#34;a-few-days-later&#34;&gt;A Few Days Later&amp;hellip;&lt;/h3&gt;
&lt;p&gt;A challenge that I&amp;rsquo;ve been running into working on &lt;code&gt;clippy&lt;/code&gt; is that because it relies so heavily on &lt;code&gt;nightly&lt;/code&gt; compiler features, and both &lt;code&gt;clippy&lt;/code&gt; and &lt;code&gt;nightly&lt;/code&gt; are moving targets, my local &lt;code&gt;clippy&lt;/code&gt; checkout can very quickly get out of date not only from upstream but also from the &lt;code&gt;nightly&lt;/code&gt; release channel.&lt;/p&gt;
&lt;p&gt;For example, I updated everything recently and got:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;$ cargo build

   Compiling clippy_lints v0.0.212 (/Users/azure/devel/rust-clippy/clippy_lints)
error[E0615]: attempted to take value of method `abi` on type `rustc_target::abi::Align`
    --&amp;gt; clippy_lints/src/types.rs:1067:93
     |
1067 |                 if let Some(from_align) = cx.layout_of(from_ptr_ty.ty).ok().map(|a| a.align.abi);
     |                                                                                             ^^^
     |
     = help: maybe a `()` to call it is missing?

error[E0615]: attempted to take value of method `abi` on type `rustc_target::abi::Align`
    --&amp;gt; clippy_lints/src/types.rs:1068:89
     |
1068 |                 if let Some(to_align) = cx.layout_of(to_ptr_ty.ty).ok().map(|a| a.align.abi);
     |                                                                                         ^^^
     |
     = help: maybe a `()` to call it is missing?

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0615`.
error: Could not compile `clippy_lints`.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which is the change introduced in &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/pull/3452&#34;&gt;rust-lang/rust-clippy#3452&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For whatever reason, even after updating Rust and using the same tool versions as in &lt;a href=&#34;https://travis-ci.org/rust-lang/rust-clippy/builds/458715770&#34;&gt;this passing test&lt;/a&gt; for the above pull request the project does not build locally.
Luckily reverting back to &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/pull/3449&#34;&gt;&lt;code&gt;61501b2810d887367d360025398dd9280c4bcd8b&lt;/code&gt;&lt;/a&gt; lets me compile the project so I can continue working without getting &lt;em&gt;too&lt;/em&gt; out of date with upstream, but there&amp;rsquo;s a lot of churn and things often break for unexplained reasons.&lt;/p&gt;
&lt;p&gt;I reached out to &lt;a href=&#34;https://github.com/matthiaskrgr&#34;&gt;Matthias Krüger&lt;/a&gt;, the original author of &lt;code&gt;#3453&lt;/code&gt;, on the &lt;code&gt;wg-rust&lt;/code&gt; Discord channel to find out what was going on.
It turns out that sometimes even the &lt;code&gt;nightly&lt;/code&gt; release channel isn&amp;rsquo;t &lt;a href=&#34;https://en.wikipedia.org/wiki/Bleeding_edge_technology&#34;&gt;bleeding-edge&lt;/a&gt; enough to work on &lt;code&gt;clippy&lt;/code&gt; lints and a tool called &lt;a href=&#34;https://github.com/kennytm/rustup-toolchain-install-master&#34;&gt;&lt;code&gt;rustup-toolchain-install-master&lt;/code&gt;&lt;/a&gt; is necessary to install compiler artifacts directly from Rust&amp;rsquo;s continuous integration pipeline that haven&amp;rsquo;t even been published to the &lt;code&gt;nightly&lt;/code&gt; channel yet.
This information is also documented in &lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md#fixing-build-failures-caused-by-rust&#34;&gt;&lt;code&gt;CONTRIBUTING.MD&lt;/code&gt; file&lt;/a&gt;, but it&amp;rsquo;s located at almost the bottom of the document which is why I hadn&amp;rsquo;t run across the information earlier.
It is very true that it pays to read the documentation, and in many other projects asking a question about why my local build was failing in this way would receive comments to &amp;ldquo;&lt;a href=&#34;https://en.wikipedia.org/wiki/RTFM&#34;&gt;RTFM&lt;/a&gt;&amp;rdquo;.
However, my experiences in the Rust community have been nothing but positive, everyone I have interacted with has been very helpful, and even &amp;ldquo;big names&amp;rdquo; in the community are accessible and directly engaged in projects and contributor mentorship.&lt;/p&gt;
&lt;h2 id=&#34;to-be-continued&#34;&gt;To Be Continued&amp;hellip;&lt;/h2&gt;
&lt;p&gt;This week was all about finding my footing and getting my local environment set up to actually do development work on &lt;code&gt;clippy&lt;/code&gt;.
In the coming weeks I&amp;rsquo;ll tackle actually implementing the lint now that the requirements and goals have been fleshed out, and I hope to have something up for code review soon to get community feedback on improving the lint and catching anything I&amp;rsquo;ve missed.&lt;/p&gt;
&lt;p&gt;First up: reading &lt;a href=&#34;https://twitter.com/llogiq&#34;&gt;llogiq&lt;/a&gt;&amp;rsquo;s blogpost on &lt;a href=&#34;https://llogiq.github.io/2015/06/04/workflows.html&#34;&gt;writing &lt;code&gt;clippy&lt;/code&gt; lints&lt;/a&gt;.
Then I&amp;rsquo;ll create a starting point for my lint with &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md#author-lint&#34;&gt;&lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s internal &lt;code&gt;author&lt;/code&gt; lint&lt;/a&gt; as well as reading some &lt;a href=&#34;https://github.com/rust-lang/rust-clippy/tree/master/clippy_lints/src&#34;&gt;existing lints&lt;/a&gt; to get a general idea of lint structure.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Opinionated Formatting</title>
      <link>https://stuartcrust.com/2018/11/opinionated-formatting/</link>
      <pubDate>Sun, 18 Nov 2018 00:00:00 -0500</pubDate>
      
      <guid>https://stuartcrust.com/2018/11/opinionated-formatting/</guid>
      <description>&lt;p&gt;This week in class we talked about code linting and code formatting using &lt;a href=&#34;https://eslint.org/&#34;&gt;ESLint&lt;/a&gt; and &lt;a href=&#34;https://prettier.io/&#34;&gt;Prettier&lt;/a&gt;.
These kinds of tools automate a lot of the otherwise labour-intensive and easy-to-miss nitpicks reviewers often leave on pull requests, freeing up time to review much more important elements such as design and code structure.
Many tech companies - &lt;a href=&#34;https://google.github.io/styleguide/&#34;&gt;Google&lt;/a&gt;, &lt;a href=&#34;http://airbnb.io/javascript/&#34;&gt;AirBnB&lt;/a&gt;, &lt;a href=&#34;https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions&#34;&gt;Microsoft&lt;/a&gt; to name a few - have their own code style guides, much in the same way that writing organizations (&lt;a href=&#34;https://www.bbc.co.uk/academy/en/collections/news-style-guide&#34;&gt;news organizations&lt;/a&gt; and &lt;a href=&#34;https://www.apastyle.org/&#34;&gt;scientific publishing&lt;/a&gt;, for example) have documents that outline how to maintain consistency in publications across many hundreds of outlets and thousands of writers, and the idea of a style guide is not new.
However, the idea of automating this style checking to help developers maintain a consistent style has gained a lot more traction in recent years thanks in part to style and formatting tools coming standard and enabled by default in many modern programming languages.&lt;/p&gt;
&lt;h2 id=&#34;formatting-as-a-first-class-tool&#34;&gt;Formatting as a First-Class Tool&lt;/h2&gt;
&lt;p&gt;I was first exposed to this idea of a universal formatter as part of a language&amp;rsquo;s toolchain when I started experimenting with &lt;a href=&#34;https://golang.org/&#34;&gt;Go&lt;/a&gt;.
Go&amp;rsquo;s &lt;a href=&#34;https://golang.org/cmd/gofmt/&#34;&gt;&lt;code&gt;gofmt&lt;/code&gt;&lt;/a&gt; enforces a consistent style not just within one project, but across the &lt;em&gt;entire&lt;/em&gt; ecosystem of Go code, making even foreign codebases more accessible because of their consistent style.
This consistency helps to reduce visual noise, making it easier to focus on what the code says rather than how it&amp;rsquo;s formatted.
This idea of a universal formatter appears in other languages like &lt;a href=&#34;https://www.rust-lang.org&#34;&gt;Rust&lt;/a&gt;&amp;rsquo;s own &lt;a href=&#34;https://github.com/rust-lang-nursery/rustfmt&#34;&gt;&lt;code&gt;rustfmt&lt;/code&gt;&lt;/a&gt;, though there are many other tools for enforcing style that predate these tools, such as &lt;a href=&#34;https://rubocop.org/&#34;&gt;rubocop&lt;/a&gt; for Ruby and &lt;a href=&#34;http://astyle.sourceforge.net/&#34;&gt;astyle&lt;/a&gt; for C and C++.&lt;/p&gt;
&lt;p&gt;In Go and Rust, these formatters increase productivity dramatically because as long as you write syntactically correct code, it can be the ugliest code you have ever written and by passing it through the formatter (and many editors and IDEs will even format the source for you when you save!) you can leave it up to the formatter to make the code pretty and readable.
This means less time fiddling with alignment, worrying about indentation, and dithering over where to break your function call chain to best communicate your intent.
It also means that wars over format like &lt;a href=&#34;https://www.businessinsider.com/tabs-vs-spaces-from-silicon-valley-2016-5&#34;&gt;tabs versus spaces&lt;/a&gt; are dead; the formatter is the absolute arbitrator of the correct style, and because the formatter is consistent across the entire ecosystem there is a lot of pressure for users to conform instead of trying to tweak the formatter to their own personal preferences.&lt;/p&gt;
&lt;p&gt;We still have an &lt;a href=&#34;https://github.com/0xazure/supernova/issues/21&#34;&gt;open issue&lt;/a&gt; on &lt;code&gt;supernova&lt;/code&gt; for implementing &lt;code&gt;rustfmt&lt;/code&gt; as part of our continuous integration process that we hope to close out with a pull request relatively soon so we can be sure all the code contributed to &lt;code&gt;supernova&lt;/code&gt; follows the same format as other projects.&lt;/p&gt;
&lt;h2 id=&#34;build-infrastructure-weirdness&#34;&gt;Build Infrastructure Weirdness&lt;/h2&gt;
&lt;p&gt;Speaking of our continuous integration process, we ran into a very curious issue with &lt;a href=&#34;https://github.com/0xazure/supernova/pull/24&#34;&gt;&lt;code&gt;0xazure/supernova#24&lt;/code&gt;&lt;/a&gt; this week where our builds started failing on the &lt;code&gt;beta&lt;/code&gt; release channel.
The build failure is caused by &lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s &lt;a href=&#34;https://rust-lang-nursery.github.io/rust-clippy/current/index.html#new_ret_no_self&#34;&gt;&lt;code&gt;new_ret_no_self&lt;/code&gt; lint&lt;/a&gt; which checks to ensure that, as a convention, &lt;code&gt;new&lt;/code&gt; methods are used to make a new instance of a type and return that instance as the return value.
In the issue, the build is only failing on the &lt;code&gt;beta&lt;/code&gt; release channel which was surprising because I was expecting this lint to have failed the build on the &lt;code&gt;stable&lt;/code&gt; release channel as well if it failed on &lt;code&gt;beta&lt;/code&gt;.
To further confuse the issue the build on &lt;code&gt;nightly&lt;/code&gt;, which per our configuration for &lt;code&gt;supernova&lt;/code&gt; is allowed to fail, was successful.&lt;/p&gt;
&lt;p&gt;Digging into the problem some more, it looks like we are running into &lt;a href=&#34;https://github.com/rust-lang-nursery/rust-clippy/issues/3313&#34;&gt;&lt;code&gt;rust-lang-nursery/rust-clippy#3313&lt;/code&gt;&lt;/a&gt; where the &lt;code&gt;new_ret_no_self&lt;/code&gt; lint is incorrectly triggering on a &lt;code&gt;new&lt;/code&gt; function that &lt;em&gt;does&lt;/em&gt; return &lt;code&gt;Self&lt;/code&gt;, it&amp;rsquo;s just wrapped by a container type or tuple.&lt;/p&gt;
&lt;p&gt;Indeed, we can see this from our implementation of &lt;code&gt;Config::new&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;new&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;mut&lt;/span&gt; args: &lt;span style=&#34;color:#a6e22e&#34;&gt;env&lt;/span&gt;::Args) -&amp;gt; Result&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;Config, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&amp;#39;static &lt;span style=&#34;color:#66d9ef&#34;&gt;str&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; {
    args.next();

    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; username &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;match&lt;/span&gt; args.next() {
        None &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; Err(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;No username provided&amp;#34;&lt;/span&gt;),
        Some(arg) &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; arg,
    };

    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; token &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; args.next();

    Ok(Config { username, token })
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which triggers the resulting lint failure&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;error: methods called `new` usually return `Self`
  --&amp;gt; src/lib.rs:18:5
   |
18 | /     pub fn new(mut args: env::Args) -&amp;gt; Result&amp;lt;Config, &amp;amp;&amp;#39;static str&amp;gt; {
19 | |         args.next();
20 | |
21 | |         let username = match args.next() {
...  |
28 | |         Ok(Config { username, token })
29 | |     }
   | |_____^
   |
   = note: `-D clippy::new-ret-no-self` implied by `-D warnings`
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#new_ret_no_self
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;even though our return type is &lt;code&gt;Result&amp;lt;Config, &amp;amp;&#39;static str&amp;gt;&lt;/code&gt; which unwraps to &lt;code&gt;Config&lt;/code&gt; on success and a &lt;code&gt;static str&lt;/code&gt; when there is an error in creating a new instance.&lt;/p&gt;
&lt;h2 id=&#34;investigating-the-root-cause&#34;&gt;Investigating the Root Cause&lt;/h2&gt;
&lt;p&gt;An important part of build infrastructure is reproducibility: the ability to run a build with the same inputs and get the same outputs.
Without reproducibility we have flaky tests that no one wants to run and worse, no one trusts.
In the case of &lt;code&gt;supernova&lt;/code&gt; we have a build matrix to test on all three release channels: &lt;code&gt;stable&lt;/code&gt;, &lt;code&gt;beta&lt;/code&gt;, and &lt;code&gt;nightly&lt;/code&gt;, and we need to make sure testing on these channels happens in a predictable way.&lt;/p&gt;
&lt;p&gt;It turns out the issue results from how &lt;code&gt;clippy&lt;/code&gt; is installed in each environment.
The recommended way to install &lt;code&gt;clippy&lt;/code&gt; is as a &lt;code&gt;rustup&lt;/code&gt; component using &lt;code&gt;rustup component add clippy-preview&lt;/code&gt;.
However, because &lt;code&gt;clippy&lt;/code&gt; is published as a component for &lt;code&gt;rustup&lt;/code&gt; rather than as some kind of version-pinned project dependency, this command does not install the same version of &lt;code&gt;clippy&lt;/code&gt; across all release channels.
This can be verified as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;$ cargo +stable clippy --version
clippy 0.0.212 (125907ad 2018-09-17)

$ cargo +beta clippy --version
clippy 0.0.212 (b1d03437 2018-10-19)

$ cargo +nightly clippy --version
clippy 0.0.212 (d8b42690 2018-11-04)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that while all of the build numbers are the same (&lt;code&gt;v0.0.212&lt;/code&gt;), the commit hashes and dates are all different.&lt;/p&gt;
&lt;p&gt;It is important to verify that the tool(s) you&amp;rsquo;re using to test or lint your project are the same version in &lt;strong&gt;all&lt;/strong&gt; of your environments, otherwise you&amp;rsquo;ll end up with confusing build failures like the one we did here.
In our case we are testing against &lt;code&gt;beta&lt;/code&gt; and &lt;code&gt;nightly&lt;/code&gt; to have an idea of future changes to the Rust compiler and any new lints that may get added in the future, so failures on anything but &lt;code&gt;stable&lt;/code&gt; are nice-to-have information rather than complete show-stoppers.
In other cases, or in different matrices, it&amp;rsquo;s even more important that the test environment is as consistent as possible and that the number of variables that &lt;em&gt;are&lt;/em&gt; being changed are as small as possible to make tracing failures relatively simple.&lt;/p&gt;
&lt;p&gt;Lint tools are great for catching low-hanging fruit in code review, but you can&amp;rsquo;t blindly trust them.
When there &lt;em&gt;is&lt;/em&gt; a failure, it takes a person&amp;rsquo;s knowledge of the project to determine if the failure is legitimate or if there&amp;rsquo;s a problem in the tool or lint rule and to determine if it&amp;rsquo;s a problem with the submitted code, a problem with the tool configuration, or a false positive in the tool as in this case with &lt;code&gt;clippy&lt;/code&gt;&amp;rsquo;s &lt;code&gt;new_ret_no_self&lt;/code&gt; lint.&lt;/p&gt;
&lt;h2 id=&#34;fixing-the-problem&#34;&gt;Fixing the Problem&lt;/h2&gt;
&lt;p&gt;After &lt;a href=&#34;https://github.com/0xazure/supernova/pull/24#issuecomment-437530272&#34;&gt;reaching out to some friends&lt;/a&gt; in the &lt;code&gt;#rust&lt;/code&gt; IRC channel, we decided to &lt;a href=&#34;https://github.com/0xazure/supernova/pull/27&#34;&gt;not run &lt;code&gt;clippy&lt;/code&gt; on the &lt;code&gt;beta&lt;/code&gt; toolchain&lt;/a&gt; to avoid more false positives like this in the future.
We are keeping &lt;code&gt;clippy&lt;/code&gt; enabled for the &lt;code&gt;nightly&lt;/code&gt; release channel because we are allowing &lt;code&gt;nightly&lt;/code&gt; to fail on Travis so while we will investigate those failures it will not block landing any pull requests if for some reason &lt;code&gt;nightly&lt;/code&gt; or &lt;code&gt;clippy&lt;/code&gt; on &lt;code&gt;nightly&lt;/code&gt; finds fault with our code.&lt;/p&gt;
&lt;p&gt;I also recently filed &lt;a href=&#34;https://github.com/0xazure/supernova/issues/32&#34;&gt;&lt;code&gt;0xazure/supernova#32&lt;/code&gt;&lt;/a&gt; to provide better visibility into the versions of tools we install to match how Travis prints out tooling versions for tools that come automatically installed with the Rust build environment.
This should help us track down version discrepancies and make trouble-shooting failures much quicker.&lt;/p&gt;
&lt;p&gt;After landing the above fix (and &lt;a href=&#34;https://github.com/0xazure/supernova/pull/30&#34;&gt;an extra tweak&lt;/a&gt; so we only run Travis against the &lt;code&gt;master&lt;/code&gt; branch), our builds went fully green &lt;a href=&#34;https://travis-ci.org/0xazure/supernova/builds/455179153&#34;&gt;for the first time&lt;/a&gt; since we enabled Travis on the project!
Setting up automated builds can take a lot of up-front effort, but it pays big dividends as the project grows to ensure the quality of the software being written.
Now we just &lt;a href=&#34;https://github.com/0xazure/supernova/issues/8&#34;&gt;need some tests&lt;/a&gt; so we can verify our code is actually correct&amp;hellip;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Improving CLI Ergonomics</title>
      <link>https://stuartcrust.com/2018/11/improving-cli-ergonomics/</link>
      <pubDate>Sun, 11 Nov 2018 00:00:00 -0500</pubDate>
      
      <guid>https://stuartcrust.com/2018/11/improving-cli-ergonomics/</guid>
      <description>&lt;p&gt;In my day-to-day, I use &lt;em&gt;a lot&lt;/em&gt; of command-line tools.
I generally find myself to be much more productive working in a non-GUI environment, mostly down to the fact that I can type much faster than I can move and aim a mouse and the less time I spend switching between keyboard and mouse the more time I can spend typing.
Unfortunately, command-line tools have one major drawback: discoverability.
If I am given a GUI application, I can click around, hover over different UI elements, and generally get a feel for how the interface is laid out.
In a command-line tool, I don&amp;rsquo;t have any of these visual cues to help me learn the functionality; I have to start typing and see what happens.
To supplement this lack of visual cues, good command-line tools generally have autocomplete snippets for your shell so you can type the command name and start hitting &lt;code&gt;TAB&lt;/code&gt; to see what options are available at a particular time, as well as extensive &lt;code&gt;man&lt;/code&gt; pages that describe all the various options, commands, and any sub-commands (though these &lt;code&gt;man&lt;/code&gt; pages are often extraordinarily verbose and rarely provide useful examples of how the tool is commonly used, so &lt;a href=&#34;https://tldr.sh/&#34;&gt;alternatives such as &lt;code&gt;tldr&lt;/code&gt;&lt;/a&gt; fill this gap).&lt;/p&gt;
&lt;p&gt;I want &lt;a href=&#34;https://github.com/0xazure/supernova&#34;&gt;&lt;code&gt;supernova&lt;/code&gt;&lt;/a&gt; to be a good command-line tool, so I have been thinking about ways to improve discoverability and make the tool easier to use.
A really interesting post by &lt;a href=&#34;https://twitter.com/jdxcode&#34;&gt;Jeff Dickey&lt;/a&gt;, an engineer at Heroku, crossed my timeline recently titled &lt;a href=&#34;https://medium.com/@jdxcode/12-factor-cli-apps-dd3c227a0e46&#34;&gt;12 Factor CLI Apps&lt;/a&gt;
In his post, Jeff provides twelve principles to guide CLI design in a similar fashion to Heroku&amp;rsquo;s original &lt;a href=&#34;https://12factor.net/&#34;&gt;Twelve-Factor App&lt;/a&gt; methodology.
Out of the twelve principles, Principle 2 stood out to me, particularly in the context of &lt;code&gt;supernova&lt;/code&gt;; Jeff suggests to &amp;ldquo;prefer flags to args&amp;rdquo; when designing a CLI.
He says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sometimes args are just fine though when the argument is obvious such as &lt;code&gt;$rm file_to_remove&lt;/code&gt;. A good rule of thumb is 1 type of argument is fine, 2 types are very suspect, and 3 are never good.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This rule of thumb got me thinking about &lt;code&gt;supernova&lt;/code&gt;&amp;rsquo;s current calling convention.
Currently, you would use &lt;code&gt;supernova&lt;/code&gt; like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ supernova &amp;lt;username&amp;gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&amp;lt;auth-token&amp;gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This violates Jeff&amp;rsquo;s rule of thumb because &lt;code&gt;&amp;lt;username&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;auth-token&amp;gt;&lt;/code&gt; are not the same type of argument, and it&amp;rsquo;s arguably even worse because the &lt;code&gt;&amp;lt;auth-token&amp;gt;&lt;/code&gt; is optional here.&lt;/p&gt;
&lt;p&gt;I opened &lt;a href=&#34;https://github.com/0xazure/supernova/issues/16&#34;&gt;&lt;code&gt;0xazure/supernova#16&lt;/code&gt;&lt;/a&gt; to track this problem with our current calling convention.
In it, I suggest using the &lt;a href=&#34;https://crates.io/crates/clap&#34;&gt;clap&lt;/a&gt; crate to improve our CLI and provide the facilities to do command-line argument parsing.&lt;/p&gt;
&lt;h2 id=&#34;introducing-clap&#34;&gt;Introducing Clap&lt;/h2&gt;
&lt;p&gt;Clap is a great crate that makes it super easy to add all kinds of CLI goodies to your command-line tool including auto-generated help, version, and usage information which are all, as Jeff highlights in Principle 1: Great help is essential, important to good CLIs.&lt;/p&gt;
&lt;p&gt;Adding clap to the project would check off Principles 1 &amp;amp; 2, so I went ahead and &lt;a href=&#34;https://github.com/0xazure/supernova/pull/19&#34;&gt;created a pull request&lt;/a&gt; to add clap and improve &lt;code&gt;supernova&lt;/code&gt;&amp;rsquo;s calling convention. All that was necessary was to create a new clap-based &lt;code&gt;App&lt;/code&gt; with the desired arguments and flags, provide good help messages, and set &lt;code&gt;&amp;lt;auth-token&amp;gt;&lt;/code&gt; to be an optional argument.
Having done all that, this is what clap generates, all for 13 lines of code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;$ supernova --help
supernova 0.1.0

USAGE:
    supernova [OPTIONS] &amp;lt;USERNAME&amp;gt;

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -t, --token &amp;lt;TOKEN&amp;gt;    Sets the authentication token for requests to GitHub

ARGS:
    &amp;lt;USERNAME&amp;gt;    The user whose stars to collect
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Clap will print the name as well as the version with every &lt;code&gt;--help&lt;/code&gt; request.
I was a little wary of this at first, because while I definitely want to include this information in my CLI, I also don&amp;rsquo;t want the maintenance burden of having to remember to update the version string in &lt;code&gt;main.rs&lt;/code&gt; every time a new version is published.
However, clap exposes some &lt;a href=&#34;https://docs.rs/clap/2.32.0/clap/#macros&#34;&gt;very handy macros&lt;/a&gt; that make use of environment variables &lt;a href=&#34;https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates&#34;&gt;exported by &lt;code&gt;cargo&lt;/code&gt;&lt;/a&gt; at build time to pull this information out of &lt;code&gt;Cargo.toml&lt;/code&gt;, so these values will always be up to date with the crate&amp;rsquo;s metadata and don&amp;rsquo;t require setting the values in code.&lt;/p&gt;
&lt;p&gt;To actually extract all of the parsed arguments from clap, we call &lt;a href=&#34;https://docs.rs/clap/2.32.0/clap/struct.App.html#method.get_matches&#34;&gt;&lt;code&gt;App::get_matches()&lt;/code&gt;&lt;/a&gt; which produces an &lt;a href=&#34;https://docs.rs/clap/2.32.0/clap/struct.ArgMatches.html&#34;&gt;&lt;code&gt;ArgMatches&lt;/code&gt;&lt;/a&gt; struct we can query for specific arguments by name. Instead of parsing out each argument, I decided to try my hand at implementing the &lt;code&gt;From&lt;/code&gt; trait to convert &lt;code&gt;ArgMatches&lt;/code&gt; into &lt;code&gt;supernova&lt;/code&gt;&amp;rsquo;s &lt;code&gt;Config&lt;/code&gt; type so it can be passed directly to the next function call.&lt;/p&gt;
&lt;h2 id=&#34;traits-in-rust&#34;&gt;Traits in Rust&lt;/h2&gt;
&lt;p&gt;Before I talk about implementing the &lt;code&gt;From&lt;/code&gt; trait, I want to quickly talk about what traits actually are, as well as why I chose to implement &lt;code&gt;From&lt;/code&gt; instead of one of the other conversion traits.&lt;/p&gt;
&lt;p&gt;The Rust Book &lt;a href=&#34;https://doc.rust-lang.org/book/second-edition/ch10-02-traits.html#traits-defining-shared-behavior&#34;&gt;explains traits like this&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A &lt;em&gt;trait&lt;/em&gt; tells the Rust compiler about functionality a particular type has and can share with other types. We can use traits to define shared behavior in an abstract way.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you are familiar with the idea of &lt;em&gt;interfaces&lt;/em&gt; in other languages such as Java or Go, traits are a very similar idea.&lt;/p&gt;
&lt;p&gt;There is an important caveat with traits.
Again, from the Rust Book, &lt;a href=&#34;https://doc.rust-lang.org/book/second-edition/ch10-02-traits.html#implementing-a-trait-on-a-type&#34;&gt;Chapter 10.2, &lt;em&gt;Implementing a Trait on a Type&lt;/em&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One restriction to note with trait implementations is that we can implement a trait on a type only if either the trait or the type is local to our crate.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This means that I will need to implement my conversion on a type that I control, &lt;code&gt;Config&lt;/code&gt;, to convert between &lt;code&gt;ArgMatches&lt;/code&gt; and &lt;code&gt;Config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The restriction on traits is very interesting, because while it is not necessary in my case it raises the question of how to convert from types that I do control into types defined in the standard library or in other crates.
If I wanted to convert a &lt;code&gt;Config&lt;/code&gt; object into a &lt;code&gt;String&lt;/code&gt; for example, it might make sense to use the conveniently named &lt;a href=&#34;https://doc.rust-lang.org/std/convert/trait.Into.html&#34;&gt;&lt;code&gt;Into&lt;/code&gt; trait&lt;/a&gt;.
However, the documentation for &lt;code&gt;Into&lt;/code&gt; states:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Library authors should not directly implement this trait, but should prefer implementing the &lt;code&gt;From&lt;/code&gt; trait, which offers greater flexibility and provides an equivalent &lt;code&gt;Into&lt;/code&gt; implementation for free, thanks to a blanket implementation in the standard library.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, instead of implementing &lt;code&gt;Into&lt;/code&gt;, I should implement the conversion of &lt;code&gt;Config&lt;/code&gt; &lt;strong&gt;from&lt;/strong&gt; &lt;code&gt;String&lt;/code&gt;, and I get the equivalent &lt;code&gt;Into&lt;/code&gt; implementation for free?
It seems a bit backwards since we are defining a trait that converts in the &lt;em&gt;opposite&lt;/em&gt; direction of our needs, but because of this blanket implementation in the standard library we get symmetric conversions between types for free as long as we implement &lt;code&gt;From&lt;/code&gt; on the type.
That means we only have to write the conversion function once instead of needing to write it once in each direction, and I&amp;rsquo;m definitely in favour of anything that reduces the amount of code I need to write.&lt;/p&gt;
&lt;h2 id=&#34;the-from-trait&#34;&gt;The &lt;code&gt;From&lt;/code&gt; Trait&lt;/h2&gt;
&lt;p&gt;Actually implementing the &lt;code&gt;From&lt;/code&gt; trait was straight-forward, other than the &lt;a href=&#34;https://github.com/0xazure/supernova/pull/19/files#diff-b4aea3e418ccdb71239b96952d9cddb6R27&#34;&gt;necessary addition of a lifetime annotation&lt;/a&gt; because of how &lt;code&gt;ArgMatches&lt;/code&gt; is implemented on clap&amp;rsquo;s side.
Implementing &lt;code&gt;From&lt;/code&gt; also let me replace another method in &lt;code&gt;Config&lt;/code&gt; which reduces the surface area of &lt;code&gt;Config&lt;/code&gt;&amp;rsquo;s implementation.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not totally happy with implementing &lt;code&gt;From&lt;/code&gt; on &lt;code&gt;Config&lt;/code&gt; because I had to pull clap into the library side of &lt;code&gt;supernova&lt;/code&gt; instead of leaving arguments parsing completely in &lt;code&gt;main&lt;/code&gt;, so I may go back and change this implementation to provide better separation between data and arguments parsing.
Or I may decide to move &lt;code&gt;Config&lt;/code&gt; out to its own module which would also increase separation of concerns.
Either way, I was very happy to get my hands back on the keyboard writing Rust code this week, and I hope to be writing more in the near future!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Open Source Level Up: Becoming a Maintainer</title>
      <link>https://stuartcrust.com/2018/11/open-source-level-up-becoming-a-maintainer/</link>
      <pubDate>Sun, 04 Nov 2018 00:00:00 -0400</pubDate>
      
      <guid>https://stuartcrust.com/2018/11/open-source-level-up-becoming-a-maintainer/</guid>
      <description>&lt;p&gt;After a &lt;a href=&#34;https://stuartcrust.com/2018/11/hacktoberfest-a-month-of-open-source&#34;&gt;month of open source&lt;/a&gt; following my &lt;a href=&#34;https://stuartcrust.com/2018/09/a-return-to-open-source&#34;&gt;return to open source&lt;/a&gt;, the next step in my journey is to really immerse myself in one or two projects and start making larger contributions. The open source course I&amp;rsquo;m taking is encouraging us to complete contributions to three &amp;ldquo;external&amp;rdquo; open source projects over the next 5 weeks, as well as make three contributions to &amp;ldquo;internal&amp;rdquo; projects during the same period. In this case, &amp;ldquo;external&amp;rdquo; refers to established projects in the open source community and &amp;ldquo;internal&amp;rdquo; refers to projects we as a class are starting ourselves to get a feel for being core maintainers of a project so we can gain experience on both sides of the process. As a class we had a brainstorming session to come up with ideas for internal projects we could start, and I donated one of my existing side-projects to the list, which has lead to&amp;hellip;&lt;/p&gt;
&lt;h2 id=&#34;level-up&#34;&gt;Level Up!&lt;/h2&gt;
&lt;p&gt;With absolutely zero fanfare, hoops to jump through, or documents to sign, I suddenly became the initial maintainer of one of our course&amp;rsquo;s internal projects. I was able to generate enough interest in my side-project that members of my class wanted to contribute, and the project was added to the official list of internal projects. The amazing thing about open source development is you don&amp;rsquo;t need anyone&amp;rsquo;s permission or to be told to create something; if you have an idea and enough people are interested in using and/or growing that idea, you have an open source project. The project itself grows in a very organic way as people find out about the project and drop in to see what&amp;rsquo;s going on. Some people just drop in and perhaps contribute a little bit or share their use-case for the project, while others get started and then decide to stick around for a long time; that is the nature of open source.&lt;/p&gt;
&lt;h2 id=&#34;supernova&#34;&gt;supernova&lt;/h2&gt;
&lt;p&gt;The project I am maintaining is &lt;a href=&#34;https://github.com/0xazure/supernova&#34;&gt;&lt;code&gt;0xazure/supernova&lt;/code&gt;&lt;/a&gt;, and I would really encourage you to come check us out! We&amp;rsquo;re still in the early stages, but we would encourage any and all to take a look at what we&amp;rsquo;re building, make comments and submit issues or pull requests, and give us feedback. Even though it has been deemed an &amp;ldquo;internal&amp;rdquo; project for the course, we still welcome contributions from anyone who wants to get involved so stop by and &lt;a href=&#34;https://github.com/0xazure/supernova/issues/new&#34;&gt;file an issue&lt;/a&gt; if you have any questions.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;supernova&lt;/code&gt; started out as a learning project for me to improve my understanding of the &lt;a href=&#34;https://www.rust-lang.org&#34;&gt;Rust&lt;/a&gt; programming language, a {,de}serializing library written in Rust called &lt;a href=&#34;https://serde.rs/&#34;&gt;Serde&lt;/a&gt;, and the &lt;a href=&#34;https://developer.github.com/v3/&#34;&gt;GitHub API&lt;/a&gt;. I am a project-oriented learner, so whenever I have some tools and techniques I&amp;rsquo;d like to learn or improve, I start a project that tries to use them so I can have a better understanding of their strengths and weaknesses. The initial implementation as a CLI tool was designed to pull &lt;a href=&#34;https://developer.github.com/v3/activity/starring/#list-repositories-being-starred&#34;&gt;stars data&lt;/a&gt; from the GitHub API and display it in a formatted list. I have a tendency to use stars like I would bookmarks so I have accumulated a lot of stars since I joined GitHub, but I have no great way to view all of my stars in one place (GitHub insists on paginating the list) or export them in various formats. &lt;code&gt;supernova&lt;/code&gt; was only added to the internal projects list a week ago, but we already have &lt;a href=&#34;https://github.com/0xazure/supernova/issues?utf8=%E2%9C%93&amp;amp;q=is%3Aissue+is%3Aopen+created%3A%3C2018-11-04&#34;&gt;a number of open issues&lt;/a&gt; to start growing &lt;code&gt;supernova&lt;/code&gt;&amp;rsquo;s feature set.&lt;/p&gt;
&lt;h2 id=&#34;first-week&#34;&gt;First Week&lt;/h2&gt;
&lt;p&gt;In the first week we&amp;rsquo;ve been focusing on a lot of the low-hanging fruit for a new open source project: setting up the project infrastructure and documenting what we already have.&lt;/p&gt;
&lt;p&gt;There are currently a few open issues for writing docs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/0xazure/supernova/issues/4&#34;&gt;0xazure/supernova#4&lt;/a&gt; - Update the Readme&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/0xazure/supernova/issues/7&#34;&gt;0xazure/supernova#7&lt;/a&gt; - Create contributing guidelines&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;as well as the ever-present need to &lt;a href=&#34;https://doc.rust-lang.org/book/second-edition/ch14-02-publishing-to-crates-io.html#making-useful-documentation-comments&#34;&gt;document existing code&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Within the first week we&amp;rsquo;ve also &lt;a href=&#34;https://github.com/0xazure/supernova/pull/9&#34;&gt;set up and enabled&lt;/a&gt; TravisCI for testing and &lt;a href=&#34;https://github.com/rust-lang-nursery/rust-clippy&#34;&gt;linting&lt;/a&gt; our codebase thanks to &lt;a href=&#34;https://github.com/SeanPrashad&#34;&gt;Sean Prashad&lt;/a&gt; and made &lt;code&gt;supernova&lt;/code&gt; more accessible to new contributors by &lt;a href=&#34;https://github.com/0xazure/supernova/pull/15&#34;&gt;converting existing documentation to Markdown&lt;/a&gt; thanks to &lt;a href=&#34;https://github.com/Mordax&#34;&gt;Mordax&lt;/a&gt;. I really enjoyed landing these contributions; it&amp;rsquo;s really exciting to see something I started as a side-project to get better at writing &lt;a href=&#34;https://www.rust-lang.org&#34;&gt;Rust&lt;/a&gt; grow and take on a life of its own.&lt;/p&gt;
&lt;h2 id=&#34;next-week&#34;&gt;Next Week&lt;/h2&gt;
&lt;p&gt;In the next week or so we hope to have a lot of the initial set up completed so that we can move on to adding functionality. My personal goal for next week is to submit a pull request for &lt;a href=&#34;https://github.com/0xazure/supernova/issues/16&#34;&gt;improving the usability of &lt;code&gt;supernova&lt;/code&gt;&lt;/a&gt; by following Guideline #2 of &lt;a href=&#34;https://medium.com/@jdxcode/12-factor-cli-apps-dd3c227a0e46&#34;&gt;12 Factor CLI Apps&lt;/a&gt; to &amp;ldquo;prefer flags to args&amp;rdquo; to make input to the CLI more explicit and clear, as well as many other usability benefits.&lt;/p&gt;
&lt;p&gt;I also need to start thinking about what external project(s) I want to contribute to over the next few weeks; I have some ideas from my contributions during Hackoberfest, but I&amp;rsquo;ll need to make a decision soon so I can get set up to contribute.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Hacktoberfest - A Month of Open Source</title>
      <link>https://stuartcrust.com/2018/11/hacktoberfest-a-month-of-open-source/</link>
      <pubDate>Thu, 01 Nov 2018 00:00:00 -0400</pubDate>
      
      <guid>https://stuartcrust.com/2018/11/hacktoberfest-a-month-of-open-source/</guid>
      <description>&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;The past month has flown by so quickly. After a full month dedicated to contributing to the open source community, I want to reflect on my experiences with Hacktoberfest 2018 and write a bit about things I learned over the past month, what went well, what I would do differently next time, and a general reflection on the Hacktoberfest event itself.&lt;/p&gt;
&lt;p&gt;First, a reflection on my goals. For the month of Hacktoberfest I wanted to make contributions to a number of different projects, and I specifically wanted to &lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-one&#34;&gt;contribute to at least two projects that use Rust&lt;/a&gt;. How did I do?&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Week&lt;/th&gt;
&lt;th&gt;Issues / Pull Requests&lt;/th&gt;
&lt;th style=&#34;text-align:center&#34;&gt;Uses Rust?&lt;/th&gt;
&lt;th&gt;Blog Post&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://github.com/lk-geimfari/awesomo/pull/125&#34;&gt;https://github.com/lk-geimfari/awesomo/pull/125&lt;/a&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;✘&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-one&#34;&gt;Week 1&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://github.com/dplesca/purehugo/pull/26&#34;&gt;https://github.com/dplesca/purehugo/pull/26&lt;/a&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;✘&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-two&#34;&gt;Week 2&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://github.com/rustwasm/book/issues/127&#34;&gt;https://github.com/rustwasm/book/issues/127&lt;/a&gt; &lt;!-- raw HTML omitted --&gt;  &lt;a href=&#34;https://github.com/rustwasm/book/pull/128&#34;&gt;https://github.com/rustwasm/book/pull/128&lt;/a&gt; &lt;!-- raw HTML omitted --&gt;  &lt;a href=&#34;https://github.com/diesel-rs/diesel/issues/1891&#34;&gt;https://github.com/diesel-rs/diesel/issues/1891&lt;/a&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;✔&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-three&#34;&gt;Week 3&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://github.com/dplesca/purehugo/pull/28&#34;&gt;https://github.com/dplesca/purehugo/pull/28&lt;/a&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;✘&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-four&#34;&gt;Week 4&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://github.com/rustwasm/book/pull/129&#34;&gt;https://github.com/rustwasm/book/pull/129&lt;/a&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;✔&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-five&#34;&gt;Week 5&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;2 ✔&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;In the past month, I made 4 contributions (issues or pull requests) to 2 different projects that use Rust. Ironically, I did not have the opportunity to &lt;em&gt;use&lt;/em&gt; Rust or write any code as part of those contributions as all of those contributions were in the form of documentation. However, I did still achieve the goal I had set for myself for Hacktoberfest!&lt;/p&gt;
&lt;p&gt;I also ran some quick stats on my blog posts for this past month, as shown below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;wc -w content/posts/2018/hacktoberfest-week-*.rst
     673 content/posts/2018/hacktoberfest-week-one.rst
     822 content/posts/2018/hacktoberfest-week-two.rst
    1579 content/posts/2018/hacktoberfest-week-three.rst
     514 content/posts/2018/hacktoberfest-week-four.rst
     425 content/posts/2018/hacktoberfest-week-five.rst
    4013 total
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For the month of October, I wrote a total of &lt;code&gt;4013&lt;/code&gt; words about my contributions to open source, writing a one-time maximum of &lt;code&gt;1579&lt;/code&gt; words during Week 3 about &lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-three&#34;&gt;documentation and different ways to contribute&lt;/a&gt; to open source projects.&lt;/p&gt;
&lt;h1 id=&#34;what-went-well&#34;&gt;What Went Well&lt;/h1&gt;
&lt;p&gt;Overall, I think Hacktoberfest was a positive experience. I had some really great interactions with the open source community on GitHub, and all of the project maintainers were very encouraging and helpful. Special shout-out to &lt;a href=&#34;https://github.com/sendilkumarn&#34;&gt;Sendil Kumar N&lt;/a&gt;, a member of the &lt;a href=&#34;https://github.com/rustwasm&#34;&gt;rust-wasm&lt;/a&gt; team, for an &lt;a href=&#34;https://github.com/rustwasm/book/pull/128#pullrequestreview-167612434&#34;&gt;especially warm welcome&lt;/a&gt; to the Rust and WebAssembly Book repository.&lt;/p&gt;
&lt;p&gt;I am also happy to share that all of my pull requests were merged within the month. Hacktoberfest does not require pull requests to be merged as part of participating, only that they are created, but it was very validating that I did not have to go back to the drawing board or make many changes to my contributions for them to be accepted by the project maintainers. Hacktoberfest is definitely geared more towards small fixes and improvements, and while it is less likely to happen during an even like this I have made other contributions in the past that got tied up in &lt;a href=&#34;https://en.wiktionary.org/wiki/bikeshedding&#34;&gt;bikeshedding&lt;/a&gt; and nitpicking such that no progress was made for weeks or months at a time.&lt;/p&gt;
&lt;h1 id=&#34;what-to-do-differently&#34;&gt;What to do Differently&lt;/h1&gt;
&lt;p&gt;Now that Hacktoberfest is over, I definitely think it was a mistake to jump around from project to project. Every time I went to make a contribution to a new project I would have to ramp up again, learning how the project is organized, where I can find existing documentation, how to successfully contribute to the project, etc. I also didn&amp;rsquo;t feel like I was immersing myself in a community the way I had hoped to while participating in Hacktoberfest this year. As I have written about before, I am &lt;a href=&#34;https://stuartcrust.com/2018/09/a-return-to-open-source&#34;&gt;not a stranger to open source&lt;/a&gt;, so I definitely felt there was something missing this month, and I think the project-hopping contributed to this feeling.&lt;/p&gt;
&lt;p&gt;The next time I participate in Hacktoberfest, I will be trying to focus a lot more on contributing code rather than documentation or other forms of contribution. I &lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-three&#34;&gt;wrote at length&lt;/a&gt; about different forms open source contributions can take during week three of Hacktoberfest and while I do not want to deemphasize the importance of things like documentation I am a programmer at heart, I genuinely enjoy writing code, and I&amp;rsquo;d like to do more of that.&lt;/p&gt;
&lt;h1 id=&#34;reflecting-on-hacktoberfest&#34;&gt;Reflecting on Hacktoberfest&lt;/h1&gt;
&lt;p&gt;Hacktoberfest is a great outreach event to get more people participating in open source. There is definitely more awareness in the community the past few years about the new contributor experience, and GitHub tags like &amp;ldquo;&lt;a href=&#34;https://github.com/search?q=label%3A%22help+wanted%22&#34;&gt;help wanted&lt;/a&gt;&amp;rdquo; and &amp;ldquo;&lt;a href=&#34;https://github.com/search?q=label%3A%22hacktoberfest%22&#34;&gt;hacktoberfest&lt;/a&gt;&amp;rdquo; make it a lot easier for people to find projects and get involved. One of the downsides to this is sifting through all of the results to find a project of interest or an issue that details a fix or feature a new contributor might actually be able to tackle.&lt;/p&gt;
&lt;p&gt;Which brings us to: time constraints. Hacktoberfest is a month-long event, which seems like an excessive amount of time on October 1st, but once the event moves into its last week everyone realizes how little time a month turns out to be. The Hacktoberfest &lt;a href=&#34;https://hacktoberfest.digitalocean.com/#stats--global&#34;&gt;global stats&lt;/a&gt; bear this out: there was a pretty healthy uptick in contributions during the last few days of the event as more contributors worked towards completing their five pull requests.&lt;/p&gt;
&lt;p&gt;These time constraints can also make people feel like they need to contribute as much as possible as quickly as possible, leading to contributions that focus on quantity over quality. Or interactions like the one I had on one of the first projects I was going to contribute to for Hacktoberfest: I indicated my interest in attempting to fix an issue, and someone else - who did not participate in the discussion on the issue or check if an issue had already been claimed - submitted a pull request ahead of me. &lt;em&gt;Twice&lt;/em&gt;. Thankfully I had not started on an implementation at that point, so I simply moved on to another project and a different contribution.&lt;/p&gt;
&lt;p&gt;Part of the solution to this problem definitely falls to project maintainers. Creating separate issues for each contribution and assigning those issues to the claimant can resolve the ambiguity of who has priority to submit a pull request for a given issue. Also, not merging pull requests from anyone other than the claimant would go a long way to encouraging potential contributors to get involved and make sure they are taking unclaimed issues, rather than dropping off a pull request and moving on to the next contribution.&lt;/p&gt;
&lt;p&gt;In the projects I &lt;em&gt;did&lt;/em&gt; contribute to, I had a really pleasant experience. The Rust projects in particular are very welcoming; the Rust community is well known for being friendly and inclusive and it was a pleasure to contribute to making these projects even better.&lt;/p&gt;
&lt;p&gt;All in all, I learned a lot this Hacktoberfest, particularly about myself, the kinds of projects I&amp;rsquo;m interested in, and how I personally like to contribute to open source. I&amp;rsquo;m looking forward to putting those lessons into practice during next year&amp;rsquo;s Hacktoberfest, as well as in the rest of my open source contributions going forward.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Hacktoberfest - Week Five</title>
      <link>https://stuartcrust.com/2018/10/hacktoberfest-week-five/</link>
      <pubDate>Wed, 31 Oct 2018 00:00:00 -0400</pubDate>
      
      <guid>https://stuartcrust.com/2018/10/hacktoberfest-week-five/</guid>
      <description>&lt;p&gt;With this fifth week, Hacktoberfest 2018 comes to a close. I&amp;rsquo;ll be doing a retrospective on the whole month of contributions soon, but that is not this post. This week, I was able to make one of the contributions I had started back in &lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-three&#34;&gt;week three&lt;/a&gt;, a documentation contribution to the &lt;a href=&#34;https://rustwasm.github.io/book/&#34;&gt;Rust and WebAssembly Book&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As I mentioned in that post, I had filed &lt;a href=&#34;https://github.com/rustwasm/book/issues/127&#34;&gt;rustwasm/book#127&lt;/a&gt; to suggest some improvements to the explanation of &lt;code&gt;src/utils.rs&lt;/code&gt;, a module that the &lt;code&gt;rust-wasm&lt;/code&gt; &lt;a href=&#34;https://github.com/rustwasm/wasm-pack-template&#34;&gt;project template&lt;/a&gt; provides to make working with Rust compiled to WebAssembly easier including some debugging helpers in the form of a &lt;a href=&#34;https://github.com/rustwasm/console_error_panic_hook&#34;&gt;panic hook&lt;/a&gt; to print well-formatted and helpful wasm error messages to &lt;code&gt;console.error&lt;/code&gt;. &lt;a href=&#34;https://github.com/fitzgen&#34;&gt;Nick Fitzgerald&lt;/a&gt;, a member of the &lt;a href=&#34;https://www.rust-lang.org/en-US/team.html#Dev-tools-team&#34;&gt;Rust dev tools team&lt;/a&gt;, responded to &lt;a href=&#34;https://github.com/rustwasm/book/issues/127#issuecomment-433858876&#34;&gt;my issue&lt;/a&gt; and said that he would be happy to merge a pull request that did the rephrasing I had suggested. Since I had already done the work up-front when I filed my issue, I was able to get a &lt;a href=&#34;https://github.com/rustwasm/book/pull/129&#34;&gt;pull request with the change&lt;/a&gt; up very quickly and it got merged the same day.&lt;/p&gt;
&lt;p&gt;My change is &lt;a href=&#34;https://rustwasm.github.io/book/game-of-life/hello-world.html#wasm-game-of-lifesrcutilsrs&#34;&gt;live on the Rust and WebAssembly site&lt;/a&gt; right now, and it feels really great to see something that I wrote included in a project in which I&amp;rsquo;m excited to get even more involved. Big thanks to Nick for getting back to me about my proposed change and for the quick merge on &lt;a href=&#34;https://github.com/rustwasm/book/pull/129&#34;&gt;rustwasm/book#129&lt;/a&gt; to get it incorporated.&lt;/p&gt;
&lt;p&gt;With that pull request opened (and merged), I was able to achieve my five pull requests for Hacktoberfest and secure my limited edition T-shirt. The T-shirt is nice, of course, but the real benefit of Hacktoberfest is to all the open source projects that took pull requests this past month, as well as for all the participants who were able to level up their programming skills while contributing to the open source community. More on that in the next post where I&amp;rsquo;ll summarize my experience participating in Hacktoberfest 2018 and talk about what I learned, what went well, what I would do differently next time, and a general reflection on Hacktoberfest itself.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Hacktoberfest - Week Four</title>
      <link>https://stuartcrust.com/2018/10/hacktoberfest-week-four/</link>
      <pubDate>Tue, 30 Oct 2018 00:00:00 -0400</pubDate>
      
      <guid>https://stuartcrust.com/2018/10/hacktoberfest-week-four/</guid>
      <description>&lt;p&gt;Hacktoberfest week four! In keeping with the theme I &lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-three&#34;&gt;set last week&lt;/a&gt; I continued to improve open source project documentation as part of Hacktoberfest. This week I returned to &lt;a href=&#34;https://github.com/dplesca/purehugo&#34;&gt;dplesca/purehugo&lt;/a&gt;, the theme I use for this blog, to help out with improving some areas of the documentation I noticed could use a bit of polish during my first contribution to the project during Hacktoberfest &lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-two&#34;&gt;week two&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In &lt;a href=&#34;https://github.com/dplesca/purehugo/pull/28&#34;&gt;dplesca/purehugo#28&lt;/a&gt; I rephrased the section of the &lt;code&gt;README.md&lt;/code&gt; that deals with code syntax highlighting on generated blogs. As I mention in the issue, it seems as though the original author simply missed a word when writing the section:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All you need to do is to let rainbow.js the language of the highlighted code [&amp;hellip;]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;which should instead read:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All you need to do is to let rainbow.js &lt;strong&gt;know&lt;/strong&gt; the language of the highlighted code [&amp;hellip;]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The simple fix in this case would be to add the missing word. However, since I knew I would be editing this part of the document anyways, I decided to take a bit more time and rephrase the existing wording to simplify the instructions and use more specific language to instruct new users what they need to do to get the highlighting library to pick up the desired language. I also added a full example of how to apply &lt;a href=&#34;https://golang.org/&#34;&gt;Go&lt;/a&gt; syntax to a code block using Markdown, as I find seeing complete code samples or full examples in documentation to be very helpful when I&amp;rsquo;m learning a new tool or framework, and serve as quick reminders if I&amp;rsquo;m returning to a tool or framework I haven&amp;rsquo;t used recently to get me back on track.&lt;/p&gt;
&lt;p&gt;This week turned into a twofer because while I was working on &lt;a href=&#34;https://github.com/dplesca/purehugo/pull/28&#34;&gt;dplesca/purehugo#28&lt;/a&gt; I noticed a small spelling error elsewhere in the &lt;code&gt;README.md&lt;/code&gt; file and submitted &lt;a href=&#34;https://github.com/dplesca/purehugo/pull/27&#34;&gt;dplesca/purehugo#27&lt;/a&gt; to correct a word in one of the document headings. I only noticed the spelling mistake as I had just set up proper spell checking in Visual Studio Code using &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=ban.spellright&#34;&gt;Spell Right by Bartosz Antosik&lt;/a&gt; to warn me about typos and other spelling errors. I had been under the impression that VS Code shipped with spell checking by default but this does not seem to be the case. Further, the VS Code spellchecking addon I found &lt;a href=&#34;https://github.com/microsoft/vscode-spell-check&#34;&gt;published by Microsoft&lt;/a&gt; is marked as deprecated and suggests finding an alternate addon. Correcting minor typos in documentation is small potatoes compared to some other Hacktoberfest contributions, but they are important changes that affect readability, comprehension, and the flow of the document(s) in which they occur.&lt;/p&gt;
&lt;p&gt;The end of Hacktoberfest is almost upon us, and I have one last post to share about my final contribution this month. Look forward to a piece about my first major contribution to a Rust project!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Hacktoberfest - Week Three</title>
      <link>https://stuartcrust.com/2018/10/hacktoberfest-week-three/</link>
      <pubDate>Mon, 22 Oct 2018 00:00:00 -0400</pubDate>
      
      <guid>https://stuartcrust.com/2018/10/hacktoberfest-week-three/</guid>
      <description>&lt;p&gt;As of last week we are just about half way through Hacktoberfest. Time is just flying by, and I can&amp;rsquo;t believe how quickly it&amp;rsquo;s passing. In my &lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-two/&#34;&gt;previous Hacktoberfest post&lt;/a&gt; I wrote about my slightly self-interested contribution to &lt;a href=&#34;https://github.com/dplesca/purehugo&#34;&gt;dplesca/purehugo&lt;/a&gt;, the theme I use for this blog, and how I used some of Hugo&amp;rsquo;s built-in functions to normalize URLs that used the &lt;code&gt;.Site.BaseURL&lt;/code&gt; variable.&lt;/p&gt;
&lt;p&gt;My contribution this week for Hacktoberfest is minor, but it started me on a path to encounter a number of issues with a common theme that should leave me with plenty of work to do over the next few weeks and possibly past the end of the month.&lt;/p&gt;
&lt;h1 id=&#34;theme-week-documentation&#34;&gt;Theme Week: Documentation&lt;/h1&gt;
&lt;p&gt;There has been a trend over the last number of years for contributors to open source to diversify how they contribute to open source. Code is not the only kind of contribution maintainers hope to receive, and they are happy to receive contributions in the form of documentation, code examples, sample projects, and feedback from first-time users, among others.&lt;/p&gt;
&lt;p&gt;For Hacktoberfest week three, I focused my efforts on project documentation, or a lack thereof, specifically from the perspective of a new user. So far during Hacktoberfest I haven&amp;rsquo;t made more than one contribution to the same project; instead I&amp;rsquo;ve jumped around quite a bit to different projects that use many different languages and project structures. This project hopping has given me some perspective on the onboarding and getting started instructions of a number of projects, which are critical for encouraging adoption and helping new users get up to speed on how to use or contribute to a project, application, or service. Documentation can also be tricky to get right the first, second, or even fifth time because it is hard to write a document that is useful for every audience, especially if the topic is technical in nature and the author(s) can&amp;rsquo;t make many assumptions about the audience&amp;rsquo;s technical background or ability. Many projects deal with this by dividing the documentation in two: one set of high-level documentation on getting the project up and running aimed at users, and another set of documentation that augments and extends this high-level documentation aimed at contributors and developers that provides much more technical detail.&lt;/p&gt;
&lt;p&gt;This past week also reiterates the importance of contributing to projects in ways other than implementing new features, writing test cases, or fixing bugs in code. There are so many ways to contribute to open source projects, and one of the best ways new contributors can help a project is to verify the project&amp;rsquo;s onboarding flow by following basic steps like the project setup information and getting their development environment up and running. These are tasks that established contributors and maintainers do not have to do very often and documentation can get out of date; new contributors are great at spotting problem areas in guides, tutorials, and example code that can improve the onboarding experience and identify areas where further explanation may be necessary that established contributors may not be able to see.&lt;/p&gt;
&lt;h1 id=&#34;project-one-rust-wasm&#34;&gt;Project One: &lt;code&gt;rust-wasm&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;I have been excited about &lt;a href=&#34;https://webassembly.org/&#34;&gt;WebAssembly&lt;/a&gt; since I first heard about the work being done to support it in multiple browser engines. WebAssembly is a binary instruction format predominantly designed for the web (though its success on the web will surely spur adoption in other areas just as NodeJS forced us to rethink possible applications for JavaScript) that can be targeted by many other languages like C++, Rust, Go, and Java, among others. &lt;code&gt;rust-wasm&lt;/code&gt; is the Rust initiative to provide compilation for the wasm target as well as support interoperation with existing JavaScript code both shipped in browsers and provided as libraries through tools like &lt;code&gt;npm&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I wanted to get up and running with WebAssembly as a compilation target for Rust, so I decided to read some of the core documentation provided by the &lt;code&gt;rust-wasm&lt;/code&gt; team: the &lt;a href=&#34;https://rustwasm.github.io/book/&#34;&gt;Rust and WebAssembly Book&lt;/a&gt;. After taking a brief detour to set up a &lt;a href=&#34;https://github.com/0xazure/homebrew-tap/blob/master/Formula/wasm-pack.rb&#34;&gt;personal Homebrew tap&lt;/a&gt; for the &lt;code&gt;wasm-pack&lt;/code&gt; tool (which I hope, once the prerequisite Rust version lands on the stable channel, I will be able to contribute back to &lt;code&gt;homebrew/hombrew-core&lt;/code&gt; and &lt;code&gt;rust-wasm&lt;/code&gt;), I was able to set up all of the necessary project dependencies to start working through &lt;a href=&#34;https://rustwasm.github.io/book/game-of-life/introduction.html&#34;&gt;the tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;hello-world&#34;&gt;Hello, World!&lt;/h2&gt;
&lt;p&gt;The Rust and WebAssembly Book bases the tutorial off a project template to get new users up and running more quickly. It spends a portion of &lt;a href=&#34;https://rustwasm.github.io/book/game-of-life/hello-world.html&#34;&gt;the introductory section&lt;/a&gt; talking about each file in the template and its purpose in the larger project. When I got to the section describing &lt;code&gt;wasm-game-of-life/src/utils.rs&lt;/code&gt;, I was given this explanation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;src/utils.rs&lt;/code&gt; module provides a couple included batteries that we will use later in the tutorial. We can ignore it for now.&lt;/p&gt;
&lt;p&gt;— Rust and WebAssembly, &lt;em&gt;5.2 - Hello, World!&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After the reasonably detailed explanations of other files in the project, this section stood out to me as one that could be improved. This section also makes reference to a philosophy of &amp;ldquo;batteries included&amp;rdquo;, which I had only ever been exposed to before &lt;a href=&#34;https://docs.python.org/2/tutorial/stdlib.html#batteries-included&#34;&gt;in Python jargon&lt;/a&gt; and that may not be familiar to everyone who has not had a similar exposure, or for whom English is not their primary language and the idiom is lost in translation.&lt;/p&gt;
&lt;p&gt;Being a fresh set of eyes on the Rust and WebAssembly Book, I filed &lt;a href=&#34;https://github.com/rustwasm/book/issues/127&#34;&gt;rustwasm/book#127&lt;/a&gt; to discuss some suggestions for how this section could be improved without the need for jargon-heavy idioms and to provide more details about the particular module in question. At the time of publishing I have not heard back from anyone on the &lt;code&gt;rust-wasm&lt;/code&gt; team, but I am hopeful that I will be able to submit a pull request before the end of the month to improve this part of the tutorial.&lt;/p&gt;
&lt;h2 id=&#34;typos-and-transcription-errors&#34;&gt;Typos and Transcription Errors&lt;/h2&gt;
&lt;p&gt;Reading through the rest of the page, I ran across the simple error of a duplicated word in the explanation of &lt;code&gt;wasm-game-of-life/www/index.js&lt;/code&gt;. I submitted my correction as &lt;a href=&#34;https://github.com/rustwasm/book/pull/128&#34;&gt;rustwasm/book#128&lt;/a&gt; and it was accepted the same day. I even received a &lt;a href=&#34;https://github.com/rustwasm/book/pull/128#pullrequestreview-167612434&#34;&gt;congratulatory message&lt;/a&gt; from one of the maintainers on my first contribution to the project which, as my first interaction with any of the project maintainers, is a nice personal touch that definitely makes me want to to continue to contribute to &lt;code&gt;rust-wasm&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&#34;project-two-diesel&#34;&gt;Project Two: Diesel&lt;/h1&gt;
&lt;p&gt;I have been playing around with reimplementing a currently active Postgresql-backed project using Rust, and discovered &lt;a href=&#34;http://diesel.rs/&#34;&gt;Diesel&lt;/a&gt; as one of the ORM tools at the forefront of Rust development stacks. As with &lt;code&gt;rust-wasm&lt;/code&gt;, I have not used Diesel in any of my projects, so I turned to the &lt;a href=&#34;http://diesel.rs/guides/getting-started/&#34;&gt;getting started guide&lt;/a&gt; Diesel provides. It wasn&amp;rsquo;t long after I got the &lt;code&gt;diesel-cli&lt;/code&gt; tool installed that I ran into a discrepancy between the guide and the behaviour of the CLI tool, so I filed &lt;a href=&#34;https://github.com/diesel-rs/diesel/issues/1891&#34;&gt;diesel-rs/diesel#1891&lt;/a&gt; to detail my expectations along with the actual output the tool was producing, as well as some suggestions for improving the clarity of documentation in a few disparate but related areas of the codebase and guide.&lt;/p&gt;
&lt;p&gt;I am of course very grateful for the guide because it is much more approachable - with many code samples and examples - than reading highly technical API documentation or &lt;code&gt;man&lt;/code&gt; pages. However, it can be intimidating for a new user if they are following along with the steps in the guide and something unexpected happens; often the new user doesn&amp;rsquo;t know if they did something in the wrong order or missed an important step, or if the guide is simply out of date and they are not sure how to get around the outdated part to continue their progress. It is also common for code and documentation to get out of sync, resulting in confused and annoyed users. Unfortunately there isn&amp;rsquo;t a great technical solution to this issue and authors need to always take care to not only update code but also documentation, though Rust&amp;rsquo;s &lt;a href=&#34;https://doc.rust-lang.org/rustdoc/documentation-tests.html&#34;&gt;documentation tests&lt;/a&gt; are one example of a tool that can help by ensuring that example code included in comments is up to date and working.&lt;/p&gt;
&lt;h1 id=&#34;project-next&#34;&gt;Project: Next&lt;/h1&gt;
&lt;p&gt;As I am still a new user of &lt;code&gt;rust-wasm&lt;/code&gt; and &lt;a href=&#34;http://diesel.rs/&#34;&gt;Diesel&lt;/a&gt;, I am sure there are still many things I can contribute to these projects, both in terms of improving the onboarding experience for new users as well as other non-code contributions. I also have my eye on a few areas of the guide for &lt;a href=&#34;https://rocket.rs/guide&#34;&gt;Rocket&lt;/a&gt;, a web framework written in Rust that was the reason I started using Diesel. I&amp;rsquo;m hoping to hear back soon about the two issues I filed to improve documentation, and I&amp;rsquo;d like to take the time this month to shepherd them through to getting pull requests opened and merged. As for this week, I&amp;rsquo;ll be picking out my next few contributions for Hacktoberfest and might also start thinking about picking a project to stick with for a while now that I&amp;rsquo;ve worked on a number of projects so far this term.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Hacktoberfest - Week Two</title>
      <link>https://stuartcrust.com/2018/10/hacktoberfest-week-two/</link>
      <pubDate>Mon, 15 Oct 2018 00:00:00 -0400</pubDate>
      
      <guid>https://stuartcrust.com/2018/10/hacktoberfest-week-two/</guid>
      <description>&lt;p&gt;Hacktoberfest week two! &lt;a href=&#34;https://stuartcrust.com/2018/10/hacktoberfest-week-one/&#34;&gt;Week one&lt;/a&gt; was all about getting into the groove of Hacktoberfest, making a small change to contribute, and finding out about other awesome projects in open source and &lt;a href=&#34;https://stuartcrust.com/categories/rust/&#34;&gt;my area of interest&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My contribution for this week had a bit more self-interest involved; I contributed a change to &lt;a href=&#34;https://github.com/dplesca/purehugo&#34;&gt;dplesca/purehugo&lt;/a&gt;, the &lt;a href=&#34;https://gohugo.io&#34;&gt;Hugo&lt;/a&gt; blog theme I use for this blog, to &lt;a href=&#34;https://github.com/dplesca/purehugo/pull/26&#34;&gt;normalize URLs&lt;/a&gt; that use Hugo&amp;rsquo;s &lt;code&gt;.Site.BaseURL&lt;/code&gt; variable.&lt;/p&gt;
&lt;h1 id=&#34;the-problem&#34;&gt;The Problem&lt;/h1&gt;
&lt;p&gt;Using the &lt;a href=&#34;https://github.com/dplesca/purehugo&#34;&gt;dplesca/purehugo&lt;/a&gt; theme, I was noticing that many links to other parts of the site - that is, links that were not external links to e.g. GitHub or Twitter - contained multiple slashes after the site root. Modern web browsers are really good at dealing with partially-malformed URLs so there was no functional problem with any of the links as the browser&amp;rsquo;s URL parser took over and cleaned them up into a value it could resolve, but it would still be better if the URLs were correctly formatted when Hugo generates the static site content.&lt;/p&gt;
&lt;p&gt;The malformed URLs looked something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pure-button&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://localhost:1313//index.xml&amp;#34;&lt;/span&gt;&amp;gt;[...]&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt;&amp;gt;
&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;post-category post-category-open source&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://localhost:1313//categories/open-source&amp;#34;&lt;/span&gt;&amp;gt;open source&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Delving into the template code revealed how &lt;code&gt;dplesca/purehugo&lt;/code&gt; was generating the URLs:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-sourceCode&#34; data-lang=&#34;sourceCode&#34;&gt;&amp;lt;a class=&amp;quot;pure-button&amp;quot; href=&amp;quot;{{ .Site.BaseURL }}/index.xml&amp;quot;&amp;gt;[...]&amp;lt;/a&amp;gt;
&amp;lt;a class=&amp;quot;post-category post-category-{{ . }}&amp;quot; href=&amp;quot;{{ $baseUrl }}/categories/{{ . | urlize }}&amp;quot;&amp;gt;{{ . }}&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The template string used &lt;code&gt;.Site.BaseURL&lt;/code&gt; and appended a slash before the next URL fragment. Since this results in a double slash in the generated output, I presume but have not confirmed that &lt;code&gt;.Site.BaseURL&lt;/code&gt; always ends in a trailing slash that needs to be taken into consideration when generating URLs relative the the site&amp;rsquo;s root.&lt;/p&gt;
&lt;h1 id=&#34;the-solution&#34;&gt;The Solution&lt;/h1&gt;
&lt;p&gt;In a similar way to how we join file paths in NodeJS with &lt;a href=&#34;https://nodejs.org/api/path.html#path_path_join_paths&#34;&gt;path.join()&lt;/a&gt;, we almost never want to be responsible for building URL paths ourselves. Luckily, Hugo provides &lt;a href=&#34;https://gohugo.io/functions/&#34;&gt;many built-in helper functions&lt;/a&gt; that cover a whole range of use cases, including the one I decided to use to normalize URL paths throughout &lt;code&gt;dplesca/purehugo&lt;/code&gt;: &lt;a href=&#34;https://gohugo.io/functions/absurl/.&#34;&gt;absURL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;From the Hugo documentation, &lt;code&gt;absURL&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Creates an absolute URL based on the configured &lt;code&gt;baseURL&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;where &lt;code&gt;baseURL&lt;/code&gt; is the hostname (and path) to the root of the site which is set as part of Hugo&amp;rsquo;s &lt;a href=&#34;https://gohugo.io/getting-started/configuration/#all-configuration-settings&#34;&gt;site configuration&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This function was a perfect solution in most of the places where static files need to be linked and served to the client, such as JavaScript or CSS content. In those cases it was a simple matter of removing &lt;code&gt;.Site.BaseURL&lt;/code&gt; and the subsequent concatenation and replace it with a call to the &lt;code&gt;absURL&lt;/code&gt; function, like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pure-button&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{{ &amp;#34;index.xml&amp;#34; | absURL }}&amp;#39;&lt;/span&gt;&amp;gt;[...]&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Normalizing the post category links turned out to be a bit more complicated than this simple substitution because these links needed to include more URL fragments to create the complete path. In order to correctly concatenate and then normalize these URLs, I turned to another of Hugo&amp;rsquo;s built-in functions: &lt;a href=&#34;https://gohugo.io/functions/printf/&#34;&gt;printf&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Hugo&amp;rsquo;s templating system is built almost entirely on top of Go&amp;rsquo;s built-in &lt;a href=&#34;https://golang.org/pkg/text/template/&#34;&gt;template package&lt;/a&gt;, which makes things very familiar if you have worked with Go templates before. It also means that Hugo can expose a lot of Go functions as Hugo functions available inside templates. In this case, Hugo&amp;rsquo;s &lt;code&gt;printf&lt;/code&gt; function exposes Go&amp;rsquo;s &lt;code&gt;fmt.Sprintf&lt;/code&gt; function which works much like &lt;code&gt;printf&lt;/code&gt; in C.&lt;/p&gt;
&lt;p&gt;This is the solution I came up with for building the more complicated post category link URLs while still being able to normalize the resulting URL using &lt;code&gt;absURL&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;post-category post-category-{{ . }}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{{ ( printf &amp;#34;categories/%s&amp;#34; . ) | absURL }}&amp;#39;&lt;/span&gt;&amp;gt;{{ . }}&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Unlike in NodeJS, in this case it&amp;rsquo;s safe to do a simple string concatenation of &lt;code&gt;categories/&amp;lt;category-name&amp;gt;&lt;/code&gt; because unlike with file systems, the fragment separator in URLs is always the &lt;code&gt;/&lt;/code&gt; character.&lt;/p&gt;
&lt;h1 id=&#34;to-be-continued&#34;&gt;To be Continued&lt;/h1&gt;
&lt;p&gt;I am very thankful to &lt;code&gt;purehugo&lt;/code&gt;&amp;rsquo;s author, &lt;a href=&#34;https://github.com/dplesca&#34;&gt;@dplesca&lt;/a&gt;, for responding so quickly to my pull request with this change and for merging the pull request within a few hours of my submission. While working on this change I noticed a few other areas where I think &lt;code&gt;dplesca/purehugo&lt;/code&gt; could be improved, and I&amp;rsquo;m looking forward to working on it more as I continue using it to generate my blog and host my site content.&lt;/p&gt;
&lt;p&gt;Hacktoberfest continues on, and I need to start thinking about my next contribution. My school is on a break starting next week, so I&amp;rsquo;m hoping to find the time to dig into something a bit larger and more challenging based on the projects I&amp;rsquo;ve seen so far or had recommended to me by classmates.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Hacktoberfest - Week One</title>
      <link>https://stuartcrust.com/2018/10/hacktoberfest-week-one/</link>
      <pubDate>Thu, 04 Oct 2018 00:00:00 -0400</pubDate>
      
      <guid>https://stuartcrust.com/2018/10/hacktoberfest-week-one/</guid>
      <description>&lt;p&gt;Hacktoberfest, start! In my &lt;a href=&#34;/2018/09/a-return-to-open-source/&#34;&gt;previous post&lt;/a&gt; I mentioned that I was hoping to find some interesting projects to contribute to this month, and so far I&amp;rsquo;ve come up with a pretty good shortlist of contributions I want to make.&lt;/p&gt;
&lt;p&gt;To start the month off, I lent a hand to &lt;a href=&#34;https://github.com/lk-geimfari/awesomo&#34;&gt;lk-geimfari/awesomo&lt;/a&gt; to &lt;a href=&#34;https://github.com/lk-geimfari/awesomo/pull/125&#34;&gt;reorganize their list&lt;/a&gt; of Rust projects. They had already reorganized the one for Python and suggested contributors use that as a model for the rest of the reorganizations. There are still a bunch of languages on the list in the &lt;a href=&#34;https://github.com/lk-geimfari/awesomo/issues/101&#34;&gt;tracking issue&lt;/a&gt;, so head on over and give them a hand!&lt;/p&gt;
&lt;p&gt;The work itself was straight forward; contributors were asked to alphabetize the projects in the list, and provide a table of contents and headings based on the example. I think this was a great first issue for Hacktoberfest because my goal for this month is to contribute to at least two projects that use &lt;a href=&#34;https://www.rust-lang.org/en-US/&#34;&gt;Rust&lt;/a&gt;, and what better way to find out about cool projects than working with a list chock full of them?&lt;/p&gt;
&lt;h1 id=&#34;alacritty&#34;&gt;Alacritty&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/jwilm/alacritty&#34;&gt;Alacritty&lt;/a&gt; was one of the first projects to catch my eye, not just because it was originally at the top of the list, but also because I saw an announcement post that Alacritty &lt;a href=&#34;https://www.reddit.com/r/rust/comments/9gl75a/alacritty_now_supports_scrollback/&#34;&gt;now supports terminal scrollback&lt;/a&gt; which introduced me to the existence of the project in the first place. Alacritty claims to be &amp;ldquo;the fastest terminal emulator in existence&amp;rdquo;, and uses the GPU for rendering to enable optimizations that aren&amp;rsquo;t possible using other terminal emulators. Alacritty is still very much in its infancy, with &lt;a href=&#34;https://github.com/jwilm/alacritty/releases/tag/v0.2.1&#34;&gt;version 0.2.1&lt;/a&gt; as the most recent release at the time of writing. Windows support is planned before a 1.0 release, so if this intrigues you and you&amp;rsquo;re a Windows developer &lt;a href=&#34;https://github.com/jwilm/alacritty/issues/28&#34;&gt;have a look at the tracking issue&lt;/a&gt; and see if you can help out.&lt;/p&gt;
&lt;h1 id=&#34;diesel&#34;&gt;Diesel&lt;/h1&gt;
&lt;p&gt;Another project I was aware of before working with this awesome list of Rust projects is &lt;a href=&#34;http://diesel.rs/&#34;&gt;Diesel&lt;/a&gt;, a safe, extensible object-relational mapper (ORM) for Rust. When deciding on the technology stack for my capstone project this year, I investigated using the &lt;a href=&#34;https://rocket.rs/overview/&#34;&gt;Rocket&lt;/a&gt; web framework written in Rust, and Diesel is one of the ORMs &lt;a href=&#34;https://rocket.rs/guide/state/#dependencies&#34;&gt;recommended in the getting started guide&lt;/a&gt;. Diesel provides a comfortable CLI experience for developers familiar with tools like &lt;a href=&#34;https://guides.rubyonrails.org/active_record_basics.html&#34;&gt;ActiveRecord&lt;/a&gt; from Ruby on Rails and &lt;a href=&#34;http://docs.sequelizejs.com/&#34;&gt;Sequelize&lt;/a&gt; in NodeJS, but drastically improves on both by leveraging Rust&amp;rsquo;s type safety and by &amp;ldquo;eliminat[ing] the possibility of incorrect database interactions at compile time.&amp;rdquo;&lt;/p&gt;
&lt;h1 id=&#34;exa&#34;&gt;exa&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://the.exa.website/&#34;&gt;exa&lt;/a&gt; is a modern replacement for the built-in unix &lt;code&gt;ls&lt;/code&gt; command which aims to have better defaults and more features. I have been using &lt;code&gt;exa&lt;/code&gt; myself for a few weeks and I am really enjoying the experience so far. With &lt;code&gt;ls&lt;/code&gt; I set up a number of shell aliases and functions to do things like enable human-readable sizes and always show colours; in &lt;code&gt;exa&lt;/code&gt; these features are turned on automatically without any setup. I am all for customizability in those cases where it&amp;rsquo;s absolutely necessary but sane defaults is almost always a better solution, especially with a tool that most of us use hundreds of times a day.&lt;/p&gt;
&lt;h1 id=&#34;to-be-continued&#34;&gt;To be Continued&lt;/h1&gt;
&lt;p&gt;I definitely have some ideas about more projects that I&amp;rsquo;d like to contribute to after seeing the &lt;a href=&#34;https://github.com/lk-geimfari/awesomo&#34;&gt;lk-geimfari/awesomo&lt;/a&gt; list, either this month for Hacktoberfest or on an ongoing basis. If Rust isn&amp;rsquo;t your language of choice, there are similar lists of projects in pretty much every popular language as well as some more obscure ones, so take a look, be inspired, and happy hacking!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A Return to Open Source</title>
      <link>https://stuartcrust.com/2018/09/a-return-to-open-source/</link>
      <pubDate>Sat, 29 Sep 2018 00:00:00 -0400</pubDate>
      
      <guid>https://stuartcrust.com/2018/09/a-return-to-open-source/</guid>
      <description>&lt;p&gt;Today marks the first month of my return to open source. I say &lt;em&gt;return&lt;/em&gt; even though I never really &lt;em&gt;left&lt;/em&gt;, it&amp;rsquo;s more of a return to active participation in the community. As I &lt;a href=&#34;https://stuartcrust.com/2018/09/third-times-the-charm/&#34;&gt;wrote about earlier&lt;/a&gt;, one of my courses right now focuses on open source development, so I have been able to &lt;a href=&#34;https://github.com/0xazure?tab=overview&amp;amp;from=2018-09-01&amp;amp;to=2018-09-30&#34;&gt;contribute much more regularly&lt;/a&gt; and I hope to be able to continue to do so even after the course is over.&lt;/p&gt;
&lt;p&gt;This past month has been all about getting back into the swing of things by contributing to &lt;a href=&#34;https://github.com/filerjs/filer&#34;&gt;filerjs/filer&lt;/a&gt;, a port of NodeJS&#39; &lt;code&gt;fs&lt;/code&gt; module to the web using backends like IndexedDB. My first contribution to filer, which I have &lt;a href=&#34;https://stuartcrust.com/2018/09/its-dependencies-all-the-way-down/&#34;&gt;already blogged about&lt;/a&gt;, was to update a development dependency to resolve package vulnerabilities as reported by &lt;code&gt;npm audit&lt;/code&gt;. This issue was logged as &lt;a href=&#34;https://github.com/filerjs/filer/issues/384&#34;&gt;filer#384&lt;/a&gt; and fixed in &lt;a href=&#34;https://github.com/filerjs/filer/pull/385&#34;&gt;filer#385&lt;/a&gt; by updating the vulnerable dependency. This issue also spawned some discussion as &lt;a href=&#34;https://github.com/filerjs/filer/issues/386&#34;&gt;filer#386&lt;/a&gt; about automating the process of keeping project dependencies up to date so it is much easier to stay on top of new versions of dependencies.&lt;/p&gt;
&lt;p&gt;Open source isn&amp;rsquo;t just about contributing code and documentation though. It&amp;rsquo;s also about the community, interacting with other developers, discussing issues and potential solutions, as well as reviewing and helping out other members of the community. In addition to helping out my classmates over Slack and in-class throughout the month, I also reviewed a few pull requests opened against the filer repository.&lt;/p&gt;
&lt;p&gt;The first issue I reviewed, &lt;a href=&#34;https://github.com/filerjs/filer/pull/478&#34;&gt;filer#478&lt;/a&gt;, is a pull request that adds a test to &lt;code&gt;fs.watch()&lt;/code&gt; to verify the event type emitted when renaming an existing file. Other than the boilerplate mocha test code, the test logic itself is fairly straight forward. However, &lt;code&gt;fs.watch()&lt;/code&gt; and related watching functions are an interesting set of methods because they are not guaranteed to be consistent due to the &lt;a href=&#34;https://nodejs.org/api/fs.html#fs_caveats&#34;&gt;underlying implementation details&lt;/a&gt;. I actually had to go back to this pull request and re-review it because it turns out that filer &lt;a href=&#34;https://github.com/filerjs/filer/issues/411#issuecomment-422946490&#34;&gt;doesn&amp;rsquo;t currently have support&lt;/a&gt; for &lt;code&gt;rename&lt;/code&gt; events at all. This issue was also interesting because I picked out a minor style nitpick in the form of a missing semi-colon that the Travis build &lt;a href=&#34;https://github.com/filerjs/filer/issues/482&#34;&gt;didn&amp;rsquo;t seem to pick up&lt;/a&gt; for some reason. Rerunning the build resolved the issue, but it&amp;rsquo;s always worrying when you run into issues with your build infrastructure and tests because it can shake your faith in them a bit.&lt;/p&gt;
&lt;p&gt;Another issue that I reviewed was &lt;a href=&#34;https://github.com/filerjs/filer/pull/472&#34;&gt;filer#472&lt;/a&gt;. This pull request adds a test to ensure that reading from a nonexistent file results in an error. The submission is well done overall, with one minor nitpick that lead to me filing &lt;a href=&#34;https://github.com/filerjs/filer/pull/498&#34;&gt;filer#498&lt;/a&gt; to reduce small nitpick-type comments on reviews. Nitpicks are generally a waste of everyone&amp;rsquo;s time because style should be automatically enforced by some kind of automated tool before code is pushed; JavaScript doesn&amp;rsquo;t have anything quite like &lt;a href=&#34;https://golang.org/cmd/gofmt/&#34;&gt;gofmt&lt;/a&gt; or &lt;a href=&#34;https://github.com/rust-lang-nursery/rustfmt&#34;&gt;rustfmt&lt;/a&gt;, but tools like &lt;a href=&#34;https://github.com/xojs/xo&#34;&gt;xo&lt;/a&gt; and &lt;a href=&#34;https://github.com/prettier/prettier&#34;&gt;prettier&lt;/a&gt; can help. In this review I also cautioned the original author of the pull request about changing multiple variables at a time in a test, which we ideally would like to avoid as we can easily end up testing more code paths than we either need or want to, thereby complicating the test or making it fragile against future changes to the code.&lt;/p&gt;
&lt;p&gt;Looking ahead, October marks the beginning of &lt;a href=&#34;https://hacktoberfest.digitalocean.com/&#34;&gt;Hacktoberfest&lt;/a&gt;. I&amp;rsquo;m really excited to be participating this year; I participated once before but I either missed the cutoff or something happened to my package because I never received my t-shirt from DigitalOcean. I&amp;rsquo;ll be writing a lot more short blog posts throughout October as I chronicle my participation in this event, and I&amp;rsquo;m hoping to find some interesting projects to contribute to for at least the rest of this year and hopefully well into the next.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>It&#39;s Dependencies All the Way Down</title>
      <link>https://stuartcrust.com/2018/09/its-dependencies-all-the-way-down/</link>
      <pubDate>Sat, 29 Sep 2018 00:00:00 -0400</pubDate>
      
      <guid>https://stuartcrust.com/2018/09/its-dependencies-all-the-way-down/</guid>
      <description>&lt;p&gt;NodeJS has experienced a lot of growth over the years. Like any platform, programming or otherwise, much of that growth and user adoption depends not only on the quality of the platform itself, but also the ecosystem that builds up around it.&lt;/p&gt;
&lt;p&gt;In this respect, NodeJS has possibly one of the largest ecosystems available. With &lt;a href=&#34;https://www.npmjs.com/&#34;&gt;over 700,000 packages&lt;/a&gt; published to npm, the NodeJS platform offers developers a lot of choice when it comes to 3rd-party modules. This choice lets developers choose and compose modules from many different authors when writing software, saving time, consolidating work, and reducing bugs instead of constantly &lt;a href=&#34;https://en.wikipedia.org/wiki/Not_invented_here&#34;&gt;reinventing the wheel&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The NodeJS ecosystem by and large follows the &lt;a href=&#34;https://en.wikipedia.org/wiki/Unix_philosophy&#34;&gt;Unix philosophy&lt;/a&gt;, in particular the primary tenant to&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Write programs [and libraries] that do one thing and do it well&lt;/p&gt;
&lt;p&gt;— Peter H. Salus, &lt;em&gt;A Quarter-Century of Unix (1994)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Keeping a module&amp;rsquo;s focus small is an important aspect of many programming design patterns such as the single-responsibility principle, as well as improving code reuse and composability. However, including these modules doesn&amp;rsquo;t come for free. Every project dependency is an added burden that the maintainers need to keep up to date and have to modify their code as the API of the module changes. Sometimes serious bugs are found in these modules that can expose application secrets, user data, or unauthorized access, among other classes of vulnerabilities, that the module authors need to fix before dependent projects can update to fix the bug.&lt;/p&gt;
&lt;p&gt;Staying on top of vulnerability disclosures and keeping track of all of the changes from version to version in a project&amp;rsquo;s dependencies is a challenging and resource-draining task. Even more challenging, authors must not only be concerned with the vulnerabilities in modules they depend on directly, but also those in all of the &lt;a href=&#34;https://docs.gradle.org/current/userguide/dependency_management_terminology.html#sub:terminology_transitive_dependency&#34;&gt;transitive dependencies&lt;/a&gt; that NodeJS is (in)famous for.&lt;/p&gt;
&lt;h1 id=&#34;npm-audit&#34;&gt;npm audit&lt;/h1&gt;
&lt;p&gt;In the &lt;a href=&#34;https://medium.com/npm-inc/announcing-npm-6-5d0b1799a905&#34;&gt;April 2018 announcement&lt;/a&gt; of &lt;code&gt;npm@6&lt;/code&gt;, the headlining feature the npm team showcased was &lt;code&gt;npm audit&lt;/code&gt;, a powerful tool designed to provide automatic security warnings when using code with a known security issue. The &lt;code&gt;npm audit&lt;/code&gt; tool allows developers to completely analyze a project&amp;rsquo;s dependency tree - including all transitive dependencies - to identify known vulnerable versions of dependencies based on data from the Node Security Platform database that npm &lt;a href=&#34;https://medium.com/npm-inc/npm-acquires-lift-security-258e257ef639&#34;&gt;acquired in April 2018&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The npm team made two really important decisions when designing &lt;code&gt;npm audit&lt;/code&gt;. First, all install requests issued through &lt;code&gt;npm install&lt;/code&gt; are automatically subjected to the same analysis that the &lt;code&gt;npm audit&lt;/code&gt; command performs, analyzing the package to be installed as well as any additional dependencies that package would pull into the project. Second, &lt;code&gt;npm audit&lt;/code&gt; suggests resolutions for vulnerabilities it identifies thereby giving clear actionable feedback to developers on the next steps they can take to resolve issues identified in the audit. These two decisions are critical because not only does npm take a security-conscious approach by default, but it tries to make resolving issues as painless as possible. Developers don&amp;rsquo;t want to spend hours combing through changelogs or reviewing vulnerability reports just to find the package version that includes the vulnerability fix, they want to resolve the problem and get on with writing code.&lt;/p&gt;
&lt;p&gt;As of &lt;code&gt;npm@6.1&lt;/code&gt;, &lt;code&gt;npm&lt;/code&gt; includes the &lt;code&gt;npm audit fix&lt;/code&gt; command to &lt;a href=&#34;https://blog.npmjs.org/post/174001864165/v610-next0&#34;&gt;automatically run all the package installations&lt;/a&gt; recommended by &lt;code&gt;npm audit&lt;/code&gt;, lowering the pain of updating vulnerable packages even further.&lt;/p&gt;
&lt;p&gt;The npm team shares their vision with the inclusion of tools like &lt;code&gt;npm audit&lt;/code&gt; and a security-conscious approach to ecosystem packages:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;By alerting the entire community to security vulnerabilities within a tool you already use, we can make JavaScript development safer for everyone.&lt;/p&gt;
&lt;p&gt;— &lt;a href=&#34;https://medium.com/npm-inc/announcing-npm-6-5d0b1799a905&#34;&gt;npm, Inc.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;auditing-filer&#34;&gt;Auditing filer&lt;/h1&gt;
&lt;p&gt;The first thing to do after making a fresh clone of any project is to install its dependencies. After grabbing the &lt;a href=&#34;https://github.com/filerjs/filer&#34;&gt;filer&lt;/a&gt; git url and cloning the repository, a quick &lt;code&gt;npm install&lt;/code&gt; pulls in all the dependencies we should need to get started.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;added &lt;span style=&#34;color:#ae81ff&#34;&gt;1079&lt;/span&gt; packages from &lt;span style=&#34;color:#ae81ff&#34;&gt;1531&lt;/span&gt; contributors and audited &lt;span style=&#34;color:#ae81ff&#34;&gt;9518&lt;/span&gt; packages in 36.358s
found &lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt; vulnerabilities &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; low, &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt; moderate&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
  run &lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;npm audit fix&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt; to fix them, or &lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;npm audit&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; details
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It looks like &lt;code&gt;filer@353290a&lt;/code&gt; has some vulnerable packages, which is a perfect opportunity to dig into the auditing process.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;npm@6&lt;/code&gt; is pretty in-your-face about this information, which is important. It lists the total number of vulnerabilities, as well as breaks down the number of vulnerabilities of varying severity, and provides an actionable next step: running a full audit.&lt;/p&gt;
&lt;p&gt;Running &lt;code&gt;npm audit&lt;/code&gt; produces the following report:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; npm audit security report &lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt;

    &lt;span style=&#34;color:#75715e&#34;&gt;# Run  npm install --save-dev karma@3.0.0  to resolve 6 vulnerabilities&lt;/span&gt;
    SEMVER WARNING: Recommended action is a potentially breaking change
    ┌───────────────┬──────────────────────────────────────────────────────────────┐
    │ Moderate      │ Memory Exposure                                              │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Package       │ tunnel-agent                                                 │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Dependency of │ karma &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;dev&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;                                                  │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Path          │ karma &amp;gt; log4js &amp;gt; loggly &amp;gt; request &amp;gt; tunnel-agent             │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ More info     │ https://nodesecurity.io/advisories/598                       │
    └───────────────┴──────────────────────────────────────────────────────────────┘

    ┌───────────────┬──────────────────────────────────────────────────────────────┐
    │ Moderate      │ Prototype pollution                                          │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Package       │ hoek                                                         │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Dependency of │ karma &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;dev&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;                                                  │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Path          │ karma &amp;gt; log4js &amp;gt; loggly &amp;gt; request &amp;gt; hawk &amp;gt; boom &amp;gt; hoek       │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ More info     │ https://nodesecurity.io/advisories/566                       │
    └───────────────┴──────────────────────────────────────────────────────────────┘

    ┌───────────────┬──────────────────────────────────────────────────────────────┐
    │ Moderate      │ Prototype pollution                                          │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Package       │ hoek                                                         │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Dependency of │ karma &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;dev&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;                                                  │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Path          │ karma &amp;gt; log4js &amp;gt; loggly &amp;gt; request &amp;gt; hawk &amp;gt; cryptiles &amp;gt; boom  │
    │               │ &amp;gt; hoek                                                       │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ More info     │ https://nodesecurity.io/advisories/566                       │
    └───────────────┴──────────────────────────────────────────────────────────────┘

    ┌───────────────┬──────────────────────────────────────────────────────────────┐
    │ Moderate      │ Prototype pollution                                          │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Package       │ hoek                                                         │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Dependency of │ karma &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;dev&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;                                                  │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Path          │ karma &amp;gt; log4js &amp;gt; loggly &amp;gt; request &amp;gt; hawk &amp;gt; hoek              │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ More info     │ https://nodesecurity.io/advisories/566                       │
    └───────────────┴──────────────────────────────────────────────────────────────┘

    ┌───────────────┬──────────────────────────────────────────────────────────────┐
    │ Moderate      │ Prototype pollution                                          │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Package       │ hoek                                                         │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Dependency of │ karma &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;dev&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;                                                  │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Path          │ karma &amp;gt; log4js &amp;gt; loggly &amp;gt; request &amp;gt; hawk &amp;gt; sntp &amp;gt; hoek       │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ More info     │ https://nodesecurity.io/advisories/566                       │
    └───────────────┴──────────────────────────────────────────────────────────────┘

    ┌───────────────┬──────────────────────────────────────────────────────────────┐
    │ Low           │ Regular Expression Denial of Service                         │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Package       │ timespan                                                     │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Dependency of │ karma &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;dev&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;                                                  │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ Path          │ karma &amp;gt; log4js &amp;gt; loggly &amp;gt; timespan                           │
    ├───────────────┼──────────────────────────────────────────────────────────────┤
    │ More info     │ https://nodesecurity.io/advisories/533                       │
    └───────────────┴──────────────────────────────────────────────────────────────┘

    found &lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt; vulnerabilities &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; low, &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt; moderate&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; in &lt;span style=&#34;color:#ae81ff&#34;&gt;9518&lt;/span&gt; scanned packages
    &lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt; vulnerabilities require semver-major dependency updates.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The audit provides a lot of information, but it&amp;rsquo;s all broken down for the developer in a consistent format so even those who aren&amp;rsquo;t familiar with vulnerability mitigation or announcement procedures can understand what&amp;rsquo;s going on.&lt;/p&gt;
&lt;p&gt;One of the most important parts of the audit output is the path. This shows how the project and the vulnerable package are related, and is a subset of the total dependency graph for the project. This is really useful if there is no clear update path for the package your project depends on directly and you need to report (or ideally, submit a pull request) that a dependency in one of your direct dependencies should update one (or more) of its packages. Without this information clearly displayed, you would spend a lot of time chasing dependencies down by manually reviewing &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;package-lock.json&lt;/code&gt; files trying to figure out who needed to update their dependencies so you can update yours.&lt;/p&gt;
&lt;p&gt;In the case of Filer we&amp;rsquo;re pretty lucky: not only are all of the vulnerable packages related to a single direct dependency, but that dependency is one that is only used during development; resolving the problems is a simple as updating to &lt;code&gt;karma@3.0.0&lt;/code&gt;. Since this is a simple resolution, we could either run &lt;code&gt;npm audit fix&lt;/code&gt; and have &lt;code&gt;npm&lt;/code&gt; take care of the version updates for us, or we can update the &lt;code&gt;karma&lt;/code&gt; version in our &lt;code&gt;package.json&lt;/code&gt; and install the updated package.&lt;/p&gt;
&lt;p&gt;After updating &lt;code&gt;karma&lt;/code&gt;, re-running &lt;code&gt;npm audit&lt;/code&gt; to ensure we haven&amp;rsquo;t introduced any new vulnerabilities, and running the project&amp;rsquo;s tests to ensure we haven&amp;rsquo;t accidentally broken any functionality, we should take the time to contribute this fix &lt;a href=&#34;https://github.com/filerjs/filer/pull/385&#34;&gt;back to the main project&lt;/a&gt;. The fix was small and simple, but security is everyone&amp;rsquo;s responsibility; if you notice a project using outdated or vulnerable packages, take some time to help the maintainers out by submitting a pull request. Also, projects should consider looking into automating the process of keeping project dependencies up to date through various tools like &lt;a href=&#34;https://greenkeeper.io/&#34;&gt;Greenkeeper&lt;/a&gt; and &lt;a href=&#34;https://snyk.io/&#34;&gt;Snyk&lt;/a&gt;, which is a conversation &lt;a href=&#34;https://github.com/filerjs/filer/issues/386&#34;&gt;you can start&lt;/a&gt; in your project today!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Filesystem Events in NodeJS</title>
      <link>https://stuartcrust.com/2018/09/filesystem-events-in-nodejs/</link>
      <pubDate>Thu, 13 Sep 2018 00:00:00 -0400</pubDate>
      
      <guid>https://stuartcrust.com/2018/09/filesystem-events-in-nodejs/</guid>
      <description>&lt;p&gt;I have a personal interest in &lt;a href=&#34;https://en.wikipedia.org/wiki/Automation&#34;&gt;automation&lt;/a&gt;, mostly because I believe that we should be trying to offload everything we possibly can onto computing systems so that we can spend our time thinking about interesting problems rather than manually repeating the same tasks over and over again.
Good programmers, coders, and software engineers (depending on how you identify) should be trying to automate as much of their jobs as possible for all kinds of reasons: to help mitigate the &lt;a href=&#34;https://en.wikipedia.org/wiki/Bus_factor&#34;&gt;bus factor&lt;/a&gt;, to get rid of boring and repetitive parts of their jobs, and even to better document internal and external processes (if the process has been put into code - especially well-commented code - that is a form of documentation about the process!) that can then be tracked and versioned in a version control system.&lt;/p&gt;
&lt;h1 id=&#34;the-programming-loop&#34;&gt;The Programming Loop&lt;/h1&gt;
&lt;p&gt;Why am I talking about automation when the title of this post is about filesystem events? Before we talk about those kinds of events, we need to take a look at a simplified but typical example of the programming loop when writing code. Such a loop might look something like the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make a change to some code&lt;/li&gt;
&lt;li&gt;Check the editor or IDE for feedback about the code you just wrote&lt;/li&gt;
&lt;li&gt;Run tools that check for programming errors, outright bugs, and stylistic errors&lt;/li&gt;
&lt;li&gt;Run the project&amp;rsquo;s tests (the project &lt;em&gt;has&lt;/em&gt; tests, right?)&lt;/li&gt;
&lt;li&gt;Review tool and test feedback, and resolve issues&lt;/li&gt;
&lt;li&gt;Return to Step 1 and repeat&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&amp;rsquo;s a lot to do every time the code changes, but the tools are there to help write better code and catch a lot of little or subtle issues that people aren&amp;rsquo;t as good at noticing as computers can be. To take advantage of all of these tools and their output, we want to make this loop from writing some code to reviewing feedback as quick as possible so the programmer isn&amp;rsquo;t waiting around for feedback, gets annoyed at how long the process takes, and stops using the tools. Some projects also use a lot of different tools, and it can be a lot to remember how to run each tool individually and what command line arguments are required for the current project.&lt;/p&gt;
&lt;p&gt;Instead of having to remember all this information, it would be great to have to remember fewer commands to get feedback from all the tools. Automation to the rescue! Instead of running each tool separately ourselves, we can use a tool that runs other tools; in this case we want to use a task runner. &lt;code&gt;make&lt;/code&gt; is a well-known tool for automating this process, and can be used for many different kinds of projects:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;C programs [&amp;hellip;] are most common, but you can use &lt;em&gt;make&lt;/em&gt; with any programming language whose compiler can be run with a shell command. In fact, &lt;em&gt;make&lt;/em&gt; is not limited to programs. You can use it to describe any task where some files must be updated automatically from others whenever the others change.&lt;/p&gt;
&lt;p&gt;— &lt;a href=&#34;https://linux.die.net/man/1/make&#34;&gt;make manpage&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Using a tool like &lt;code&gt;make&lt;/code&gt; can simplify the loop to something like the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make a change to some code&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;make&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Review tool and test feedback from each tool that &lt;code&gt;make&lt;/code&gt; runs, and resolve issues&lt;/li&gt;
&lt;li&gt;Return to Step 1 and repeat&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This significantly reduces the steps the programmer has to take every time they make a change as well as the number of commands they need to remember: all they have to do is run &lt;code&gt;make&lt;/code&gt;! But do we really need to remember to run a command? Is there some way that we can have &lt;code&gt;make&lt;/code&gt; or something like it run whenever we make a change to the code?&lt;/p&gt;
&lt;h1 id=&#34;enter-filesystem-events&#34;&gt;Enter: Filesystem Events&lt;/h1&gt;
&lt;p&gt;Filesystem events are a great way to trigger other tasks. Other kinds of task runners such as &lt;a href=&#34;https://gruntjs.com/&#34;&gt;grunt&lt;/a&gt; and &lt;a href=&#34;https://gulpjs.com/&#34;&gt;gulp&lt;/a&gt; in NodeJS, as well as &lt;a href=&#34;https://guardgem.org/&#34;&gt;guard&lt;/a&gt; in Ruby, let the programmer set up a process to &amp;ldquo;watch&amp;rdquo; individual files or entire directories for changes. When a file changes, these task runners pick up the change and perform whatever tasks the programmer has specified.&lt;/p&gt;
&lt;p&gt;NodeJS core exposes this functionality to the JavaScript runtime through functions in the &lt;a href=&#34;https://nodejs.org/api/fs.html&#34;&gt;fs module&lt;/a&gt;. These functions include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://nodejs.org/api/fs.html#fs_fs_watch_filename_options_listener&#34;&gt;fs.watch()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://nodejs.org/api/fs.html#fs_fs_watchfile_filename_options_listener&#34;&gt;fs.watchFile()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://nodejs.org/api/fs.html#fs_fs_unwatchfile_filename_listener&#34;&gt;fs.unwatchFile()&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These functions respond to changes in the filesystem and communicate data about the detected changed file back to their listener functions.&lt;/p&gt;
&lt;h1 id=&#34;a-simple-example&#34;&gt;A Simple Example&lt;/h1&gt;
&lt;p&gt;The following is an example of how to use the &lt;code&gt;fs.watch()&lt;/code&gt; function in NodeJS. This is the recommended function to use because it supports single files as well as directories where &lt;code&gt;fs.watchFile()&lt;/code&gt; only watches individual files, and it is &lt;a href=&#34;https://nodejs.org/api/fs.html#fs_fs_watchfile_filename_options_listener&#34;&gt;more efficient&lt;/a&gt; than both &lt;code&gt;fs.watchFile()&lt;/code&gt; and &lt;code&gt;fs.unwatchFile()&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;use strict&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;// enforce JavaScript strict mode
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;fs&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;); &lt;span style=&#34;color:#75715e&#34;&gt;// import the core module
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;path&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;.&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;// start watching in the current directory
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#a6e22e&#34;&gt;fs&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;watch&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;path&lt;/span&gt;, (&lt;span style=&#34;color:#a6e22e&#34;&gt;eventType&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;filename&lt;/span&gt;) =&amp;gt; {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;eventType&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;change&amp;#39;&lt;/span&gt;) {
        &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;filename&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; changed!`&lt;/span&gt;)
    }
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;some-caveats&#34;&gt;Some Caveats&lt;/h1&gt;
&lt;p&gt;The &lt;code&gt;fs.watch()&lt;/code&gt; function does &lt;a href=&#34;https://nodejs.org/api/fs.html#fs_caveats&#34;&gt;come with some caveats&lt;/a&gt; due to the state of this kind of filesystem event handling on various platforms; specifically, the API is not 100% consistent across platforms and some options are not universally available due to the underlying implementations.&lt;/p&gt;
&lt;p&gt;Also, because &lt;code&gt;fs.watch()&lt;/code&gt; is event-driven, there is no matching set of functions in the experimental &lt;code&gt;fs&lt;/code&gt; Promise API &lt;a href=&#34;https://nodejs.org/en/blog/release/v10.0.0/&#34;&gt;introduced in Node 10.0.0&lt;/a&gt; and there is no synchronous equivalent like there are for many other functions in the &lt;code&gt;fs&lt;/code&gt; module because the task is inherently asynchronous.&lt;/p&gt;
&lt;p&gt;However, this is still really useful functionality when working with files and filesystems, and is of particular interest in our pursuit of efficient automation.&lt;/p&gt;
&lt;h1 id=&#34;one-last-twist&#34;&gt;One Last Twist&lt;/h1&gt;
&lt;p&gt;After looking a bit more into how &lt;a href=&#34;https://gruntjs.com/&#34;&gt;grunt&lt;/a&gt; and &lt;a href=&#34;https://gulpjs.com/&#34;&gt;gulp&lt;/a&gt; actually implement their file-watching functionality, it turns out that neither one of these popular test runners uses any of the &lt;code&gt;fs.watch()&lt;/code&gt; functions directly and don&amp;rsquo;t even use the same dependency to provide watching functionality!&lt;/p&gt;
&lt;p&gt;Grunt&amp;rsquo;s file-watching functionality is provided in a Grunt plugin called &lt;a href=&#34;https://www.npmjs.com/package/grunt-contrib-watch&#34;&gt;grunt-contrib-watch&lt;/a&gt;, which uses the &lt;a href=&#34;https://www.npmjs.com/package/gaze&#34;&gt;gaze&lt;/a&gt; package to interact with filesystem events.&lt;/p&gt;
&lt;p&gt;Gulp, on the other hand, relies on &lt;a href=&#34;https://www.npmjs.com/package/gulp-watch&#34;&gt;gulp-watch&lt;/a&gt; for watching files, which uses a package called &lt;a href=&#34;https://www.npmjs.com/package/chokidar&#34;&gt;chokidar&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Chokidar goes &lt;a href=&#34;https://www.npmjs.com/package/chokidar#why&#34;&gt;into some detail&lt;/a&gt; as to why &lt;code&gt;fs.watch()&lt;/code&gt; is insufficient, and gaze lists a &lt;a href=&#34;https://www.npmjs.com/package/gaze#similar-projects&#34;&gt;number of alternative projects&lt;/a&gt;, so there are clearly some community opinions on the quality of the built-in functions.&lt;/p&gt;
&lt;p&gt;Some notable functionality &lt;code&gt;fs.watch()&lt;/code&gt; lacks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;no wildcard support (e.g. cannot watch only for files that end with a particular extension, like &lt;code&gt;*.js&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;does not support recursive watching on platforms other than Windows or macOS (see &lt;a href=&#34;https://nodejs.org/api/fs.html#fs_caveats&#34;&gt;the fs watch caveats&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eventType&lt;/code&gt; is only one of &lt;code&gt;&#39;rename&#39;&lt;/code&gt; or &lt;code&gt;&#39;change&#39;&lt;/code&gt;, no support for other file events such as &lt;code&gt;&#39;removed&#39;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As in everything, there are trade-offs when implementing functionality. For simple use cases, &lt;code&gt;fs.watch()&lt;/code&gt; may be sufficient and will not require including additional project dependencies. However, if file watching is a core piece of functionality, it might be worth evaluating some of the other options available on npm to find one with the necessary functionality for the project at hand, while also keeping you from tearing your hair out tracking down odd edge cases.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Third Time&#39;s The Charm</title>
      <link>https://stuartcrust.com/2018/09/third-times-the-charm/</link>
      <pubDate>Thu, 13 Sep 2018 00:00:00 -0400</pubDate>
      
      <guid>https://stuartcrust.com/2018/09/third-times-the-charm/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been meaning to start blogging for a while. Not even blogging &lt;em&gt;consistently&lt;/em&gt;, just writing some long-form-ish pieces on projects that I&amp;rsquo;ve been working on, things I&amp;rsquo;ve learned, or things that I might want for my own reference. I&amp;rsquo;ve tried at least twice before - once when I purchased this domain back in December of &lt;em&gt;2013&lt;/em&gt; and again at the end of 2016 - and as evidenced by the utter lack of content it&amp;rsquo;s pretty clear I haven&amp;rsquo;t been successful.&lt;/p&gt;
&lt;p&gt;I made a real attempt to begin publishing at the end of 2016 with the release of that year&amp;rsquo;s &lt;a href=&#34;http://adventofcode.com/2016/&#34;&gt;Advent of Code&lt;/a&gt;, but coursework kept me pretty busy and I never managed to finish and publish any of the posts I was working on at the time. I&amp;rsquo;ll probably revisit some of them, clean them up, and post them - if I still remember what I was writing about - and the rest I may throw into a backlog so that if I ever run into a similar topic again I can incorporate my draft.&lt;/p&gt;
&lt;p&gt;The reason I&amp;rsquo;m giving it another try now is I&amp;rsquo;m taking a course that specifically focuses on open source and includes a requirement that the students blog about their work and experiences as they gain exposure to the open source community. I&amp;rsquo;m &lt;a href=&#34;https://github.com/0xazure&#34;&gt;not exactly a stranger&lt;/a&gt; to open source work, but I haven&amp;rsquo;t had time to be as active as I would like to be so this course is giving me a good excuse to commit more time to getting involved and getting my hands dirty with some contributions.&lt;/p&gt;
&lt;p&gt;On the technical side, this site is built using the static site generator &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;. I&amp;rsquo;ve been learning a lot about the ins and outs of Hugo&amp;rsquo;s project structure as I set this blog up, but so far I&amp;rsquo;m pretty happy with the results. Hugo is written in &lt;a href=&#34;https://golang.org/&#34;&gt;Go&lt;/a&gt;, the Google-sponsored C/++ replacement, and Hugo has a very active community that keeps improving the project.&lt;/p&gt;
&lt;p&gt;One issue that I did run into was some confusion over themes in Hugo. Each Hugo site has a &lt;code&gt;config.toml&lt;/code&gt; that sets parameters for how the static site content should be generated. Those parameters also include information like social media links that get embedded in certain parts of the Hugo theme that structures the site content and controls the look and feel. Unfortunately, there don&amp;rsquo;t seem to be standard keys for many of these parameters, so the key name for your GitHub or StackOverflow account information needs to be updated if you decide to change your site theme. You can see some of the work I had to do &lt;a href=&#34;https://github.com/0xazure/0xazure/commit/ed9a74d58acbcd49f0be613cfd14dbefb725a842&#34;&gt;in this commit&lt;/a&gt; to update these values when I changed my theme from &lt;a href=&#34;https://github.com/zyro/hyde-x&#34;&gt;hyde-x&lt;/a&gt; to &lt;a href=&#34;https://github.com/dplesca/purehugo&#34;&gt;purehugo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been keeping my eye on other static site generators as well, but Hugo is very popular and has a lot of great community contributions and support so I&amp;rsquo;ll be using it for a while yet. Now that things are up and running I might take a stab at customizing my theme a little bit more, an opportunity I wouldn&amp;rsquo;t have if Hugo and its public themes weren&amp;rsquo;t open source. Where many static site generators use things like &lt;a href=&#34;http://handlebarsjs.com/&#34;&gt;Handlebars&lt;/a&gt; or &lt;a href=&#34;https://shopify.github.io/liquid/&#34;&gt;Liquid&lt;/a&gt; for templating, Hugo actually delegates straight to the built-in &lt;a href=&#34;https://golang.org/pkg/text/template/&#34;&gt;text.template&lt;/a&gt; package in Go. This makes it immediately familiar to most Go developers, but I haven&amp;rsquo;t had the opportunity to use Go much - especially recently - so I&amp;rsquo;ll likely be spending a lot of time reading the documentation.&lt;/p&gt;
&lt;p&gt;Hopefully this third attempt will be the one that sticks. Stay tuned for more posts on topics including &lt;a href=&#34;https://stuartcrust.com/categories/open-source&#34;&gt;open source&lt;/a&gt;, &lt;a href=&#34;https://stuartcrust.com/categories/nodejs&#34;&gt;NodeJS&lt;/a&gt;, &lt;a href=&#34;https://stuartcrust.com/categories/rust&#34;&gt;Rust&lt;/a&gt;, &lt;a href=&#34;https://stuartcrust.com/categories/functional-programming&#34;&gt;functional programming&lt;/a&gt;, and anything else I might get up to.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
