Skip to content

Commit 43e658c

Browse files
committed
Merge branch 'main' into pr/matifali/7044
2 parents e4ebef4 + af24aea commit 43e658c

File tree

156 files changed

+4430
-2583
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

156 files changed

+4430
-2583
lines changed

.github/workflows/cron-weekly.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Weekly Cron
2+
# runs every monday at 9 am
3+
on:
4+
schedule:
5+
- cron: "0 9 * * 1"
6+
workflow_dispatch: # allows to run manually for testing
7+
8+
jobs:
9+
check-docs:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout
13+
uses: actions/checkout@master
14+
15+
- name: Check Markdown links
16+
uses: gaurav-nelson/github-action-markdown-link-check@v1
17+
id: markdown-link-check
18+
# checks all markdown files from /docs including all subfolders
19+
with:
20+
use-quiet-mode: "yes"
21+
use-verbose-mode: "yes"
22+
config-file: ".github/workflows/mlc_config.json"
23+
folder-path: "docs/"
24+
25+
- name: Send Slack notification
26+
if: failure()
27+
run: |
28+
curl -X POST -H 'Content-type: application/json' -d '{"msg":"Broken links found in the documentation. Please check the logs at ${{ env.LOGS_URL }}"}' ${{ secrets.DOCS_LINK_SLACK_WEBHOOK }}
29+
echo "Sent Slack notification"
30+
env:
31+
LOGS_URL: https://github.com/coder/coder/actions/runs/${{ github.run_id }}

.golangci.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ issues:
194194
linters:
195195
# We use assertions rather than explicitly checking errors in tests
196196
- errcheck
197+
- forcetypeassert
197198

198199
fix: true
199200
max-issues-per-linter: 0

