From e77adb1f30f2761cc0e025c1f313b64ffe36a05e Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 18 Nov 2021 10:55:19 -0500 Subject: [PATCH] tour: serve from cmd/golangorg as go.dev/tour tour.golang.org is the last independent server in this repository and almost the last golang.org domain with user-facing content. (talks.golang.org remains.) We need to keep golang.org/x/website/tour as a runnable binary, but move the logic into internal/tour so it can be used from both the tour binary and cmd/golangorg. After this is deployed, we will need to delete the current tour app from the golang-org project, and then requests for tour.golang.org will default to the main server (cmd/golangorg). This will make the tour available in China for the first time, at golang.google.cn/tour. Change-Id: I0f025d8ae89e12489d26bb3bc380a833eeb57bcc Reviewed-on: https://go-review.googlesource.com/c/website/+/365100 Trust: Russ Cox Reviewed-by: Jamal Carvalho --- .../content => _content/tour}/basics.article | 0 .../tour}/basics/basic-types.go | 0 .../tour}/basics/constants.go | 0 .../tour}/basics/exported-names.go | 0 .../tour}/basics/functions-continued.go | 0 .../tour}/basics/functions.go | 0 .../tour}/basics/imports.go | 0 .../tour}/basics/multiple-results.go | 0 .../tour}/basics/named-results.go | 0 .../tour}/basics/numeric-constants.go | 0 .../tour}/basics/packages.go | 0 .../basics/short-variable-declarations.go | 0 .../tour}/basics/type-conversions.go | 0 .../tour}/basics/type-inference.go | 0 .../basics/variables-with-initializers.go | 0 .../tour}/basics/variables.go | 0 .../content => _content/tour}/basics/zero.go | 0 .../tour}/concurrency.article | 2 +- .../tour}/concurrency/buffered-channels.go | 0 .../tour}/concurrency/channels.go | 0 .../tour}/concurrency/default-selection.go | 0 .../exercise-equivalent-binary-trees.go | 0 .../tour}/concurrency/exercise-web-crawler.go | 0 .../tour}/concurrency/goroutines.go | 0 .../tour}/concurrency/mutex-counter.go | 0 .../tour}/concurrency/range-and-close.go | 0 .../tour}/concurrency/select.go | 0 .../content => _content/tour}/content_test.go | 2 +- .../tour}/flowcontrol.article | 0 .../tour}/flowcontrol/defer-multi.go | 0 .../tour}/flowcontrol/defer.go | 0 .../exercise-loops-and-functions.go | 0 .../tour}/flowcontrol/for-continued.go | 0 .../tour}/flowcontrol/for-is-gos-while.go | 0 .../tour}/flowcontrol/for.go | 0 .../tour}/flowcontrol/forever.go | 0 .../tour}/flowcontrol/if-and-else.go | 0 .../flowcontrol/if-with-a-short-statement.go | 0 .../tour}/flowcontrol/if.go | 0 .../flowcontrol/switch-evaluation-order.go | 0 .../flowcontrol/switch-with-no-condition.go | 0 .../tour}/flowcontrol/switch.go | 0 {tour/content => _content/tour}/img/tree.png | Bin .../content => _content/tour}/methods.article | 0 .../tour}/methods/empty-interface.go | 0 .../tour}/methods/errors.go | 0 .../tour}/methods/exercise-errors.go | 0 .../tour}/methods/exercise-images.go | 0 .../tour}/methods/exercise-reader.go | 0 .../tour}/methods/exercise-rot-reader.go | 0 .../tour}/methods/exercise-stringer.go | 0 .../tour}/methods/images.go | 0 .../tour}/methods/indirection-values.go | 0 .../tour}/methods/indirection.go | 0 .../methods/interface-values-with-nil.go | 0 .../tour}/methods/interface-values.go | 0 .../interfaces-are-satisfied-implicitly.go | 0 .../tour}/methods/interfaces.go | 0 .../tour}/methods/methods-continued.go | 0 .../tour}/methods/methods-funcs.go | 0 .../methods/methods-pointers-explained.go | 0 .../tour}/methods/methods-pointers.go | 0 .../methods/methods-with-pointer-receivers.go | 0 .../tour}/methods/methods.go | 0 .../tour}/methods/nil-interface-values.go | 0 .../tour}/methods/reader.go | 0 .../tour}/methods/stringer.go | 0 .../tour}/methods/type-assertions.go | 0 .../tour}/methods/type-switches.go | 0 .../tour}/moretypes.article | 0 .../tour}/moretypes/append.go | 0 .../tour}/moretypes/array.go | 0 .../moretypes/exercise-fibonacci-closure.go | 0 .../tour}/moretypes/exercise-maps.go | 0 .../tour}/moretypes/exercise-slices.go | 0 .../tour}/moretypes/function-closures.go | 0 .../tour}/moretypes/function-values.go | 0 .../tour}/moretypes/making-slices.go | 0 .../tour}/moretypes/map-literals-continued.go | 0 .../tour}/moretypes/map-literals.go | 0 .../tour}/moretypes/maps.go | 0 .../tour}/moretypes/mutating-maps.go | 0 .../tour}/moretypes/nil-slices.go | 0 .../tour}/moretypes/pointers.go | 0 .../tour}/moretypes/range-continued.go | 0 .../tour}/moretypes/range.go | 0 .../tour}/moretypes/slice-bounds.go | 0 .../tour}/moretypes/slice-len-cap.go | 0 .../tour}/moretypes/slice-literals.go | 0 .../tour}/moretypes/slices-of-slice.go | 0 .../tour}/moretypes/slices-pointers.go | 0 .../tour}/moretypes/slices.go | 0 .../tour}/moretypes/struct-fields.go | 0 .../tour}/moretypes/struct-literals.go | 0 .../tour}/moretypes/struct-pointers.go | 0 .../tour}/moretypes/structs.go | 0 {tour => _content/tour}/solutions/README | 0 .../tour}/solutions/binarytrees.go | 0 .../tour}/solutions/binarytrees_quit.go | 0 {tour => _content/tour}/solutions/errors.go | 0 {tour => _content/tour}/solutions/fib.go | 0 {tour => _content/tour}/solutions/http.go | 0 {tour => _content/tour}/solutions/image.go | 0 {tour => _content/tour}/solutions/loops.go | 0 {tour => _content/tour}/solutions/maps.go | 0 {tour => _content/tour}/solutions/readers.go | 0 {tour => _content/tour}/solutions/rot13.go | 0 {tour => _content/tour}/solutions/slices.go | 0 .../tour}/solutions/stringers.go | 0 .../tour}/solutions/webcrawler.go | 0 {tour => _content/tour}/static/css/app.css | 23 +++-- .../tour}/static/img/favicon.ico | Bin {tour => _content/tour}/static/img/gopher.png | Bin {tour => _content/tour}/static/js/app.js | 28 +++--- .../tour}/static/js/controllers.js | 4 +- .../tour}/static/js/directives.js | 12 +-- _content/tour/static/js/page.js | 23 +++++ {tour => _content/tour}/static/js/services.js | 2 +- {tour => _content/tour}/static/js/values.js | 0 .../tour}/static/lib/angular-ui.min.js | 0 .../tour}/static/lib/angular.min.js | 0 .../tour}/static/lib/codemirror/AUTHORS | 0 .../tour}/static/lib/codemirror/LICENSE | 0 .../tour/static/lib/codemirror/README | 0 .../static/lib/codemirror/lib/codemirror.css | 0 .../static/lib/codemirror/lib/codemirror.js | 0 .../tour}/static/lib/codemirror/mode/go/go.js | 0 .../tour}/static/lib/jquery-ui.min.js | 0 .../tour}/static/lib/jquery.min.js | 0 .../tour}/static/partials/editor.html | 0 .../static/partials/feedback-button.html | 0 _content/tour/static/partials/lesson.html | 4 + .../tour}/static/partials/list.html | 2 +- .../tour}/static/partials/toc-button.html | 0 .../tour}/static/partials/toc.html | 2 +- {tour => _content/tour}/template/action.tmpl | 0 _content/tour/template/index.tmpl | 33 ++++++++ .../content => _content/tour}/welcome.article | 0 .../tour}/welcome/hello.go | 0 .../tour}/welcome/sandbox.go | 0 cmd/golangorg/csp.go | 44 ++++++---- cmd/golangorg/server.go | 10 ++- cmd/golangorg/testdata/tour.txt | 8 ++ content.go | 14 ++- internal/redirect/redirect.go | 3 +- internal/redirect/redirect_test.go | 1 - {tour => internal/tour}/appengine.go | 35 ++------ {tour => internal/tour}/fmt.go | 6 +- {tour => internal/tour}/local.go | 54 ++++++------ {tour => internal/tour}/server_test.go | 7 +- internal/tour/testdata/tour.txt | 6 ++ {tour => internal/tour}/tour.go | 80 ++++++++++-------- tour/README.md | 13 +-- tour/TRANSLATE | 2 +- tour/app.yaml | 19 ----- tour/cloudbuild.yaml | 19 ----- tour/codereview.cfg | 1 - tour/main.go | 11 +++ tour/static/partials/lesson.html | 4 - tour/template/index.tmpl | 55 ------------ tour/testdata/tour.txt | 3 - 161 files changed, 260 insertions(+), 272 deletions(-) rename {tour/content => _content/tour}/basics.article (100%) rename {tour/content => _content/tour}/basics/basic-types.go (100%) rename {tour/content => _content/tour}/basics/constants.go (100%) rename {tour/content => _content/tour}/basics/exported-names.go (100%) rename {tour/content => _content/tour}/basics/functions-continued.go (100%) rename {tour/content => _content/tour}/basics/functions.go (100%) rename {tour/content => _content/tour}/basics/imports.go (100%) rename {tour/content => _content/tour}/basics/multiple-results.go (100%) rename {tour/content => _content/tour}/basics/named-results.go (100%) rename {tour/content => _content/tour}/basics/numeric-constants.go (100%) rename {tour/content => _content/tour}/basics/packages.go (100%) rename {tour/content => _content/tour}/basics/short-variable-declarations.go (100%) rename {tour/content => _content/tour}/basics/type-conversions.go (100%) rename {tour/content => _content/tour}/basics/type-inference.go (100%) rename {tour/content => _content/tour}/basics/variables-with-initializers.go (100%) rename {tour/content => _content/tour}/basics/variables.go (100%) rename {tour/content => _content/tour}/basics/zero.go (100%) rename {tour/content => _content/tour}/concurrency.article (99%) rename {tour/content => _content/tour}/concurrency/buffered-channels.go (100%) rename {tour/content => _content/tour}/concurrency/channels.go (100%) rename {tour/content => _content/tour}/concurrency/default-selection.go (100%) rename {tour/content => _content/tour}/concurrency/exercise-equivalent-binary-trees.go (100%) rename {tour/content => _content/tour}/concurrency/exercise-web-crawler.go (100%) rename {tour/content => _content/tour}/concurrency/goroutines.go (100%) rename {tour/content => _content/tour}/concurrency/mutex-counter.go (100%) rename {tour/content => _content/tour}/concurrency/range-and-close.go (100%) rename {tour/content => _content/tour}/concurrency/select.go (100%) rename {tour/content => _content/tour}/content_test.go (96%) rename {tour/content => _content/tour}/flowcontrol.article (100%) rename {tour/content => _content/tour}/flowcontrol/defer-multi.go (100%) rename {tour/content => _content/tour}/flowcontrol/defer.go (100%) rename {tour/content => _content/tour}/flowcontrol/exercise-loops-and-functions.go (100%) rename {tour/content => _content/tour}/flowcontrol/for-continued.go (100%) rename {tour/content => _content/tour}/flowcontrol/for-is-gos-while.go (100%) rename {tour/content => _content/tour}/flowcontrol/for.go (100%) rename {tour/content => _content/tour}/flowcontrol/forever.go (100%) rename {tour/content => _content/tour}/flowcontrol/if-and-else.go (100%) rename {tour/content => _content/tour}/flowcontrol/if-with-a-short-statement.go (100%) rename {tour/content => _content/tour}/flowcontrol/if.go (100%) rename {tour/content => _content/tour}/flowcontrol/switch-evaluation-order.go (100%) rename {tour/content => _content/tour}/flowcontrol/switch-with-no-condition.go (100%) rename {tour/content => _content/tour}/flowcontrol/switch.go (100%) rename {tour/content => _content/tour}/img/tree.png (100%) rename {tour/content => _content/tour}/methods.article (100%) rename {tour/content => _content/tour}/methods/empty-interface.go (100%) rename {tour/content => _content/tour}/methods/errors.go (100%) rename {tour/content => _content/tour}/methods/exercise-errors.go (100%) rename {tour/content => _content/tour}/methods/exercise-images.go (100%) rename {tour/content => _content/tour}/methods/exercise-reader.go (100%) rename {tour/content => _content/tour}/methods/exercise-rot-reader.go (100%) rename {tour/content => _content/tour}/methods/exercise-stringer.go (100%) rename {tour/content => _content/tour}/methods/images.go (100%) rename {tour/content => _content/tour}/methods/indirection-values.go (100%) rename {tour/content => _content/tour}/methods/indirection.go (100%) rename {tour/content => _content/tour}/methods/interface-values-with-nil.go (100%) rename {tour/content => _content/tour}/methods/interface-values.go (100%) rename {tour/content => _content/tour}/methods/interfaces-are-satisfied-implicitly.go (100%) rename {tour/content => _content/tour}/methods/interfaces.go (100%) rename {tour/content => _content/tour}/methods/methods-continued.go (100%) rename {tour/content => _content/tour}/methods/methods-funcs.go (100%) rename {tour/content => _content/tour}/methods/methods-pointers-explained.go (100%) rename {tour/content => _content/tour}/methods/methods-pointers.go (100%) rename {tour/content => _content/tour}/methods/methods-with-pointer-receivers.go (100%) rename {tour/content => _content/tour}/methods/methods.go (100%) rename {tour/content => _content/tour}/methods/nil-interface-values.go (100%) rename {tour/content => _content/tour}/methods/reader.go (100%) rename {tour/content => _content/tour}/methods/stringer.go (100%) rename {tour/content => _content/tour}/methods/type-assertions.go (100%) rename {tour/content => _content/tour}/methods/type-switches.go (100%) rename {tour/content => _content/tour}/moretypes.article (100%) rename {tour/content => _content/tour}/moretypes/append.go (100%) rename {tour/content => _content/tour}/moretypes/array.go (100%) rename {tour/content => _content/tour}/moretypes/exercise-fibonacci-closure.go (100%) rename {tour/content => _content/tour}/moretypes/exercise-maps.go (100%) rename {tour/content => _content/tour}/moretypes/exercise-slices.go (100%) rename {tour/content => _content/tour}/moretypes/function-closures.go (100%) rename {tour/content => _content/tour}/moretypes/function-values.go (100%) rename {tour/content => _content/tour}/moretypes/making-slices.go (100%) rename {tour/content => _content/tour}/moretypes/map-literals-continued.go (100%) rename {tour/content => _content/tour}/moretypes/map-literals.go (100%) rename {tour/content => _content/tour}/moretypes/maps.go (100%) rename {tour/content => _content/tour}/moretypes/mutating-maps.go (100%) rename {tour/content => _content/tour}/moretypes/nil-slices.go (100%) rename {tour/content => _content/tour}/moretypes/pointers.go (100%) rename {tour/content => _content/tour}/moretypes/range-continued.go (100%) rename {tour/content => _content/tour}/moretypes/range.go (100%) rename {tour/content => _content/tour}/moretypes/slice-bounds.go (100%) rename {tour/content => _content/tour}/moretypes/slice-len-cap.go (100%) rename {tour/content => _content/tour}/moretypes/slice-literals.go (100%) rename {tour/content => _content/tour}/moretypes/slices-of-slice.go (100%) rename {tour/content => _content/tour}/moretypes/slices-pointers.go (100%) rename {tour/content => _content/tour}/moretypes/slices.go (100%) rename {tour/content => _content/tour}/moretypes/struct-fields.go (100%) rename {tour/content => _content/tour}/moretypes/struct-literals.go (100%) rename {tour/content => _content/tour}/moretypes/struct-pointers.go (100%) rename {tour/content => _content/tour}/moretypes/structs.go (100%) rename {tour => _content/tour}/solutions/README (100%) rename {tour => _content/tour}/solutions/binarytrees.go (100%) rename {tour => _content/tour}/solutions/binarytrees_quit.go (100%) rename {tour => _content/tour}/solutions/errors.go (100%) rename {tour => _content/tour}/solutions/fib.go (100%) rename {tour => _content/tour}/solutions/http.go (100%) rename {tour => _content/tour}/solutions/image.go (100%) rename {tour => _content/tour}/solutions/loops.go (100%) rename {tour => _content/tour}/solutions/maps.go (100%) rename {tour => _content/tour}/solutions/readers.go (100%) rename {tour => _content/tour}/solutions/rot13.go (100%) rename {tour => _content/tour}/solutions/slices.go (100%) rename {tour => _content/tour}/solutions/stringers.go (100%) rename {tour => _content/tour}/solutions/webcrawler.go (100%) rename {tour => _content/tour}/static/css/app.css (96%) rename {tour => _content/tour}/static/img/favicon.ico (100%) rename {tour => _content/tour}/static/img/gopher.png (100%) rename {tour => _content/tour}/static/js/app.js (65%) rename {tour => _content/tour}/static/js/controllers.js (97%) rename {tour => _content/tour}/static/js/directives.js (95%) create mode 100644 _content/tour/static/js/page.js rename {tour => _content/tour}/static/js/services.js (99%) rename {tour => _content/tour}/static/js/values.js (100%) rename {tour => _content/tour}/static/lib/angular-ui.min.js (100%) rename {tour => _content/tour}/static/lib/angular.min.js (100%) rename {tour => _content/tour}/static/lib/codemirror/AUTHORS (100%) rename {tour => _content/tour}/static/lib/codemirror/LICENSE (100%) rename tour/static/lib/codemirror/README.md => _content/tour/static/lib/codemirror/README (100%) rename {tour => _content/tour}/static/lib/codemirror/lib/codemirror.css (100%) rename {tour => _content/tour}/static/lib/codemirror/lib/codemirror.js (100%) rename {tour => _content/tour}/static/lib/codemirror/mode/go/go.js (100%) rename {tour => _content/tour}/static/lib/jquery-ui.min.js (100%) rename {tour => _content/tour}/static/lib/jquery.min.js (100%) rename {tour => _content/tour}/static/partials/editor.html (100%) rename {tour => _content/tour}/static/partials/feedback-button.html (100%) create mode 100644 _content/tour/static/partials/lesson.html rename {tour => _content/tour}/static/partials/list.html (85%) rename {tour => _content/tour}/static/partials/toc-button.html (100%) rename {tour => _content/tour}/static/partials/toc.html (87%) rename {tour => _content/tour}/template/action.tmpl (100%) create mode 100755 _content/tour/template/index.tmpl rename {tour/content => _content/tour}/welcome.article (100%) rename {tour/content => _content/tour}/welcome/hello.go (100%) rename {tour/content => _content/tour}/welcome/sandbox.go (100%) create mode 100644 cmd/golangorg/testdata/tour.txt rename {tour => internal/tour}/appengine.go (63%) rename {tour => internal/tour}/fmt.go (94%) rename {tour => internal/tour}/local.go (81%) rename {tour => internal/tour}/server_test.go (75%) create mode 100644 internal/tour/testdata/tour.txt rename {tour => internal/tour}/tour.go (76%) delete mode 100644 tour/app.yaml delete mode 100644 tour/cloudbuild.yaml delete mode 100644 tour/codereview.cfg create mode 100644 tour/main.go delete mode 100644 tour/static/partials/lesson.html delete mode 100755 tour/template/index.tmpl delete mode 100644 tour/testdata/tour.txt diff --git a/tour/content/basics.article b/_content/tour/basics.article similarity index 100% rename from tour/content/basics.article rename to _content/tour/basics.article diff --git a/tour/content/basics/basic-types.go b/_content/tour/basics/basic-types.go similarity index 100% rename from tour/content/basics/basic-types.go rename to _content/tour/basics/basic-types.go diff --git a/tour/content/basics/constants.go b/_content/tour/basics/constants.go similarity index 100% rename from tour/content/basics/constants.go rename to _content/tour/basics/constants.go diff --git a/tour/content/basics/exported-names.go b/_content/tour/basics/exported-names.go similarity index 100% rename from tour/content/basics/exported-names.go rename to _content/tour/basics/exported-names.go diff --git a/tour/content/basics/functions-continued.go b/_content/tour/basics/functions-continued.go similarity index 100% rename from tour/content/basics/functions-continued.go rename to _content/tour/basics/functions-continued.go diff --git a/tour/content/basics/functions.go b/_content/tour/basics/functions.go similarity index 100% rename from tour/content/basics/functions.go rename to _content/tour/basics/functions.go diff --git a/tour/content/basics/imports.go b/_content/tour/basics/imports.go similarity index 100% rename from tour/content/basics/imports.go rename to _content/tour/basics/imports.go diff --git a/tour/content/basics/multiple-results.go b/_content/tour/basics/multiple-results.go similarity index 100% rename from tour/content/basics/multiple-results.go rename to _content/tour/basics/multiple-results.go diff --git a/tour/content/basics/named-results.go b/_content/tour/basics/named-results.go similarity index 100% rename from tour/content/basics/named-results.go rename to _content/tour/basics/named-results.go diff --git a/tour/content/basics/numeric-constants.go b/_content/tour/basics/numeric-constants.go similarity index 100% rename from tour/content/basics/numeric-constants.go rename to _content/tour/basics/numeric-constants.go diff --git a/tour/content/basics/packages.go b/_content/tour/basics/packages.go similarity index 100% rename from tour/content/basics/packages.go rename to _content/tour/basics/packages.go diff --git a/tour/content/basics/short-variable-declarations.go b/_content/tour/basics/short-variable-declarations.go similarity index 100% rename from tour/content/basics/short-variable-declarations.go rename to _content/tour/basics/short-variable-declarations.go diff --git a/tour/content/basics/type-conversions.go b/_content/tour/basics/type-conversions.go similarity index 100% rename from tour/content/basics/type-conversions.go rename to _content/tour/basics/type-conversions.go diff --git a/tour/content/basics/type-inference.go b/_content/tour/basics/type-inference.go similarity index 100% rename from tour/content/basics/type-inference.go rename to _content/tour/basics/type-inference.go diff --git a/tour/content/basics/variables-with-initializers.go b/_content/tour/basics/variables-with-initializers.go similarity index 100% rename from tour/content/basics/variables-with-initializers.go rename to _content/tour/basics/variables-with-initializers.go diff --git a/tour/content/basics/variables.go b/_content/tour/basics/variables.go similarity index 100% rename from tour/content/basics/variables.go rename to _content/tour/basics/variables.go diff --git a/tour/content/basics/zero.go b/_content/tour/basics/zero.go similarity index 100% rename from tour/content/basics/zero.go rename to _content/tour/basics/zero.go diff --git a/tour/content/concurrency.article b/_content/tour/concurrency.article similarity index 99% rename from tour/content/concurrency.article rename to _content/tour/concurrency.article index 9cb5f69a..f5f656b1 100644 --- a/tour/content/concurrency.article +++ b/_content/tour/concurrency.article @@ -96,7 +96,7 @@ Use a `default` case to try a send or receive without blocking: There can be many different binary trees with the same sequence of values stored in it. For example, here are two binary trees storing the sequence 1, 1, 2, 3, 5, 8, 13. -.image /content/img/tree.png +.image /tour/static/img/tree.png A function to check whether two binary trees store the same sequence is quite complex in most languages. We'll use Go's concurrency and channels to write a simple solution. diff --git a/tour/content/concurrency/buffered-channels.go b/_content/tour/concurrency/buffered-channels.go similarity index 100% rename from tour/content/concurrency/buffered-channels.go rename to _content/tour/concurrency/buffered-channels.go diff --git a/tour/content/concurrency/channels.go b/_content/tour/concurrency/channels.go similarity index 100% rename from tour/content/concurrency/channels.go rename to _content/tour/concurrency/channels.go diff --git a/tour/content/concurrency/default-selection.go b/_content/tour/concurrency/default-selection.go similarity index 100% rename from tour/content/concurrency/default-selection.go rename to _content/tour/concurrency/default-selection.go diff --git a/tour/content/concurrency/exercise-equivalent-binary-trees.go b/_content/tour/concurrency/exercise-equivalent-binary-trees.go similarity index 100% rename from tour/content/concurrency/exercise-equivalent-binary-trees.go rename to _content/tour/concurrency/exercise-equivalent-binary-trees.go diff --git a/tour/content/concurrency/exercise-web-crawler.go b/_content/tour/concurrency/exercise-web-crawler.go similarity index 100% rename from tour/content/concurrency/exercise-web-crawler.go rename to _content/tour/concurrency/exercise-web-crawler.go diff --git a/tour/content/concurrency/goroutines.go b/_content/tour/concurrency/goroutines.go similarity index 100% rename from tour/content/concurrency/goroutines.go rename to _content/tour/concurrency/goroutines.go diff --git a/tour/content/concurrency/mutex-counter.go b/_content/tour/concurrency/mutex-counter.go similarity index 100% rename from tour/content/concurrency/mutex-counter.go rename to _content/tour/concurrency/mutex-counter.go diff --git a/tour/content/concurrency/range-and-close.go b/_content/tour/concurrency/range-and-close.go similarity index 100% rename from tour/content/concurrency/range-and-close.go rename to _content/tour/concurrency/range-and-close.go diff --git a/tour/content/concurrency/select.go b/_content/tour/concurrency/select.go similarity index 100% rename from tour/content/concurrency/select.go rename to _content/tour/concurrency/select.go diff --git a/tour/content/content_test.go b/_content/tour/content_test.go similarity index 96% rename from tour/content/content_test.go rename to _content/tour/content_test.go index 64b8136b..45542aab 100644 --- a/tour/content/content_test.go +++ b/_content/tour/content_test.go @@ -43,7 +43,7 @@ func TestContent(t *testing.T) { } t.Run(path, func(t *testing.T) { t.Parallel() - if err := testSnippet(t, path, scratch); err != nil { + if err := testSnippet(t, filepath.ToSlash(path), scratch); err != nil { t.Errorf("%v: %v", path, err) } }) diff --git a/tour/content/flowcontrol.article b/_content/tour/flowcontrol.article similarity index 100% rename from tour/content/flowcontrol.article rename to _content/tour/flowcontrol.article diff --git a/tour/content/flowcontrol/defer-multi.go b/_content/tour/flowcontrol/defer-multi.go similarity index 100% rename from tour/content/flowcontrol/defer-multi.go rename to _content/tour/flowcontrol/defer-multi.go diff --git a/tour/content/flowcontrol/defer.go b/_content/tour/flowcontrol/defer.go similarity index 100% rename from tour/content/flowcontrol/defer.go rename to _content/tour/flowcontrol/defer.go diff --git a/tour/content/flowcontrol/exercise-loops-and-functions.go b/_content/tour/flowcontrol/exercise-loops-and-functions.go similarity index 100% rename from tour/content/flowcontrol/exercise-loops-and-functions.go rename to _content/tour/flowcontrol/exercise-loops-and-functions.go diff --git a/tour/content/flowcontrol/for-continued.go b/_content/tour/flowcontrol/for-continued.go similarity index 100% rename from tour/content/flowcontrol/for-continued.go rename to _content/tour/flowcontrol/for-continued.go diff --git a/tour/content/flowcontrol/for-is-gos-while.go b/_content/tour/flowcontrol/for-is-gos-while.go similarity index 100% rename from tour/content/flowcontrol/for-is-gos-while.go rename to _content/tour/flowcontrol/for-is-gos-while.go diff --git a/tour/content/flowcontrol/for.go b/_content/tour/flowcontrol/for.go similarity index 100% rename from tour/content/flowcontrol/for.go rename to _content/tour/flowcontrol/for.go diff --git a/tour/content/flowcontrol/forever.go b/_content/tour/flowcontrol/forever.go similarity index 100% rename from tour/content/flowcontrol/forever.go rename to _content/tour/flowcontrol/forever.go diff --git a/tour/content/flowcontrol/if-and-else.go b/_content/tour/flowcontrol/if-and-else.go similarity index 100% rename from tour/content/flowcontrol/if-and-else.go rename to _content/tour/flowcontrol/if-and-else.go diff --git a/tour/content/flowcontrol/if-with-a-short-statement.go b/_content/tour/flowcontrol/if-with-a-short-statement.go similarity index 100% rename from tour/content/flowcontrol/if-with-a-short-statement.go rename to _content/tour/flowcontrol/if-with-a-short-statement.go diff --git a/tour/content/flowcontrol/if.go b/_content/tour/flowcontrol/if.go similarity index 100% rename from tour/content/flowcontrol/if.go rename to _content/tour/flowcontrol/if.go diff --git a/tour/content/flowcontrol/switch-evaluation-order.go b/_content/tour/flowcontrol/switch-evaluation-order.go similarity index 100% rename from tour/content/flowcontrol/switch-evaluation-order.go rename to _content/tour/flowcontrol/switch-evaluation-order.go diff --git a/tour/content/flowcontrol/switch-with-no-condition.go b/_content/tour/flowcontrol/switch-with-no-condition.go similarity index 100% rename from tour/content/flowcontrol/switch-with-no-condition.go rename to _content/tour/flowcontrol/switch-with-no-condition.go diff --git a/tour/content/flowcontrol/switch.go b/_content/tour/flowcontrol/switch.go similarity index 100% rename from tour/content/flowcontrol/switch.go rename to _content/tour/flowcontrol/switch.go diff --git a/tour/content/img/tree.png b/_content/tour/img/tree.png similarity index 100% rename from tour/content/img/tree.png rename to _content/tour/img/tree.png diff --git a/tour/content/methods.article b/_content/tour/methods.article similarity index 100% rename from tour/content/methods.article rename to _content/tour/methods.article diff --git a/tour/content/methods/empty-interface.go b/_content/tour/methods/empty-interface.go similarity index 100% rename from tour/content/methods/empty-interface.go rename to _content/tour/methods/empty-interface.go diff --git a/tour/content/methods/errors.go b/_content/tour/methods/errors.go similarity index 100% rename from tour/content/methods/errors.go rename to _content/tour/methods/errors.go diff --git a/tour/content/methods/exercise-errors.go b/_content/tour/methods/exercise-errors.go similarity index 100% rename from tour/content/methods/exercise-errors.go rename to _content/tour/methods/exercise-errors.go diff --git a/tour/content/methods/exercise-images.go b/_content/tour/methods/exercise-images.go similarity index 100% rename from tour/content/methods/exercise-images.go rename to _content/tour/methods/exercise-images.go diff --git a/tour/content/methods/exercise-reader.go b/_content/tour/methods/exercise-reader.go similarity index 100% rename from tour/content/methods/exercise-reader.go rename to _content/tour/methods/exercise-reader.go diff --git a/tour/content/methods/exercise-rot-reader.go b/_content/tour/methods/exercise-rot-reader.go similarity index 100% rename from tour/content/methods/exercise-rot-reader.go rename to _content/tour/methods/exercise-rot-reader.go diff --git a/tour/content/methods/exercise-stringer.go b/_content/tour/methods/exercise-stringer.go similarity index 100% rename from tour/content/methods/exercise-stringer.go rename to _content/tour/methods/exercise-stringer.go diff --git a/tour/content/methods/images.go b/_content/tour/methods/images.go similarity index 100% rename from tour/content/methods/images.go rename to _content/tour/methods/images.go diff --git a/tour/content/methods/indirection-values.go b/_content/tour/methods/indirection-values.go similarity index 100% rename from tour/content/methods/indirection-values.go rename to _content/tour/methods/indirection-values.go diff --git a/tour/content/methods/indirection.go b/_content/tour/methods/indirection.go similarity index 100% rename from tour/content/methods/indirection.go rename to _content/tour/methods/indirection.go diff --git a/tour/content/methods/interface-values-with-nil.go b/_content/tour/methods/interface-values-with-nil.go similarity index 100% rename from tour/content/methods/interface-values-with-nil.go rename to _content/tour/methods/interface-values-with-nil.go diff --git a/tour/content/methods/interface-values.go b/_content/tour/methods/interface-values.go similarity index 100% rename from tour/content/methods/interface-values.go rename to _content/tour/methods/interface-values.go diff --git a/tour/content/methods/interfaces-are-satisfied-implicitly.go b/_content/tour/methods/interfaces-are-satisfied-implicitly.go similarity index 100% rename from tour/content/methods/interfaces-are-satisfied-implicitly.go rename to _content/tour/methods/interfaces-are-satisfied-implicitly.go diff --git a/tour/content/methods/interfaces.go b/_content/tour/methods/interfaces.go similarity index 100% rename from tour/content/methods/interfaces.go rename to _content/tour/methods/interfaces.go diff --git a/tour/content/methods/methods-continued.go b/_content/tour/methods/methods-continued.go similarity index 100% rename from tour/content/methods/methods-continued.go rename to _content/tour/methods/methods-continued.go diff --git a/tour/content/methods/methods-funcs.go b/_content/tour/methods/methods-funcs.go similarity index 100% rename from tour/content/methods/methods-funcs.go rename to _content/tour/methods/methods-funcs.go diff --git a/tour/content/methods/methods-pointers-explained.go b/_content/tour/methods/methods-pointers-explained.go similarity index 100% rename from tour/content/methods/methods-pointers-explained.go rename to _content/tour/methods/methods-pointers-explained.go diff --git a/tour/content/methods/methods-pointers.go b/_content/tour/methods/methods-pointers.go similarity index 100% rename from tour/content/methods/methods-pointers.go rename to _content/tour/methods/methods-pointers.go diff --git a/tour/content/methods/methods-with-pointer-receivers.go b/_content/tour/methods/methods-with-pointer-receivers.go similarity index 100% rename from tour/content/methods/methods-with-pointer-receivers.go rename to _content/tour/methods/methods-with-pointer-receivers.go diff --git a/tour/content/methods/methods.go b/_content/tour/methods/methods.go similarity index 100% rename from tour/content/methods/methods.go rename to _content/tour/methods/methods.go diff --git a/tour/content/methods/nil-interface-values.go b/_content/tour/methods/nil-interface-values.go similarity index 100% rename from tour/content/methods/nil-interface-values.go rename to _content/tour/methods/nil-interface-values.go diff --git a/tour/content/methods/reader.go b/_content/tour/methods/reader.go similarity index 100% rename from tour/content/methods/reader.go rename to _content/tour/methods/reader.go diff --git a/tour/content/methods/stringer.go b/_content/tour/methods/stringer.go similarity index 100% rename from tour/content/methods/stringer.go rename to _content/tour/methods/stringer.go diff --git a/tour/content/methods/type-assertions.go b/_content/tour/methods/type-assertions.go similarity index 100% rename from tour/content/methods/type-assertions.go rename to _content/tour/methods/type-assertions.go diff --git a/tour/content/methods/type-switches.go b/_content/tour/methods/type-switches.go similarity index 100% rename from tour/content/methods/type-switches.go rename to _content/tour/methods/type-switches.go diff --git a/tour/content/moretypes.article b/_content/tour/moretypes.article similarity index 100% rename from tour/content/moretypes.article rename to _content/tour/moretypes.article diff --git a/tour/content/moretypes/append.go b/_content/tour/moretypes/append.go similarity index 100% rename from tour/content/moretypes/append.go rename to _content/tour/moretypes/append.go diff --git a/tour/content/moretypes/array.go b/_content/tour/moretypes/array.go similarity index 100% rename from tour/content/moretypes/array.go rename to _content/tour/moretypes/array.go diff --git a/tour/content/moretypes/exercise-fibonacci-closure.go b/_content/tour/moretypes/exercise-fibonacci-closure.go similarity index 100% rename from tour/content/moretypes/exercise-fibonacci-closure.go rename to _content/tour/moretypes/exercise-fibonacci-closure.go diff --git a/tour/content/moretypes/exercise-maps.go b/_content/tour/moretypes/exercise-maps.go similarity index 100% rename from tour/content/moretypes/exercise-maps.go rename to _content/tour/moretypes/exercise-maps.go diff --git a/tour/content/moretypes/exercise-slices.go b/_content/tour/moretypes/exercise-slices.go similarity index 100% rename from tour/content/moretypes/exercise-slices.go rename to _content/tour/moretypes/exercise-slices.go diff --git a/tour/content/moretypes/function-closures.go b/_content/tour/moretypes/function-closures.go similarity index 100% rename from tour/content/moretypes/function-closures.go rename to _content/tour/moretypes/function-closures.go diff --git a/tour/content/moretypes/function-values.go b/_content/tour/moretypes/function-values.go similarity index 100% rename from tour/content/moretypes/function-values.go rename to _content/tour/moretypes/function-values.go diff --git a/tour/content/moretypes/making-slices.go b/_content/tour/moretypes/making-slices.go similarity index 100% rename from tour/content/moretypes/making-slices.go rename to _content/tour/moretypes/making-slices.go diff --git a/tour/content/moretypes/map-literals-continued.go b/_content/tour/moretypes/map-literals-continued.go similarity index 100% rename from tour/content/moretypes/map-literals-continued.go rename to _content/tour/moretypes/map-literals-continued.go diff --git a/tour/content/moretypes/map-literals.go b/_content/tour/moretypes/map-literals.go similarity index 100% rename from tour/content/moretypes/map-literals.go rename to _content/tour/moretypes/map-literals.go diff --git a/tour/content/moretypes/maps.go b/_content/tour/moretypes/maps.go similarity index 100% rename from tour/content/moretypes/maps.go rename to _content/tour/moretypes/maps.go diff --git a/tour/content/moretypes/mutating-maps.go b/_content/tour/moretypes/mutating-maps.go similarity index 100% rename from tour/content/moretypes/mutating-maps.go rename to _content/tour/moretypes/mutating-maps.go diff --git a/tour/content/moretypes/nil-slices.go b/_content/tour/moretypes/nil-slices.go similarity index 100% rename from tour/content/moretypes/nil-slices.go rename to _content/tour/moretypes/nil-slices.go diff --git a/tour/content/moretypes/pointers.go b/_content/tour/moretypes/pointers.go similarity index 100% rename from tour/content/moretypes/pointers.go rename to _content/tour/moretypes/pointers.go diff --git a/tour/content/moretypes/range-continued.go b/_content/tour/moretypes/range-continued.go similarity index 100% rename from tour/content/moretypes/range-continued.go rename to _content/tour/moretypes/range-continued.go diff --git a/tour/content/moretypes/range.go b/_content/tour/moretypes/range.go similarity index 100% rename from tour/content/moretypes/range.go rename to _content/tour/moretypes/range.go diff --git a/tour/content/moretypes/slice-bounds.go b/_content/tour/moretypes/slice-bounds.go similarity index 100% rename from tour/content/moretypes/slice-bounds.go rename to _content/tour/moretypes/slice-bounds.go diff --git a/tour/content/moretypes/slice-len-cap.go b/_content/tour/moretypes/slice-len-cap.go similarity index 100% rename from tour/content/moretypes/slice-len-cap.go rename to _content/tour/moretypes/slice-len-cap.go diff --git a/tour/content/moretypes/slice-literals.go b/_content/tour/moretypes/slice-literals.go similarity index 100% rename from tour/content/moretypes/slice-literals.go rename to _content/tour/moretypes/slice-literals.go diff --git a/tour/content/moretypes/slices-of-slice.go b/_content/tour/moretypes/slices-of-slice.go similarity index 100% rename from tour/content/moretypes/slices-of-slice.go rename to _content/tour/moretypes/slices-of-slice.go diff --git a/tour/content/moretypes/slices-pointers.go b/_content/tour/moretypes/slices-pointers.go similarity index 100% rename from tour/content/moretypes/slices-pointers.go rename to _content/tour/moretypes/slices-pointers.go diff --git a/tour/content/moretypes/slices.go b/_content/tour/moretypes/slices.go similarity index 100% rename from tour/content/moretypes/slices.go rename to _content/tour/moretypes/slices.go diff --git a/tour/content/moretypes/struct-fields.go b/_content/tour/moretypes/struct-fields.go similarity index 100% rename from tour/content/moretypes/struct-fields.go rename to _content/tour/moretypes/struct-fields.go diff --git a/tour/content/moretypes/struct-literals.go b/_content/tour/moretypes/struct-literals.go similarity index 100% rename from tour/content/moretypes/struct-literals.go rename to _content/tour/moretypes/struct-literals.go diff --git a/tour/content/moretypes/struct-pointers.go b/_content/tour/moretypes/struct-pointers.go similarity index 100% rename from tour/content/moretypes/struct-pointers.go rename to _content/tour/moretypes/struct-pointers.go diff --git a/tour/content/moretypes/structs.go b/_content/tour/moretypes/structs.go similarity index 100% rename from tour/content/moretypes/structs.go rename to _content/tour/moretypes/structs.go diff --git a/tour/solutions/README b/_content/tour/solutions/README similarity index 100% rename from tour/solutions/README rename to _content/tour/solutions/README diff --git a/tour/solutions/binarytrees.go b/_content/tour/solutions/binarytrees.go similarity index 100% rename from tour/solutions/binarytrees.go rename to _content/tour/solutions/binarytrees.go diff --git a/tour/solutions/binarytrees_quit.go b/_content/tour/solutions/binarytrees_quit.go similarity index 100% rename from tour/solutions/binarytrees_quit.go rename to _content/tour/solutions/binarytrees_quit.go diff --git a/tour/solutions/errors.go b/_content/tour/solutions/errors.go similarity index 100% rename from tour/solutions/errors.go rename to _content/tour/solutions/errors.go diff --git a/tour/solutions/fib.go b/_content/tour/solutions/fib.go similarity index 100% rename from tour/solutions/fib.go rename to _content/tour/solutions/fib.go diff --git a/tour/solutions/http.go b/_content/tour/solutions/http.go similarity index 100% rename from tour/solutions/http.go rename to _content/tour/solutions/http.go diff --git a/tour/solutions/image.go b/_content/tour/solutions/image.go similarity index 100% rename from tour/solutions/image.go rename to _content/tour/solutions/image.go diff --git a/tour/solutions/loops.go b/_content/tour/solutions/loops.go similarity index 100% rename from tour/solutions/loops.go rename to _content/tour/solutions/loops.go diff --git a/tour/solutions/maps.go b/_content/tour/solutions/maps.go similarity index 100% rename from tour/solutions/maps.go rename to _content/tour/solutions/maps.go diff --git a/tour/solutions/readers.go b/_content/tour/solutions/readers.go similarity index 100% rename from tour/solutions/readers.go rename to _content/tour/solutions/readers.go diff --git a/tour/solutions/rot13.go b/_content/tour/solutions/rot13.go similarity index 100% rename from tour/solutions/rot13.go rename to _content/tour/solutions/rot13.go diff --git a/tour/solutions/slices.go b/_content/tour/solutions/slices.go similarity index 100% rename from tour/solutions/slices.go rename to _content/tour/solutions/slices.go diff --git a/tour/solutions/stringers.go b/_content/tour/solutions/stringers.go similarity index 100% rename from tour/solutions/stringers.go rename to _content/tour/solutions/stringers.go diff --git a/tour/solutions/webcrawler.go b/_content/tour/solutions/webcrawler.go similarity index 100% rename from tour/solutions/webcrawler.go rename to _content/tour/solutions/webcrawler.go diff --git a/tour/static/css/app.css b/_content/tour/static/css/app.css similarity index 96% rename from tour/static/css/app.css rename to _content/tour/static/css/app.css index e2f2ffdd..901c5320 100755 --- a/tour/static/css/app.css +++ b/_content/tour/static/css/app.css @@ -19,6 +19,11 @@ a { color: #375eab; text-decoration: none; } +.gopherlogo { + height: 2rem; + margin-right: 2.25rem; + width: 5.125rem +} a.logo, .toc a { color: inherit; } @@ -107,9 +112,14 @@ ul { z-index: 1000; font-size: 1.4em; padding: 8px 24px; - line-height: 32px; - color: #222; - background: #E0EBF5; + text-align: center; + color: #fff; + background: #007d9c; + height: 2rem; +} +.top-bar a { + vertical-align: middle; + font-weight: bold; } .nav { float: right; @@ -118,10 +128,7 @@ ul { width: 25px; margin-left: 10px; cursor: pointer; - fill: #375eab; -} -.nav:hover { - fill: #ffffff; + fill: #fff; } /* Module list */ .page-header { @@ -304,7 +311,7 @@ a#run, a#kill { overflow: hidden; } .output { - background-image: url(/static/img/gopher.png); + background-image: url(/tour/static/img/gopher.png); background-repeat: no-repeat; background-position: bottom; background-color: #fff; diff --git a/tour/static/img/favicon.ico b/_content/tour/static/img/favicon.ico similarity index 100% rename from tour/static/img/favicon.ico rename to _content/tour/static/img/favicon.ico diff --git a/tour/static/img/gopher.png b/_content/tour/static/img/gopher.png similarity index 100% rename from tour/static/img/gopher.png rename to _content/tour/static/img/gopher.png diff --git a/tour/static/js/app.js b/_content/tour/static/js/app.js similarity index 65% rename from tour/static/js/app.js rename to _content/tour/static/js/app.js index 7127bfc8..3014db86 100755 --- a/tour/static/js/app.js +++ b/_content/tour/static/js/app.js @@ -9,21 +9,21 @@ angular.module('tour', ['ui', 'tour.services', 'tour.controllers', 'tour.directi config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) { $routeProvider. - when('/', { - redirectTo: '/welcome/1' + when('/tour/', { + redirectTo: '/tour/welcome/1' }). - when('/list', { - templateUrl: '/static/partials/list.html', + when('/tour/list', { + templateUrl: '/tour/static/partials/list.html', }). - when('/:lessonId/:pageNumber', { - templateUrl: '/static/partials/editor.html', + when('/tour/:lessonId/:pageNumber', { + templateUrl: '/tour/static/partials/editor.html', controller: 'EditorCtrl' }). - when('/:lessonId', { - redirectTo: '/:lessonId/1' + when('/tour/:lessonId', { + redirectTo: '/tour/:lessonId/1' }). otherwise({ - redirectTo: '/' + redirectTo: '/tour/' }); $locationProvider.html5Mode(true).hashPrefix('!'); @@ -34,17 +34,17 @@ config(['$routeProvider', '$locationProvider', run(function($rootScope, $location, mapping) { $rootScope.$on( "$locationChangeStart", function(event, next) { var url = document.createElement('a'); - url.href = next; - if (url.pathname != '/' || url.hash == '') { + url.href = next; + if (url.pathname != '/tour/' || url.hash == '') { return; } $location.hash(''); var m = mapping[url.hash]; if (m === undefined) { console.log('unknown url, redirecting home'); - $location.path('/welcome/1'); + $location.path('/tour/welcome/1'); return; } - $location.path(m); - }); + $location.path('/tour' + m); + }); }); diff --git a/tour/static/js/controllers.js b/_content/tour/static/js/controllers.js similarity index 97% rename from tour/static/js/controllers.js rename to _content/tour/static/js/controllers.js index f3b9cf70..6dd252ed 100755 --- a/tour/static/js/controllers.js +++ b/_content/tour/static/js/controllers.js @@ -54,12 +54,12 @@ controller('EditorCtrl', ['$scope', '$routeParams', '$location', 'toc', 'i18n', } else { l = (page < 1) ? toc.prevLesson(l) : toc.nextLesson(l); if (l === '') { // If there's not previous or next - $location.path('/list'); + $location.path('/tour/list'); return; } page = (page < 1) ? lessons[l].Pages.length : 1; } - $location.path('/' + l + '/' + page); + $location.path('/tour/' + l + '/' + page); $scope.openFile($scope.curFile); analytics.trackView(); }; diff --git a/tour/static/js/directives.js b/_content/tour/static/js/directives.js similarity index 95% rename from tour/static/js/directives.js rename to _content/tour/static/js/directives.js index d7eb9bcc..76a1eb4b 100755 --- a/tour/static/js/directives.js +++ b/_content/tour/static/js/directives.js @@ -153,7 +153,7 @@ directive('tableOfContentsButton', ['i18n', function(i18n) { var speed = 250; return { restrict: 'A', - templateUrl: '/static/partials/toc-button.html', + templateUrl: '/tour/static/partials/toc-button.html', link: function(scope, elm, attrs) { scope.tocMessage = i18n.l('toc'); elm.on('click', function() { @@ -182,7 +182,7 @@ directive('tableOfContents', ['$routeParams', 'toc', var speed = 250; return { restrict: 'A', - templateUrl: '/static/partials/toc.html', + templateUrl: '/tour/static/partials/toc.html', link: function(scope, elm) { scope.toc = toc; scope.params = $routeParams; @@ -216,14 +216,14 @@ directive('tableOfContents', ['$routeParams', 'toc', directive('feedbackButton', ['i18n', function(i18n) { return { restrict: 'A', - templateUrl: '/static/partials/feedback-button.html', + templateUrl: '/tour/static/partials/feedback-button.html', link: function(scope, elm, attrs) { scope.feedbackMessage = i18n.l('submit-feedback'); elm.on('click', function() { - var context = window.location.pathname === '/list' - ? '/list' - : '/' + scope.params.lessonId + '/' + scope.params.pageNumber; + var context = window.location.pathname === '/tour/list' + ? '/tour/list' + : '/tour/' + scope.params.lessonId + '/' + scope.params.pageNumber; context = window.location.protocol + '//' + window.location.host + context; var title = i18n.l('issue-title'); var body = i18n.l('context') + ': '+ context + '\n\n'+ i18n.l('issue-message'); diff --git a/_content/tour/static/js/page.js b/_content/tour/static/js/page.js new file mode 100644 index 00000000..f4df9b69 --- /dev/null +++ b/_content/tour/static/js/page.js @@ -0,0 +1,23 @@ +window.transport = {{.Transport}}(); +window.socketAddr = "{{.SocketAddr}}"; + +function highlight(selector) { + var speed = 50; + var obj = $(selector).stop(true, true) + for (var i = 0; i < 5; i++) { + obj.addClass("highlight", speed) + obj.delay(speed) + obj.removeClass("highlight", speed) + } +} + +function highlightAndClick(selector) { + highlight(selector); + setTimeout(function() { + $(selector)[0].click() + }, 750); +} + +function click(selector) { + $(selector)[0].click(); +} diff --git a/tour/static/js/services.js b/_content/tour/static/js/services.js similarity index 99% rename from tour/static/js/services.js rename to _content/tour/static/js/services.js index da5f79cf..81854bcb 100755 --- a/tour/static/js/services.js +++ b/_content/tour/static/js/services.js @@ -201,7 +201,7 @@ factory('toc', ['$http', '$q', '$log', 'tableOfContents', 'storage', return mod.lessons[0]; }; - $http.get('/lesson/').then( + $http.get('/tour/lesson/').then( function(data) { lessons = data.data; for (var m = 0; m < modules.length; m++) { diff --git a/tour/static/js/values.js b/_content/tour/static/js/values.js similarity index 100% rename from tour/static/js/values.js rename to _content/tour/static/js/values.js diff --git a/tour/static/lib/angular-ui.min.js b/_content/tour/static/lib/angular-ui.min.js similarity index 100% rename from tour/static/lib/angular-ui.min.js rename to _content/tour/static/lib/angular-ui.min.js diff --git a/tour/static/lib/angular.min.js b/_content/tour/static/lib/angular.min.js similarity index 100% rename from tour/static/lib/angular.min.js rename to _content/tour/static/lib/angular.min.js diff --git a/tour/static/lib/codemirror/AUTHORS b/_content/tour/static/lib/codemirror/AUTHORS similarity index 100% rename from tour/static/lib/codemirror/AUTHORS rename to _content/tour/static/lib/codemirror/AUTHORS diff --git a/tour/static/lib/codemirror/LICENSE b/_content/tour/static/lib/codemirror/LICENSE similarity index 100% rename from tour/static/lib/codemirror/LICENSE rename to _content/tour/static/lib/codemirror/LICENSE diff --git a/tour/static/lib/codemirror/README.md b/_content/tour/static/lib/codemirror/README similarity index 100% rename from tour/static/lib/codemirror/README.md rename to _content/tour/static/lib/codemirror/README diff --git a/tour/static/lib/codemirror/lib/codemirror.css b/_content/tour/static/lib/codemirror/lib/codemirror.css similarity index 100% rename from tour/static/lib/codemirror/lib/codemirror.css rename to _content/tour/static/lib/codemirror/lib/codemirror.css diff --git a/tour/static/lib/codemirror/lib/codemirror.js b/_content/tour/static/lib/codemirror/lib/codemirror.js similarity index 100% rename from tour/static/lib/codemirror/lib/codemirror.js rename to _content/tour/static/lib/codemirror/lib/codemirror.js diff --git a/tour/static/lib/codemirror/mode/go/go.js b/_content/tour/static/lib/codemirror/mode/go/go.js similarity index 100% rename from tour/static/lib/codemirror/mode/go/go.js rename to _content/tour/static/lib/codemirror/mode/go/go.js diff --git a/tour/static/lib/jquery-ui.min.js b/_content/tour/static/lib/jquery-ui.min.js similarity index 100% rename from tour/static/lib/jquery-ui.min.js rename to _content/tour/static/lib/jquery-ui.min.js diff --git a/tour/static/lib/jquery.min.js b/_content/tour/static/lib/jquery.min.js similarity index 100% rename from tour/static/lib/jquery.min.js rename to _content/tour/static/lib/jquery.min.js diff --git a/tour/static/partials/editor.html b/_content/tour/static/partials/editor.html similarity index 100% rename from tour/static/partials/editor.html rename to _content/tour/static/partials/editor.html diff --git a/tour/static/partials/feedback-button.html b/_content/tour/static/partials/feedback-button.html similarity index 100% rename from tour/static/partials/feedback-button.html rename to _content/tour/static/partials/feedback-button.html diff --git a/_content/tour/static/partials/lesson.html b/_content/tour/static/partials/lesson.html new file mode 100644 index 00000000..5934d41c --- /dev/null +++ b/_content/tour/static/partials/lesson.html @@ -0,0 +1,4 @@ +
+ {{title}} +

