Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add docs/ folder and an intro tutorial #958

Merged
merged 5 commits into from
Oct 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
ignore:
- "docs/get-started/*/main.go"

coverage:
range: 80..100
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,9 @@ jobs:
- name: Test
run: make cover

- name: Test documentation
run: make cover COVER_MODULES=./docs
if: matrix.latest

- name: Upload coverage to codecov.io
uses: codecov/codecov-action@v1
19 changes: 16 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ export GOBIN ?= $(shell pwd)/bin
GOLINT = $(GOBIN)/golint
STATICCHECK = $(GOBIN)/staticcheck
FXLINT = $(GOBIN)/fxlint
MDOX = $(GOBIN)/mdox

GO_FILES = $(shell \
find . '(' -path '*/.*' -o -path './vendor' -o -path '*/testdata/*' ')' -prune \
-o -name '*.go' -print | cut -b3-)

MODULES = . ./tools
MODULES = . ./tools ./docs

# 'make cover' should not run on docs by default.
# We run that separately explicitly on a specific platform.
COVER_MODULES ?= $(filter-out ./docs,$(MODULES))

.PHONY: build
build:
Expand All @@ -24,7 +29,7 @@ test:

.PHONY: cover
cover:
@$(foreach dir,$(MODULES), \
@$(foreach dir,$(COVER_MODULES), \
(cd $(dir) && \
echo "[cover] $(dir)" && \
go test -race -coverprofile=cover.out -coverpkg=./... ./... && \
Expand All @@ -36,11 +41,14 @@ $(GOLINT): tools/go.mod
$(STATICCHECK): tools/go.mod
cd tools && go install honnef.co/go/tools/cmd/staticcheck

$(MDOX): tools/go.mod
cd tools && go install github.com/bwplotka/mdox

$(FXLINT): tools/cmd/fxlint/main.go
cd tools && go install go.uber.org/fx/tools/cmd/fxlint

.PHONY: lint
lint: $(GOLINT) $(STATICCHECK) $(FXLINT)
lint: $(GOLINT) $(STATICCHECK) $(FXLINT) docs-check
@rm -rf lint.log
@echo "Checking formatting..."
@gofmt -d -s $(GO_FILES) 2>&1 | tee lint.log
Expand All @@ -64,6 +72,11 @@ lint: $(GOLINT) $(STATICCHECK) $(FXLINT)
git --no-pager diff; \
fi

.PHONY: docs-check
docs-check: $(MDOX)
@echo "Checking documentation"
@make -C docs check | tee -a lint.log

.PHONY: tidy
tidy:
@$(foreach dir,$(MODULES),(cd $(dir) && go mod tidy) &&) true
33 changes: 15 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
# :unicorn: Fx [![GoDoc][doc-img]][doc] [![Github release][release-img]][release] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Go Report Card](https://goreportcard.com/badge/go.uber.org/fx)](https://goreportcard.com/report/go.uber.org/fx)
# :unicorn: Fx [![GoDoc](https://pkg.go.dev/badge/go.uber.org/fx)](https://pkg.go.dev/go.uber.org/fx) [![Github release](https://img.shields.io/github/release/uber-go/fx.svg)](https://github.com/uber-go/fx/releases) [![Build Status](https://github.com/uber-go/fx/actions/workflows/go.yml/badge.svg)](https://github.com/uber-go/fx/actions/workflows/go.yml) [![Coverage Status](https://codecov.io/gh/uber-go/fx/branch/master/graph/badge.svg)](https://codecov.io/gh/uber-go/fx/branch/master) [![Go Report Card](https://goreportcard.com/badge/go.uber.org/fx)](https://goreportcard.com/report/go.uber.org/fx)

An application framework for Go that:
Fx is a dependency injection system for Go.

- Makes dependency injection easy.
- Eliminates the need for global state and `func init()`.
**Benefits**

- Eliminate globals: Fx helps you remove global state from your application.
No more `init()` or global variables. Use Fx-managed singletons.
- Code reuse: Fx lets teams within your organization build loosely-coupled
and well-integrated shareable components.
- Battle tested: Fx is the backbone of nearly all Go services at Uber.

## Installation

We recommend locking to [SemVer](http://semver.org/) range `^1` using [go mod](https://github.com/golang/go/wiki/Modules):
Use Go modules to install Fx in your application.

```shell
go get go.uber.org/fx@v1
```

## Getting started

To get started with Fx, [start here](docs/get-started/README.md).

## Stability

This library is `v1` and follows [SemVer](http://semver.org/) strictly.

No breaking changes will be made to exported APIs before `v2.0.0`.

This project follows the [Go Release Policy][release-policy]. Each major
This project follows the [Go Release Policy](https://golang.org/doc/devel/release.html#policy). Each major
version of Go is supported until there are two newer major releases.

[doc-img]: https://pkg.go.dev/badge/go.uber.org/fx
[doc]: https://pkg.go.dev/go.uber.org/fx
[release-img]: https://img.shields.io/github/release/uber-go/fx.svg
[release]: https://github.com/uber-go/fx/releases
[ci-img]: https://github.com/uber-go/fx/actions/workflows/go.yml/badge.svg
[ci]: https://github.com/uber-go/fx/actions/workflows/go.yml
[cov-img]: https://codecov.io/gh/uber-go/fx/branch/master/graph/badge.svg
[cov]: https://codecov.io/gh/uber-go/fx/branch/master
[report-card-img]: https://goreportcard.com/badge/github.com/uber-go/fx
[report-card]: https://goreportcard.com/report/github.com/uber-go/fx
[release-policy]: https://golang.org/doc/devel/release.html#policy
164 changes: 164 additions & 0 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Contributing to Fx Documentation

If you'd like to contribute to Fx's documentation, read this first.

## Document by purpose

Documentation in this folder should fall in one of the following categories.

- **Tutorials**: These hold step-by-step instructions for an end-to-end project
that a beginner could follow along to.
Don't spend time explaining things.
If explanations are available elsewhere, link to them.
These are entry points to answer the prompt,
"I don't know what Fx is, show me what it can do,"
so there won't be too many of these.
- **Explanations**: These hold long-form explanations of concepts and ideas.
These are intended to build an understanding of Fx.
Feel free to go wild here--use learning aids like diagrams, tables, etc.
- **How-tos**: These are step-by-step instructions for a *specific problem*.
Unlike tutorials, these are not meant to be end-to-end.
Feel free to leave things out, make assumptions,
or provide options ("if you're doing this, do this").
As with tutorials, don't spend time explaining;
link to explanations elsewhere.

As an example,

- A tutorial will use lifecycle hooks as part of
a larger set of instructions for a full end-to-end application.
- An explanation will explain what lifecycle hooks are, how they work,
when and how you should use them, and link to relevant APIs and guides.
- A how-to guide will demonstrate how to use lifecycle hooks
with an HTTP server, a gRPC server, etc.

This separation is inspired by the
[Divio documentation system](https://documentation.divio.com/),
which suggests separating documentation into four categories:
the three above, and references, which we get from our generated API reference.

## Formatting

### GitHub Flavored Markdown

The documentation is hosted on GitHub,
and therefore it follows [GitHub Flavored Markdown](https://github.github.com/gfm/).

### ATX-style headers

Use ATX-style headers (`#`-prefixed),
not Setext-style (underlined with `===` or `---`).

```markdown
Bad header
==========

# Good header
```

### Semantic Line Breaks

- **Do not** write overly long lines of text
- **Do not** "reflow" Markdown paragraphs
- **Do** use [Semantic Line Breaks](https://sembr.org/) to break these lines down

```markdown
This is a bad paragraph because it's really long, all on one line. When I open this in a text editor, I'll have to scroll right.

This is a bad paragraph because even though it's not all one one line, it adds
line breaks when it reaches the line length limit. This means that anytime I
change anything in this paragraph, I have to "reflow" it, which will change
other lines and make the change I'm making more difficult to review.

This is a good paragraph. It uses semantic line breaks.
I can add words or modify an existing sentence,
or even parts of a sentence,
easily and without affecting other lines.
When I change something, the actual change I made is easy to review.
Markdown will reflow this into a "normal" pargraph when rendering.
```

## Test everything

All code samples in documentation must be buildable and testable.

To aid in this, we have two tools:

- [mdox] lets us ensure that the contents of a code block are up-to-date
- the `region` shell script allows us to extract parts of a code sample

### mdox

mdox is a Markdown file formatter that includes support for
running a command and using its output as part of a code block.
To use this, declare a regular code block and tag it with `mdoc-exec`.

```markdown
```go mdox-exec="cat foo.go"
// doesn't matter
```

The contents of the code block will be replaced
with the output of the command when you run `make fmt`.
`make check` will ensure that the contents are up-to-date.

The command runs inside the directory where the Markdown file resides.
All paths should be relative to that directory.

### region

The `region` shell script is a command intended to be used with `mdox-exec`.

```plain mdox-exec="region" mdox-expect-exit-code="1"
USAGE: region FILE REGION1 REGION2 ...

Extracts text from FILE marked by "// region" blocks.
```

For example, given the file:

```
foo
// region myregion
bar
// endregion myregion
baz
```

Running `region $FILE myregion` will print:

```
bar
```

The same region name may be used multiple times
to pull different snippets from the same file.
For example, given the file:

```go
// region provide-foo
func main() {
fx.New(
fx.Provide(
NewFoo,
// endregion provide-foo
NewBar,
// region provide-foo
),
).Run()
}

// endregion provide-foo
```

`region $FILE provide-foo` will print,

```go
func main() {
fx.New(
fx.Provide(
NewFoo,
),
).Run()
}
```
22 changes: 22 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export PATH := $(shell pwd)/bin:$(PATH)

MDOX = $(shell pwd)/../bin/mdox
MDOX_FMT_FLAGS = --soft-wraps --links.validate
MD_FILES = $(shell find . -name '*.md') ../README.md

.PHONY:
fmt: $(MDOX)
@$(foreach FILE,$(MD_FILES), \
(cd $(dir $(FILE)) && \
echo "[mdox fmt] $(FILE)" && \
$(MDOX) fmt $(MDOX_FMT_FLAGS) $(notdir $(FILE)));)

.PHONY:
check: $(MDOX)
@$(foreach FILE,$(MD_FILES), \
(cd $(dir $(FILE)) && \
echo "[mdox check] $(FILE)" && \
$(MDOX) fmt --check $(MDOX_FMT_FLAGS) $(notdir $(FILE)));)

$(MDOX):
make -C .. $(shell pwd)/bin/mdox
38 changes: 38 additions & 0 deletions docs/bin/region
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

if [[ $# -ne 2 ]]; then
echo >&2 'USAGE: region FILE REGION1 REGION2 ...'
echo >&2
echo >&2 'Extracts text from FILE marked by "// region" blocks.'
exit 1
fi

file="$1"; shift

args=(-n)
for region in "$@"; do
# sed syntax:
# We can either use /regex/, or \CregexC for any C.
# Since we need to match on "//", we use "#" as the regex delimiter.
#
# And we can use $expr1,$expr2p to say "print lines inside that
# region."
open='\#// region '"$region"'$#'
close='\#// endregion '"$region"'$#'
args+=(-e "${open},${close}p")
done

sed -n "${args[@]}" "$file" |
grep -Ev '// (end)?region \S+$' |
perl -ne '
# Remove a leading/trailing empty line, if any.
if ((!$saw_first || eof) && /^\s*$/) {
next;
}
$saw_first = true;

s/\t/ /g;
print;
'
31 changes: 31 additions & 0 deletions docs/get-started/01-minimal/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2022 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// region main

package main

import "go.uber.org/fx"

func main() {
fx.New().Run()
}

// endregion main
Loading