Makefile

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ gen: \
423423
provisionersdk/proto/provisioner.pb.go \
424424
provisionerd/proto/provisionerd.pb.go \
425425
site/src/api/typesGenerated.ts \
426+
coderd/rbac/object_gen.go \
426427
docs/admin/prometheus.md \
427428
docs/cli.md \
428429
docs/admin/audit-logs.md \
@@ -443,6 +444,7 @@ gen/mark-fresh:
443444
provisionersdk/proto/provisioner.pb.go \
444445
provisionerd/proto/provisionerd.pb.go \
445446
site/src/api/typesGenerated.ts \
447+
coderd/rbac/object_gen.go \
446448
docs/admin/prometheus.md \
447449
docs/cli.md \
448450
docs/admin/audit-logs.md \
@@ -495,6 +497,9 @@ site/src/api/typesGenerated.ts: scripts/apitypings/main.go $(shell find ./coders
495497
cd site
496498
yarn run format:types
497499

500+
coderd/rbac/object_gen.go: scripts/rbacgen/main.go coderd/rbac/object.go
501+
go run scripts/rbacgen/main.go ./coderd/rbac > coderd/rbac/object_gen.go
502+
498503
docs/admin/prometheus.md: scripts/metricsdocgen/main.go scripts/metricsdocgen/metrics
499504
go run scripts/metricsdocgen/main.go
500505
cd site
@@ -505,20 +510,20 @@ docs/cli.md: scripts/clidocgen/main.go $(GO_SRC_FILES) docs/manifest.json
505510
cd site
506511
yarn run format:write:only ../docs/cli.md ../docs/cli/*.md ../docs/manifest.json
507512

508-
docs/admin/audit-logs.md: scripts/auditdocgen/main.go enterprise/audit/table.go
513+
docs/admin/audit-logs.md: scripts/auditdocgen/main.go enterprise/audit/table.go coderd/rbac/object_gen.go
509514
go run scripts/auditdocgen/main.go
510515
cd site
511516
yarn run format:write:only ../docs/admin/audit-logs.md
512517

513-
coderd/apidoc/swagger.json: $(shell find ./scripts/apidocgen $(FIND_EXCLUSIONS) -type f) $(wildcard coderd/*.go) $(wildcard enterprise/coderd/*.go) $(wildcard codersdk/*.go) .swaggo docs/manifest.json
518+
coderd/apidoc/swagger.json: $(shell find ./scripts/apidocgen $(FIND_EXCLUSIONS) -type f) $(wildcard coderd/*.go) $(wildcard enterprise/coderd/*.go) $(wildcard codersdk/*.go) .swaggo docs/manifest.json coderd/rbac/object_gen.go
514519
./scripts/apidocgen/generate.sh
515520
yarn run --cwd=site format:write:only ../docs/api ../docs/manifest.json ../coderd/apidoc/swagger.json
516521

517522
update-golden-files: cli/testdata/.gen-golden helm/tests/testdata/.gen-golden scripts/ci-report/testdata/.gen-golden
518523
.PHONY: update-golden-files
519524

520525
cli/testdata/.gen-golden: $(wildcard cli/testdata/*.golden) $(wildcard cli/*.tpl) $(GO_SRC_FILES)
521-
go test ./cli -run=TestCommandHelp -update
526+
go test ./cli -run="Test(CommandHelp|ServerYAML)" -update
522527
touch "$@"
523528

524529
helm/tests/testdata/.gen-golden: $(wildcard helm/tests/testdata/*.golden) $(GO_SRC_FILES)

cli/clibase/clibase.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,10 @@ import (
1414

1515
// Group describes a hierarchy of groups that an option or command belongs to.
1616
type Group struct {
17-
Parent *Group `json:"parent,omitempty"`
18-
Name string `json:"name,omitempty"`
19-
Children []Group `json:"children,omitempty"`
20-
Description string `json:"description,omitempty"`
21-
}
22-
23-
func (g *Group) AddChild(child Group) {
24-
child.Parent = g
25-
g.Children = append(g.Children, child)
17+
Parent *Group `json:"parent,omitempty"`
18+
Name string `json:"name,omitempty"`
19+
YAML string `json:"yaml,omitempty"`
20+
Description string `json:"description,omitempty"`
2621
}
2722

2823
// Ancestry returns the group and all of its parents, in order.

cli/clibase/cmd.go

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/spf13/pflag"
1414
"golang.org/x/exp/slices"
1515
"golang.org/x/xerrors"
16+
"gopkg.in/yaml.v3"
1617
)
1718

1819
// Cmd describes an executable command.
@@ -76,10 +77,8 @@ func (c *Cmd) PrepareAll() error {
7677
}
7778
var merr error
7879

79-
slices.SortFunc(c.Options, func(a, b Option) bool {
80-
return a.Flag < b.Flag
81-
})
82-
for _, opt := range c.Options {
80+
for i := range c.Options {
81+
opt := &c.Options[i]
8382
if opt.Name == "" {
8483
switch {
8584
case opt.Flag != "":
@@ -102,6 +101,10 @@ func (c *Cmd) PrepareAll() error {
102101
}
103102
}
104103
}
104+
105+
slices.SortFunc(c.Options, func(a, b Option) bool {
106+
return a.Name < b.Name
107+
})
105108
slices.SortFunc(c.Children, func(a, b *Cmd) bool {
106109
return a.Name() < b.Name()
107110
})
@@ -262,17 +265,38 @@ func (inv *Invocation) run(state *runState) error {
262265
parsedArgs = inv.parsedFlags.Args()
263266
}
264267

265-
// Set defaults for flags that weren't set by the user.
266-
skipDefaults := make(map[int]struct{}, len(inv.Command.Options))
268+
// Set value sources for flags.
267269
for i, opt := range inv.Command.Options {
268270
if fl := inv.parsedFlags.Lookup(opt.Flag); fl != nil && fl.Changed {
269-
skipDefaults[i] = struct{}{}
271+
inv.Command.Options[i].ValueSource = ValueSourceFlag
272+
}
273+
}
274+
275+
// Read YAML configs, if any.
276+
for _, opt := range inv.Command.Options {
277+
path, ok := opt.Value.(*YAMLConfigPath)
278+
if !ok || path.String() == "" {
279+
continue
270280
}
271-
if opt.envChanged {
272-
skipDefaults[i] = struct{}{}
281+
282+
byt, err := os.ReadFile(path.String())
283+
if err != nil {
284+
return xerrors.Errorf("reading yaml: %w", err)
285+
}
286+
287+
var n yaml.Node
288+
err = yaml.Unmarshal(byt, &n)
289+
if err != nil {
290+
return xerrors.Errorf("decoding yaml: %w", err)
291+
}
292+
293+
err = inv.Command.Options.UnmarshalYAML(&n)
294+
if err != nil {
295+
return xerrors.Errorf("applying yaml: %w", err)
273296
}
274297
}
275-
err = inv.Command.Options.SetDefaults(skipDefaults)
298+
299+
err = inv.Command.Options.SetDefaults()
276300
if err != nil {
277301
return xerrors.Errorf("setting defaults: %w", err)
278302
}

cli/clibase/cmd_test.go

Lines changed: 73 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"fmt"
7+
"os"
78
"strings"
89
"testing"
910

@@ -555,42 +556,80 @@ func TestCommand_EmptySlice(t *testing.T) {
555556
func TestCommand_DefaultsOverride(t *testing.T) {
556557
t.Parallel()
557558

558-
var got string
559-
cmd := &clibase.Cmd{
560-
Options: clibase.OptionSet{
561-
{
562-
Name: "url",
563-
Flag: "url",
564-
Default: "def.com",
565-
Env: "URL",
566-
Value: clibase.StringOf(&got),
567-
},
568-
},
569-
Handler: (func(i *clibase.Invocation) error {
570-
_, _ = fmt.Fprintf(i.Stdout, "%s", got)
571-
return nil
572-
}),
559+
test := func(name string, want string, fn func(t *testing.T, inv *clibase.Invocation)) {
560+
t.Run(name, func(t *testing.T) {
561+
t.Parallel()
562+
563+
var (
564+
got string
565+
config clibase.YAMLConfigPath
566+
)
567+
cmd := &clibase.Cmd{
568+
Options: clibase.OptionSet{
569+
{
570+
Name: "url",
571+
Flag: "url",
572+
Default: "def.com",
573+
Env: "URL",
574+
Value: clibase.StringOf(&got),
575+
YAML: "url",
576+
},
577+
{
578+
Name: "config",
579+
Flag: "config",
580+
Default: "",
581+
Value: &config,
582+
},
583+
},
584+
Handler: (func(i *clibase.Invocation) error {
585+
_, _ = fmt.Fprintf(i.Stdout, "%s", got)
586+
return nil
587+
}),
588+
}
589+
590+
inv := cmd.Invoke()
591+
stdio := fakeIO(inv)
592+
fn(t, inv)
593+
err := inv.Run()
594+
require.NoError(t, err)
595+
require.Equal(t, want, stdio.Stdout.String())
596+
})
573597
}
574598

575-
// Base case
576-
inv := cmd.Invoke()
577-
stdio := fakeIO(inv)
578-
err := inv.Run()
579-
require.NoError(t, err)
580-
require.Equal(t, "def.com", stdio.Stdout.String())
599+
test("DefaultOverNothing", "def.com", func(t *testing.T, inv *clibase.Invocation) {})
581600

582-
// Flag overrides
583-
inv = cmd.Invoke("--url", "good.com")
584-
stdio = fakeIO(inv)
585-
err = inv.Run()
586-
require.NoError(t, err)
587-
require.Equal(t, "good.com", stdio.Stdout.String())
601+
test("FlagOverDefault", "good.com", func(t *testing.T, inv *clibase.Invocation) {
602+
inv.Args = []string{"--url", "good.com"}
603+
})
588604

589-
// Env overrides
590-
inv = cmd.Invoke()
591-
inv.Environ.Set("URL", "good.com")
592-
stdio = fakeIO(inv)
593-
err = inv.Run()
594-
require.NoError(t, err)
595-
require.Equal(t, "good.com", stdio.Stdout.String())
605+
test("EnvOverDefault", "good.com", func(t *testing.T, inv *clibase.Invocation) {
606+
inv.Environ.Set("URL", "good.com")
607+
})
608+
609+
test("FlagOverEnv", "good.com", func(t *testing.T, inv *clibase.Invocation) {
610+
inv.Environ.Set("URL", "bad.com")
611+
inv.Args = []string{"--url", "good.com"}
612+
})
613+
614+
test("FlagOverYAML", "good.com", func(t *testing.T, inv *clibase.Invocation) {
615+
fi, err := os.CreateTemp(t.TempDir(), "config.yaml")
616+
require.NoError(t, err)
617+
defer fi.Close()
618+
619+
_, err = fi.WriteString("url: bad.com")
620+
require.NoError(t, err)
621+
622+
inv.Args = []string{"--config", fi.Name(), "--url", "good.com"}
623+
})
624+
625+
test("YAMLOverDefault", "good.com", func(t *testing.T, inv *clibase.Invocation) {
626+
fi, err := os.CreateTemp(t.TempDir(), "config.yaml")
627+
require.NoError(t, err)
628+
defer fi.Close()
629+
630+
_, err = fi.WriteString("url: good.com")
631+
require.NoError(t, err)
632+
633+
inv.Args = []string{"--config", fi.Name()}
634+
})
596635
}

0 commit comments

Comments
 (0)