{{description}}

+
diff --git a/tour/static/partials/list.html b/_content/tour/static/partials/list.html similarity index 85% rename from tour/static/partials/list.html rename to _content/tour/static/partials/list.html index 7cf93cf5..9d3bd3b6 100644 --- a/tour/static/partials/list.html +++ b/_content/tour/static/partials/list.html @@ -10,7 +10,7 @@
- {{m.lesson[l].Title}} + {{m.lesson[l].Title}}

{{m.lesson[l].Description}}

diff --git a/tour/static/partials/toc-button.html b/_content/tour/static/partials/toc-button.html similarity index 100% rename from tour/static/partials/toc-button.html rename to _content/tour/static/partials/toc-button.html diff --git a/tour/static/partials/toc.html b/_content/tour/static/partials/toc.html similarity index 87% rename from tour/static/partials/toc.html rename to _content/tour/static/partials/toc.html index 293ab82d..1e25dbbe 100644 --- a/tour/static/partials/toc.html +++ b/_content/tour/static/partials/toc.html @@ -7,7 +7,7 @@ {{m.lesson[l].Title}} diff --git a/tour/template/action.tmpl b/_content/tour/template/action.tmpl similarity index 100% rename from tour/template/action.tmpl rename to _content/tour/template/action.tmpl diff --git a/_content/tour/template/index.tmpl b/_content/tour/template/index.tmpl new file mode 100755 index 00000000..7f38ee31 --- /dev/null +++ b/_content/tour/template/index.tmpl @@ -0,0 +1,33 @@ + + + + +{{.AnalyticsHTML}} + A Tour of Go + + + + + + + + + + +
+
+ + +
+
+
+
+ +
+ +
+ + + + + diff --git a/tour/content/welcome.article b/_content/tour/welcome.article similarity index 100% rename from tour/content/welcome.article rename to _content/tour/welcome.article diff --git a/tour/content/welcome/hello.go b/_content/tour/welcome/hello.go similarity index 100% rename from tour/content/welcome/hello.go rename to _content/tour/welcome/hello.go diff --git a/tour/content/welcome/sandbox.go b/_content/tour/welcome/sandbox.go similarity index 100% rename from tour/content/welcome/sandbox.go rename to _content/tour/welcome/sandbox.go diff --git a/cmd/golangorg/csp.go b/cmd/golangorg/csp.go index b1c02575..73505225 100644 --- a/cmd/golangorg/csp.go +++ b/cmd/golangorg/csp.go @@ -10,26 +10,39 @@ import ( "strings" ) +// buildCSP builds the CSP header. +func buildCSP(kind string) string { + var ks []string + for k := range csp { + ks = append(ks, k) + } + sort.Strings(ks) + if kind == "tour" { + csp["script-src"] = append(csp["script-src"], unsafeEval) + } + + var sb strings.Builder + for _, k := range ks { + sb.WriteString(k) + sb.WriteString(" ") + sb.WriteString(strings.Join(csp[k], " ")) + sb.WriteString("; ") + } + return sb.String() +} + // addCSP returns a handler that adds the appropriate Content-Security-Policy header // to the response and then invokes h. func addCSP(h http.Handler) http.Handler { + std := buildCSP("") + tour := buildCSP("tour") + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - var ks []string - for k := range csp { - ks = append(ks, k) + csp := std + if strings.HasPrefix(r.URL.Path, "/tour/") { + csp = tour } - sort.Strings(ks) - - var sb strings.Builder - for _, k := range ks { - sb.WriteString(k) - sb.WriteString(" ") - sb.WriteString(strings.Join(csp[k], " ")) - sb.WriteString("; ") - } - - w.Header().Set("Content-Security-Policy", sb.String()) - + w.Header().Set("Content-Security-Policy", csp) h.ServeHTTP(w, r) }) } @@ -38,6 +51,7 @@ const ( self = "'self'" none = "'none'" unsafeInline = "'unsafe-inline'" + unsafeEval = "'unsafe-eval'" ) var csp = map[string][]string{ diff --git a/cmd/golangorg/server.go b/cmd/golangorg/server.go index 86876da5..de5c0a4d 100644 --- a/cmd/golangorg/server.go +++ b/cmd/golangorg/server.go @@ -43,6 +43,7 @@ import ( "golang.org/x/website/internal/proxy" "golang.org/x/website/internal/redirect" "golang.org/x/website/internal/short" + "golang.org/x/website/internal/tour" "golang.org/x/website/internal/web" "golang.org/x/website/internal/webtest" ) @@ -139,7 +140,7 @@ func NewHandler(contentDir, goroot string) http.Handler { if contentDir != "" { contentFS = os.DirFS(contentDir) } else { - contentFS = website.Content + contentFS = website.Content() } var gorootFS fs.FS @@ -171,6 +172,7 @@ func NewHandler(contentDir, goroot string) http.Handler { mux.Handle("golang.org/", redirectPrefix("https://go.dev/")) mux.Handle("blog.golang.org/", redirectPrefix("https://go.dev/blog/")) mux.Handle("learn.go.dev/", redirectPrefix("https://go.dev/learn/")) + mux.Handle("tour.golang.org/", redirectPrefix("https://go.dev/tour/")) // m.golang.org is an old shortcut for golang.org mail. // Gmail itself can serve this redirect, but only on HTTP (not HTTPS). @@ -215,6 +217,10 @@ func NewHandler(contentDir, goroot string) http.Handler { // Note: Registers for golang.org, go.dev/_, and golang.google.cn. proxy.RegisterHandlers(mux) + if err := tour.RegisterHandlers(mux); err != nil { + log.Fatalf("tour: %v", err) + } + var h http.Handler = mux h = addCSP(mux) h = hostEnforcerHandler(h) @@ -386,6 +392,7 @@ var validHosts = map[string]bool{ "blog.golang.org": true, "m.golang.org": true, "tip.golang.org": true, + "tour.golang.org": true, "go.dev": true, "learn.go.dev": true, @@ -469,6 +476,7 @@ type linkRewriter struct { func (r *linkRewriter) WriteHeader(code int) { loc := r.Header().Get("Location") + delete(r.Header(), "Content-Length") // we might change the content if strings.HasPrefix(loc, "/") { r.Header().Set("Location", "/"+r.host+loc) } else if u, _ := url.Parse(loc); u != nil && validHosts[u.Host] { diff --git a/cmd/golangorg/testdata/tour.txt b/cmd/golangorg/testdata/tour.txt new file mode 100644 index 00000000..84ea95e8 --- /dev/null +++ b/cmd/golangorg/testdata/tour.txt @@ -0,0 +1,8 @@ +GET https://tour.golang.org/ +redirect == https://go.dev/tour/ + +GET https://go.dev/tour/ +body contains >A Tour of Go< + +GET https://golang.google.cn/tour/ +body contains >A Tour of Go< diff --git a/content.go b/content.go index 3b596165..40ea366c 100644 --- a/content.go +++ b/content.go @@ -10,12 +10,22 @@ import ( "io/fs" ) -// Content is the go.dev website's static content. -var Content fs.FS = subdir(embedded, "_content") +// Content returns the go.dev website's static content. +func Content() fs.FS { + return subdir(embedded, "_content") +} + +// TourOnly returns the content needed only for the standalone tour. +func TourOnly() fs.FS { + return subdir(tourOnly, "_content") +} //go:embed _content var embedded embed.FS +//go:embed _content/tour _content/favicon.ico _content/images/go-logo-white.svg +var tourOnly embed.FS + func subdir(fsys fs.FS, path string) fs.FS { s, err := fs.Sub(fsys, path) if err != nil { diff --git a/internal/redirect/redirect.go b/internal/redirect/redirect.go index 6d3d2f27..658c9978 100644 --- a/internal/redirect/redirect.go +++ b/internal/redirect/redirect.go @@ -117,7 +117,6 @@ var redirects = map[string]string{ "/doc/spec": "/ref/spec", "/talks": "https://talks.golang.org", - "/tour": "https://tour.golang.org", "/wiki": "https://github.com/golang/go/wiki", "/doc/articles/c_go_cgo.html": "/blog/c-go-cgo", @@ -134,7 +133,7 @@ var redirects = map[string]string{ "/doc/articles/laws_of_reflection.html": "/blog/laws-of-reflection", "/doc/articles/slices_usage_and_internals.html": "/blog/go-slices-usage-and-internals", "/doc/go_for_cpp_programmers.html": "/wiki/GoForCPPProgrammers", - "/doc/go_tutorial.html": "https://tour.golang.org/", + "/doc/go_tutorial.html": "/tour", } var prefixHelpers = map[string]string{ diff --git a/internal/redirect/redirect_test.go b/internal/redirect/redirect_test.go index b90893c5..ee2f67c0 100644 --- a/internal/redirect/redirect_test.go +++ b/internal/redirect/redirect_test.go @@ -25,7 +25,6 @@ func TestRedirects(t *testing.T) { "/ref": {301, "/doc/#references"}, "/doc/mem": {301, "/ref/mem"}, "/doc/spec": {301, "/ref/spec"}, - "/tour": {301, "https://tour.golang.org"}, "/foo": errorResult(404), "/blog/2011/01/json-and-go.html": {301, "/blog/json-and-go"}, diff --git a/tour/appengine.go b/internal/tour/appengine.go similarity index 63% rename from tour/appengine.go rename to internal/tour/appengine.go index 4e8d50e7..990d11d4 100644 --- a/tour/appengine.go +++ b/internal/tour/appengine.go @@ -2,44 +2,27 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package main +package tour import ( "bufio" "bytes" "html/template" "io" - "log" "net/http" "os" - - _ "golang.org/x/tools/playground" - "golang.org/x/website/internal/webtest" ) -func gaeMain() { +func RegisterHandlers(mux *http.ServeMux) error { prepContent = gaePrepContent socketAddr = gaeSocketAddr analyticsHTML = template.HTML(os.Getenv("TOUR_ANALYTICS")) - if err := initTour("HTTPTransport"); err != nil { - log.Fatal(err) + if err := initTour(mux, "HTTPTransport"); err != nil { + return err } - http.Handle("/", hstsHandler(rootHandler)) - http.Handle("/lesson/", hstsHandler(lessonHandler)) - - registerStatic() - - port := os.Getenv("PORT") - if port == "" { - port = "8080" - } - - h := webtest.HandlerWithCheck(http.DefaultServeMux, "/_readycheck", - os.DirFS("."), "tour/testdata/*.txt") - - log.Fatal(http.ListenAndServe(":"+port, h)) + return nil } // gaePrepContent returns a Reader that produces the content from the given @@ -85,11 +68,3 @@ func gaePrepContent(in io.Reader) io.Reader { // gaeSocketAddr returns the WebSocket handler address. // The App Engine version does not provide a WebSocket handler. func gaeSocketAddr() string { return "" } - -// hstsHandler wraps an http.HandlerFunc such that it sets the HSTS header. -func hstsHandler(fn http.HandlerFunc) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Strict-Transport-Security", "max-age=31536000; preload") - fn(w, r) - }) -} diff --git a/tour/fmt.go b/internal/tour/fmt.go similarity index 94% rename from tour/fmt.go rename to internal/tour/fmt.go index 0a0be167..30108956 100644 --- a/tour/fmt.go +++ b/internal/tour/fmt.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package main +package tour import ( "bytes" @@ -16,10 +16,6 @@ import ( "golang.org/x/tools/imports" ) -func init() { - http.HandleFunc("/fmt", fmtHandler) -} - type fmtResponse struct { Body string Error string diff --git a/tour/local.go b/internal/tour/local.go similarity index 81% rename from tour/local.go rename to internal/tour/local.go index 1025806f..41628e54 100644 --- a/tour/local.go +++ b/internal/tour/local.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package main +package tour import ( "flag" @@ -28,23 +28,17 @@ const ( ) var ( - httpListen = flag.String("http", "127.0.0.1:3999", "host:port to listen on") + httpListen *string + openBrowser *bool + httpAddr string +) + +func Main() { + httpListen = flag.String("http", "127.0.0.1:3999", "host:port to listen on") openBrowser = flag.Bool("openbrowser", true, "open browser automatically") -) -var ( - httpAddr string -) - -func main() { flag.Parse() - if os.Getenv("GAE_ENV") == "standard" { - log.Println("running in App Engine Standard mode") - gaeMain() - return - } - host, port, err := net.SplitHostPort(*httpListen) if err != nil { log.Fatal(err) @@ -57,18 +51,19 @@ func main() { } httpAddr = host + ":" + port - if err := initTour("SocketTransport"); err != nil { + if err := initTour(http.DefaultServeMux, "SocketTransport"); err != nil { log.Fatal(err) } http.HandleFunc("/", rootHandler) - http.HandleFunc("/lesson/", lessonHandler) + http.HandleFunc("/fmt", fmtHandler) + fs := http.FileServer(http.FS(contentTour)) + http.Handle("/favicon.ico", fs) + http.Handle("/images/", fs) origin := &url.URL{Scheme: "http", Host: host + ":" + port} http.Handle(socketPath, socket.NewHandler(origin)) - registerStatic() - h := webtest.HandlerWithCheck(http.DefaultServeMux, "/_readycheck", os.DirFS("."), "tour/testdata/*.txt") @@ -80,16 +75,17 @@ func main() { log.Printf("Please open your web browser and visit %s", url) } }() - log.Fatal(http.ListenAndServe(httpAddr, h)) + + log.Fatal(http.ListenAndServe(httpAddr, &logging{h})) } -// registerStatic registers handlers to serve static content -// from the directory root. -func registerStatic() { - http.Handle("/favicon.ico", http.FileServer(http.FS(must(fs.Sub(root, "static/img"))))) - static := http.FileServer(http.FS(root)) - http.Handle("/content/img/", static) - http.Handle("/static/", static) +type logging struct { + h http.Handler +} + +func (l *logging) ServeHTTP(w http.ResponseWriter, r *http.Request) { + println(r.URL.Path) + l.h.ServeHTTP(w, r) } func must(fsys fs.FS, err error) fs.FS { @@ -101,6 +97,10 @@ func must(fsys fs.FS, err error) fs.FS { // rootHandler returns a handler for all the requests except the ones for lessons. func rootHandler(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/" { + http.Redirect(w, r, "/tour/", http.StatusFound) + return + } if err := renderUI(w); err != nil { log.Println(err) } @@ -108,7 +108,7 @@ func rootHandler(w http.ResponseWriter, r *http.Request) { // lessonHandler handler the HTTP requests for lessons. func lessonHandler(w http.ResponseWriter, r *http.Request) { - lesson := strings.TrimPrefix(r.URL.Path, "/lesson/") + lesson := strings.TrimPrefix(r.URL.Path, "/tour/lesson/") if err := writeLesson(lesson, w); err != nil { if err == lessonNotFound { http.NotFound(w, r) diff --git a/tour/server_test.go b/internal/tour/server_test.go similarity index 75% rename from tour/server_test.go rename to internal/tour/server_test.go index 4d4ab963..b9841742 100644 --- a/tour/server_test.go +++ b/internal/tour/server_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package main +package tour import ( "log" @@ -13,12 +13,9 @@ import ( ) func TestWeb(t *testing.T) { - if err := initTour("SocketTransport"); err != nil { + if err := initTour(http.DefaultServeMux, "SocketTransport"); err != nil { log.Fatal(err) } http.HandleFunc("/", rootHandler) - http.HandleFunc("/lesson/", lessonHandler) - registerStatic() - webtest.TestHandler(t, "testdata/*.txt", http.DefaultServeMux) } diff --git a/internal/tour/testdata/tour.txt b/internal/tour/testdata/tour.txt new file mode 100644 index 00000000..2ba10d54 --- /dev/null +++ b/internal/tour/testdata/tour.txt @@ -0,0 +1,6 @@ +GET https://any/ +redirect == /tour/ + +GET https://any/tour/ +body contains >A Tour of Go< + diff --git a/tour/tour.go b/internal/tour/tour.go similarity index 76% rename from tour/tour.go rename to internal/tour/tour.go index 542d26c2..c37fcd09 100644 --- a/tour/tour.go +++ b/internal/tour/tour.go @@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package main +package tour import ( "bytes" "crypto/sha1" - "embed" "encoding/base64" "encoding/json" "fmt" "html/template" "io" + "io/fs" "net/http" "path" "path/filepath" @@ -21,6 +21,7 @@ import ( "golang.org/x/tools/godoc/static" "golang.org/x/tools/present" + "golang.org/x/website" ) var ( @@ -29,18 +30,15 @@ var ( lessonNotFound = fmt.Errorf("lesson not found") ) -var ( - //go:embed content static template - root embed.FS -) +var contentTour = website.TourOnly() // initTour loads tour.article and the relevant HTML templates from root. -func initTour(transport string) error { +func initTour(mux *http.ServeMux, transport string) error { // Make sure playground is enabled before rendering. present.PlayEnabled = true // Set up templates. - tmpl, err := present.Template().ParseFS(root, "template/action.tmpl") + tmpl, err := present.Template().ParseFS(contentTour, "tour/template/action.tmpl") if err != nil { return fmt.Errorf("parse templates: %v", err) } @@ -51,7 +49,7 @@ func initTour(transport string) error { } // Init UI. - ui, err := template.ParseFS(root, "template/index.tmpl") + ui, err := template.ParseFS(contentTour, "tour/template/index.tmpl") if err != nil { return fmt.Errorf("parse index.tmpl: %v", err) } @@ -59,22 +57,24 @@ func initTour(transport string) error { data := struct { AnalyticsHTML template.HTML - SocketAddr string - Transport template.JS - }{analyticsHTML, socketAddr(), template.JS(transport)} + }{analyticsHTML} if err := ui.Execute(buf, data); err != nil { return fmt.Errorf("render UI: %v", err) } uiContent = buf.Bytes() - return initScript() + mux.HandleFunc("/tour/", rootHandler) + mux.HandleFunc("/tour/lesson/", lessonHandler) + mux.Handle("/tour/static/", http.FileServer(http.FS(contentTour))) + + return initScript(mux, socketAddr(), transport) } // initLessonss finds all the lessons in the content directory, renders them, // using the given template and saves the content in the lessons map. func initLessons(tmpl *template.Template) error { - files, err := root.ReadDir("content") + files, err := fs.ReadDir(contentTour, "tour") if err != nil { return err } @@ -82,7 +82,7 @@ func initLessons(tmpl *template.Template) error { if path.Ext(f.Name()) != ".article" { continue } - content, err := parseLesson(path.Join("content", f.Name()), tmpl) + content, err := parseLesson(f.Name(), tmpl) if err != nil { return fmt.Errorf("parsing %v: %v", f.Name(), err) } @@ -92,49 +92,49 @@ func initLessons(tmpl *template.Template) error { return nil } -// File defines the JSON form of a code file in a page. -type File struct { +// file defines the JSON form of a code file in a page. +type file struct { Name string Content string Hash string } -// Page defines the JSON form of a tour lesson page. -type Page struct { +// page defines the JSON form of a tour lesson page. +type page struct { Title string Content string - Files []File + Files []file } -// Lesson defines the JSON form of a tour lesson. -type Lesson struct { +// lesson defines the JSON form of a tour lesson. +type lesson struct { Title string Description string - Pages []Page + Pages []page } // parseLesson parses and returns a lesson content given its path // relative to root ('/'-separated) and the template to render it. func parseLesson(path string, tmpl *template.Template) ([]byte, error) { - f, err := root.Open(path) + f, err := contentTour.Open("tour/" + path) if err != nil { return nil, err } defer f.Close() ctx := &present.Context{ ReadFile: func(filename string) ([]byte, error) { - return root.ReadFile(filepath.ToSlash(filename)) + return fs.ReadFile(contentTour, "tour/"+filepath.ToSlash(filename)) }, } - doc, err := ctx.Parse(prepContent(f), filepath.FromSlash(path), 0) + doc, err := ctx.Parse(prepContent(f), path, 0) if err != nil { return nil, err } - lesson := Lesson{ + lesson := lesson{ doc.Title, doc.Subtitle, - make([]Page, len(doc.Sections)), + make([]page, len(doc.Sections)), } for i, sec := range doc.Sections { @@ -146,7 +146,7 @@ func parseLesson(path string, tmpl *template.Template) ([]byte, error) { p.Title = sec.Title p.Content = w.String() codes := findPlayCode(sec) - p.Files = make([]File, len(codes)) + p.Files = make([]file, len(codes)) for i, c := range codes { f := &p.Files[i] f.Name = c.FileName @@ -227,7 +227,7 @@ func renderUI(w io.Writer) error { // initScript concatenates all the javascript files needed to render // the tour UI and serves the result on /script.js. -func initScript() error { +func initScript(mux *http.ServeMux, socketAddr, transport string) error { modTime := time.Now() b := new(bytes.Buffer) @@ -253,17 +253,23 @@ func initScript() error { } for _, file := range files { - f, err := root.ReadFile(file) + f, err := fs.ReadFile(contentTour, "tour/"+file) if err != nil { - return fmt.Errorf("couldn't read %v: %v", file, err) - } - _, err = b.Write(f) - if err != nil { - return fmt.Errorf("error concatenating %v: %v", file, err) + return err } + b.Write(f) } - http.HandleFunc("/script.js", func(w http.ResponseWriter, r *http.Request) { + f, err := fs.ReadFile(contentTour, "tour/static/js/page.js") + if err != nil { + return err + } + s := string(f) + s = strings.ReplaceAll(s, "{{.SocketAddr}}", socketAddr) + s = strings.ReplaceAll(s, "{{.Transport}}", transport) + b.WriteString(s) + + mux.HandleFunc("/tour/script.js", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-type", "application/javascript") // Set expiration time in one week. w.Header().Set("Cache-control", "max-age=604800") diff --git a/tour/README.md b/tour/README.md index 2713de64..0c390d24 100644 --- a/tour/README.md +++ b/tour/README.md @@ -3,7 +3,7 @@ [![Go Reference](https://pkg.go.dev/badge/golang.org/x/website/tour.svg)](https://pkg.go.dev/golang.org/x/website/tour) A Tour of Go is an introduction to the Go programming language. Visit -https://tour.golang.org to start the tour. +https://go.dev/tour/ to start the tour. ## Download/Install @@ -43,15 +43,8 @@ at https://github.com/golang/tour/issues. ## Deploying -Each time a CL is reviewed and submitted, the tour is automatically deployed to App Engine. -If the CL is submitted with a Website-Publish +1 vote, -the new deployment automatically becomes https://tour.golang.org/. -Otherwise, the new deployment can be found in the -[App Engine versions list](https://console.cloud.google.com/appengine/versions?project=golang-org&serviceId=tour) and verified and manually promoted. - -If the automatic deployment is not working, or to check on the status of a pending deployment, -see the “website-redeploy-tour” trigger in the -[Cloud Build console](https://console.cloud.google.com/cloud-build/builds?project=golang-org). +Each time a CL is reviewed and submitted, the tour is automatically deployed to App Engine +as part of the main go.dev web site. See [../README.md](../README.md) for details. ## License diff --git a/tour/TRANSLATE b/tour/TRANSLATE index fa39dbaf..a6bce5f7 100644 --- a/tour/TRANSLATE +++ b/tour/TRANSLATE @@ -1,7 +1,7 @@ Translating the Tour A Tour of Go is a Go program that runs as a stand-alone web server or -an App Engine app. The version available at tour.golang.org is run from +an App Engine app. The version available at go.dev/tour/ is run from App Engine. There are several localized versions of the tour, such as this Chinese translation, also running on App Engine: diff --git a/tour/app.yaml b/tour/app.yaml deleted file mode 100644 index 7713a59a..00000000 --- a/tour/app.yaml +++ /dev/null @@ -1,19 +0,0 @@ -service: tour -runtime: go116 -main: ./tour - -env_variables: - TOUR_ANALYTICS: | - - - -handlers: -- url: /.* - script: auto - secure: always diff --git a/tour/cloudbuild.yaml b/tour/cloudbuild.yaml deleted file mode 100644 index b53a95e4..00000000 --- a/tour/cloudbuild.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# This Cloud Build file is run automatically when commits land in the website repo. -# See https://console.cloud.google.com/cloud-build/triggers?project=golang-org. -# Do not run directly. - -steps: - - name: 'golang' - args: ["go", "test", "./..."] - dir: tour - - name: gcr.io/cloud-builders/gcloud - entrypoint: bash - args: ["./go-app-deploy.sh", "tour/app.yaml"] - - name: 'golang' - args: [ - "go", "run", "./cmd/versionprune", "--dry_run=false", - "--project=$PROJECT_ID", "--service=tour", - ] - -options: - machineType: E2_HIGHCPU_8 diff --git a/tour/codereview.cfg b/tour/codereview.cfg deleted file mode 100644 index 3f8b14b6..00000000 --- a/tour/codereview.cfg +++ /dev/null @@ -1 +0,0 @@ -issuerepo: golang/go diff --git a/tour/main.go b/tour/main.go new file mode 100644 index 00000000..80971c88 --- /dev/null +++ b/tour/main.go @@ -0,0 +1,11 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "golang.org/x/website/internal/tour" + +func main() { + tour.Main() +} diff --git a/tour/static/partials/lesson.html b/tour/static/partials/lesson.html deleted file mode 100644 index 49399a06..00000000 --- a/tour/static/partials/lesson.html +++ /dev/null @@ -1,4 +0,0 @@ -
- {{title}} -

{{description}}

-
diff --git a/tour/template/index.tmpl b/tour/template/index.tmpl deleted file mode 100755 index 837dc773..00000000 --- a/tour/template/index.tmpl +++ /dev/null @@ -1,55 +0,0 @@ - - - - -{{.AnalyticsHTML}} - A Tour of Go - - - - - - - - - - -
- -
-
-
- -
- -
- - - - - - diff --git a/tour/testdata/tour.txt b/tour/testdata/tour.txt deleted file mode 100644 index bb1db633..00000000 --- a/tour/testdata/tour.txt +++ /dev/null @@ -1,3 +0,0 @@ -GET https://tour.golang.org/ -body contains >A Tour of Go< -