github.com/simpleiot/simpleiot@v0.18.3/docs/ref/development.md (about)

     1  # Development
     2  
     3  ## Go Package Documentation
     4  
     5  The Simple IoT source code is
     6  [available](https://github.com/simpleiot/simpleiot) on Github.
     7  
     8  Simple IoT is written in Go.
     9  [Go package documentation](https://pkg.go.dev/github.com/simpleiot/simpleiot) is
    10  available.
    11  
    12  ## Building Simple IoT
    13  
    14  Requirements:
    15  
    16  - Go
    17  - Node/NPM
    18  
    19  Simple IoT build has currently been testing on Linux and MacOS systems. See
    20  [`envsetup.sh`](https://github.com/simpleiot/simpleiot/blob/master/envsetup.sh)
    21  for scripts used in building.
    22  
    23  To build:
    24  
    25  - `source envsetup.sh`
    26  - `siot_setup`
    27  - `siot_build`
    28  
    29  ## Developing Simple IoT
    30  
    31  - `npm install -g run-pty`
    32  - `. envsetup.sh`
    33  - `siot_setup`
    34  - `siot_watch`
    35  
    36  The `siot_watch` command can be used when developing Simple IoT. This does the
    37  following:
    38  
    39  - starts [`elm-watch`](https://github.com/lydell/elm-watch) on the Elm code.
    40    `elm-watch` will automatically update the UI without losing state any time an
    41    Elm file changes.
    42  - runs the Go backend and rebuilds it anytime a Go module changes (only tested
    43    on Linux and MacOS, but should be easy to set up Windows as well)
    44  
    45  Both of the above are run in a [run-pty](https://github.com/lydell/run-pty)
    46  wrapper, which allows you to see the output of either process. The output of the
    47  Elm compile is displayed in the browser, so it is rarely necessary to view the
    48  `elm-watch` side.
    49  
    50  ## Using Simple IoT as a library
    51  
    52  Simple IoT can be used a library for your custom application. The siot
    53  [main.go](https://github.com/simpleiot/simpleiot/blob/master/cmd/siot/main.go)
    54  illustrates how to start the SIOT server, and add clients. You can do this from
    55  any Go application. With a few lines of code, this gives you a lot of
    56  functionality including a NATS server.
    57  
    58  ## Developing a new SIOT client
    59  
    60  Most SIOT functionality is implemented in clients. See the [client](client.md)
    61  documentation for more information.
    62  
    63  ## Customizing the UI
    64  
    65  Currently, there is no simple way to customize the SIOT UI when using SIOT as a
    66  library package. Forking and changing the SIOT Elm code is probably the simplest
    67  way if you want to make a small change now.
    68  
    69  In the future, we plan to provide an API for passing in a custom UI to the SIOT
    70  Server. You can also implement a custom http client that serves up a custom UI.
    71  
    72  ## Code Organization
    73  
    74  Currently, there are a lot of subdirectories. One reason for this is to limit
    75  the size of application binaries when building edge/embedded Linux binaries. In
    76  some use cases, we want to deploy app updates over cellular networks, therefore
    77  we want to keep packages as small as possible. For instance, if we put the
    78  `natsserver` stuff in the `nats` package, then app binaries grow a couple MB,
    79  even if you don't start a NATS server. It is not clear yet what Go does for dead
    80  code elimination, but at this point, it seems referencing a package increases
    81  the binary size, even if you don't use anything in it. (Clarification welcome!)
    82  
    83  For edge applications on Embedded Linux, we'd eventually like to get rid of
    84  net/http, since we can do all network communications over NATS. We're not there
    85  yet, but be careful about pulling in dependencies that require net/http into the
    86  NATS package, and other low level packages intended for use on devices.
    87  
    88  ### Directories
    89  
    90  See Go docs
    91  [directory descriptions](https://pkg.go.dev/github.com/simpleiot/simpleiot#section-directories)
    92  
    93  ## Coding Standards
    94  
    95  Please run `siot_test` from `envsetup.sh` before submitting pull requests. All
    96  code should be formatted and linted before committing.
    97  
    98  Please configure your editor to run code formatters:
    99  
   100  - **Go**: `goimports`
   101  - **Elm**: `elm-format`
   102  - **Markdown**: `prettier` (note, there is a `.prettierrc` in this project that
   103    configures prettier to wrap markdown to 80 characters. Whether to wrap
   104    markdown or not is debatable, as wrapping can make diffs harder to read, but
   105    Markdown is much more pleasant to read in an editor if it is wrapped. Since
   106    more people will be reading documentation than reviewing, lets optimize for
   107    the reading in all scenarios -- editor, Github, and generated docs)
   108  
   109  ## Pure Go
   110  
   111  We plan to keep the main Simple IoT application a pure Go binary if possible.
   112  Statically linked pure Go has huge advantages:
   113  
   114  1. you can easily cross compile to any target from any build machine.
   115  2. blazing fast compile times
   116  3. deployment is dead simple – zero dependencies. Docker is not needed.
   117  4. you are not vulnerable to security issues in the host systems SSL/TLS libs.
   118     What you deploy is pretty much what you get.
   119  5. although there is high quality code written in C/C++, it is much easier to
   120     write safe, reliable programs in Go, so I think long term there is much less
   121     risk using a Go implementation of about anything – especially if it is widely
   122     used.
   123  6. Go’s network programming model is much simpler than about anything else.
   124     Simplicity == less bugs.
   125  
   126  Once you link to C libs in your Go program, you forgo many of the benefits of
   127  Go. The Go authors made a brilliant choice when they chose to build Go from the
   128  ground up. Yes, you loose the ability to easily use some of the popular C
   129  libraries, but what you gain is many times more valuable.
   130  
   131  ## Running unit tests
   132  
   133  There are not a lot of unit tests in the project yet, but below are some
   134  examples of running tests:
   135  
   136  - test everything: `go test -race ./...`
   137  - test only client directory: `go test -race ./client`
   138  - run only a specific: `go test -race ./client -run BackoffTest (run takes a
   139    RegEx)
   140  - `siot_test` runs tests as well as vet/lint, frontend tests, etc.
   141  
   142  The leading `./` is important, otherwise Go things you are giving it a package
   143  name, not a directory. The `...` tells Go to recursively test all subdirs.
   144  
   145  ## Document and test during development
   146  
   147  It is much more pleasant to write documentation and tests as you develop, rather
   148  than after the fact. These efforts add value to your development if done
   149  concurrently. Quality needs to be
   150  [designed-in](https://community.tmpdir.org/t/podcast-280-cristiano-amon-qualcomm-ceo-lex-fridman-podcast/515),
   151  and
   152  [leading with documentation](https://handbook.tmpdir.org/documentation/lead-with-documentation.html)
   153  will result in
   154  [better thinking](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/leslie_lamport.pdf)
   155  and a better product.
   156  
   157  If you develop a feature, please update/create any needed documentation and
   158  write any tests (especially end-to-end) to verify the feature works and
   159  continues to work.