From 1371517f10e356ef4c5c1c902872b04e14b2eed9 Mon Sep 17 00:00:00 2001 From: Judah Jacobson Date: Mon, 28 May 2018 21:51:58 -0700 Subject: [PATCH] Update the tutorials. (#195) * Update the tutorials. - Follow-up to #190: Set an explicit stack resolver, now that proto-lens and friends are back in nightly. - Fix some broken cross-links. - Now that #171 is fixed, merge the `person` tutorial into a single package (a library with `Proto.*` modules and an executable that uses them) and make the instructions in the README match the code. * Add proto-lens-protoc as a dependency on the executable. It's not actually needed for Cabal-2.0 (lts-10 or later). But we still have CI for older versions, and it's worth confirming that the example still works on older versions. --- docs/tutorial.md | 4 +- proto-lens-tutorial/coffee-order/README.md | 2 +- proto-lens-tutorial/person/README.md | 86 ++++++++-------------- proto-lens-tutorial/person/package.yaml | 44 +++++------ proto-lens-tutorial/person/src/Main.hs | 3 +- 5 files changed, 54 insertions(+), 85 deletions(-) diff --git a/docs/tutorial.md b/docs/tutorial.md index 71c7e40b..1e88a15e 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -10,8 +10,8 @@ 6. [Repeated](#repeated) 7. [Map](#map) 8. [Lens Laws](#lens-laws) -9. [Example: Person](./person/README.md) -10. [Example: Coffee Order](./coffee-order/README.md) +9. [Example: Person](https://github.com/google/proto-lens/tree/master/proto-lens-tutorial/person) +10. [Example: Coffee Order](https://github.com/google/proto-lens/tree/master/proto-lens-tutorial/coffee-order) ## Message Generation diff --git a/proto-lens-tutorial/coffee-order/README.md b/proto-lens-tutorial/coffee-order/README.md index a68f596f..f851f012 100644 --- a/proto-lens-tutorial/coffee-order/README.md +++ b/proto-lens-tutorial/coffee-order/README.md @@ -1,6 +1,6 @@ # Coffee Order Example -In this example we will go through a more complicated data structure compared to our [Person Example](https://github.com/FintanH/proto-lens/blob/docs/codelab/proto-lens-tutorial/person/README.md). +In this example we will go through a more complicated data structure compared to our [Person Example](../person/README.md). ## Table of Contents diff --git a/proto-lens-tutorial/person/README.md b/proto-lens-tutorial/person/README.md index a86cd28f..8889128f 100644 --- a/proto-lens-tutorial/person/README.md +++ b/proto-lens-tutorial/person/README.md @@ -17,7 +17,7 @@ In this section we will go through how to setup a package with a simple definiti 3. [Did We Miss Something?](#did-we-miss-something) ## Tutorial: Setting Up a Basic Package -In this tutorial we are going to visit how to set up `proto-lens` and all its goodness. The directory structure differs between this code lab and the git directory itself. The code remains the same nonetheless. +In this tutorial we are going to visit how to set up `proto-lens` and all its goodness. The result will match the contents of this git directory. ### Setup @@ -27,14 +27,12 @@ I am going to use `stack` and `hpack` to set things up. So here we go: The command to follow will create a basic Haskell directory structure for a [stack](https://docs.haskellstack.org/en/stable/README/) project. It will use `hpack` which is a way of defining your project in a `.yaml` file which generates a `.cabal` file upon `stack build`. After this we `cd` into the directory created. -`stack new person simple-hpack && cd person` +`stack --resolver nightly-2018-05-09 new person simple-hpack && cd person` -#### 2. Setup Proto +We'll make a single package in this example, so we can leave the autogenerated `stack.yaml` as-is. -Now we have our top level project we are going to create a `proto` package inside: -`stack new proto simple-hpack` - -We will setup the stuff in this project first before coming back to `person`. In our `proto/src` directory we will remove `Main.hs` and replace it with a `person.proto` file with the following contents: +#### 2. Generate Haskell sources from proto files +Now we have our top level project, we will start with creating a directory `proto` to contain all of our files, and a file `person.proto` inside that directory with the following contents: ``` protobuf syntax="proto3"; @@ -53,20 +51,22 @@ message Address { } ``` -Next we will edit the `package.yaml` file to add in the things we need: +Next we will edit the `package.yaml` file to set up code generation: ``` yaml -name: person-proto +name: person custom-setup: - dependencies: base, Cabal, proto-lens-protoc + dependencies: + - base + - Cabal + - proto-lens-protoc -extra-source-files: src/**/*.proto +extra-source-files: proto/**/*.proto library: dependencies: - base - - proto-lens - proto-lens-protoc exposed-modules: @@ -81,51 +81,12 @@ The last thing we need to do here is edit `Setup.hs` to have: ``` haskell import Data.ProtoLens.Setup -main = defaultMainGeneratingProtos "src" +main = defaultMainGeneratingProtos "proto" ``` -#### 3. Setup Person - -Here we are going to be telling `person` how to find the proto stuff we just setup. We will edit the `stack.yaml` file as follows: - -Under `packages` we should have: - -``` yaml -packages: -- . -- proto -``` - -Then we will add `person-proto`, along with `default-data`, `microlens`, and `proto-lens`, to our dependencies in our main project like so: - -``` yaml -name: person -version: 0.1.0.0 -#synopsis: -#description: -homepage: https://github.com/githubuser/person#readme -license: BSD3 -author: Author name here -maintainer: example@example.com -copyright: 2017 Author name here -category: Web -extra-source-files: -- README.md - -dependencies: - - base >= 4.7 && < 5 - - person-proto - - data-default - - microlens - - proto-lens - -executables: - person: - source-dirs: src - main: Main.hs -``` +#### 3. Use the autogenerated modules in an executable -Alright! We are going to test this puppy out! We will make a `Main.hs` in our main project so we can create and print some stuff out! +Alright! We are going to test this puppy out! We will make a file `src/Main.hs` so we can create and print some stuff out! ``` haskell {-# LANGUAGE OverloadedStrings #-} @@ -134,8 +95,7 @@ module Main where import Proto.Person as P import Proto.Person_Fields as P -import Data.Default -import Data.ProtoLens (showMessage) +import Data.ProtoLens (def, showMessage) import Lens.Micro person :: P.Person @@ -155,6 +115,20 @@ main = do putStrLn . showMessage $ person ``` +Then, we'll put it in an `executable` section to `package.yaml` that specifies its dependencies. They include the library we created above (`person`) along with `microlens` and `proto-lens` + +``` yaml +executables: + person: + main: Main.hs + source-dirs: '.' + dependencies: + - base + - person + - microlens + - proto-lens +``` + ### Troubleshooting You may run into issues with not being able to find names and what not when trying to run `stack build`. If this is occurring then try do a `stack clean --full` and try `stack build` again. diff --git a/proto-lens-tutorial/person/package.yaml b/proto-lens-tutorial/person/package.yaml index 5a9c65d3..246e0360 100644 --- a/proto-lens-tutorial/person/package.yaml +++ b/proto-lens-tutorial/person/package.yaml @@ -1,14 +1,4 @@ -name: person -version: 0.1.0.0 -homepage: https://github.com/google/proto-lens-tutorial/person#readme -license: BSD3 -author: Fintan Halpenny -maintainer: fintan.halpenny@gmail.com -copyright: 2017 Google Inc. -category: Data -extra-source-files: -- README.md -- proto/**/*.proto +name: person custom-setup: dependencies: @@ -16,21 +6,27 @@ custom-setup: - Cabal - proto-lens-protoc -dependencies: - - base >= 4.7 && < 5 - - data-default - - microlens - - proto-lens - - proto-lens-protoc - - lens-labels - - text +extra-source-files: proto/**/*.proto + +library: + dependencies: + - base + - proto-lens-protoc + + exposed-modules: + - Proto.Person + - Proto.Person_Fields executables: person: + main: Main.hs + source-dirs: + - src dependencies: + - base + - person + - microlens + - proto-lens + # The following dependency works around a bug with Cabal-1.*. It is not + # needed with Cabal-2.0 or later (stack lts-10.0 or later). - proto-lens-protoc - other-modules: - - Proto.Person - - Proto.Person_Fields - source-dirs: src - main: Main.hs diff --git a/proto-lens-tutorial/person/src/Main.hs b/proto-lens-tutorial/person/src/Main.hs index 392ecfc6..2302f693 100644 --- a/proto-lens-tutorial/person/src/Main.hs +++ b/proto-lens-tutorial/person/src/Main.hs @@ -4,8 +4,7 @@ module Main where import Proto.Person as P import Proto.Person_Fields as P -import Data.Default -import Data.ProtoLens (showMessage) +import Data.ProtoLens (def, showMessage) import Lens.Micro person :: P.Person