3 Applying Workflows to Projects
You may apply a workflow to a project programmatically using polyglot/builds, or manually using the polyglot CLI.
3.1 polyglot/builds
(require polyglot/builds) | package: polyglot-lib |
The following procedures apply workflows to projects.
procedure
(make-polyglot-workflow-object project [ #:live? live? #:forced-workflow forced-workflow #:fallback-workflow fallback-workflow]) → (is-a?/c unlike-compiler%) project : (is-a?/c polyglot-project%) live? : boolean? = #t
forced-workflow : (or/c #f (subclass?/c unlike-compiler%)) = #f
fallback-workflow : (or/c #f (subclass?/c unlike-compiler%)) = #f
The factory will use the first class available among the following expressions:
If no class is found, the procedure will raise exn:fail.
procedure
(build-polyglot-project! project compiler [ #:changed changed #:removed removed]) → dict? project : (is-a?/c polyglot-project%) compiler : (is-a?/c unlike-compiler%) changed : (listof clear/c) = '() removed : (listof clear/c) = '()
(parameterize ([polyglot-project-directory (get-field directory project)]) (unless (directory-exists? (dist-rel)) (send project ensure-empty-distribution!)) (send compiler compile! #:changed (keep changed) #:remove (keep removed)))
where keep is a function that filters out any paths that are not asset paths in project.
procedure
(make-polyglot-builder project-directory [ #:cycle-after cycle-after #:forced-workflow forced-workflow #:fallback-workflow fallback-workflow #:entry-assets entry-assets #:gc-request gc-request])
→
(->* () (#:changed (listof clear/c) #:removed (listof clear/c)) dict?) project-directory : useable-polyglot-directory? cycle-after : (or/c #f exact-positive-integer?) = 100
forced-workflow : (or/c #f (subclass?/c unlike-compiler%)) = #f
fallback-workflow : (or/c #f (subclass?/c unlike-compiler%)) = #f entry-assets : (non-empty-listof unclear/c) = '("index.md") gc-request : (or/c 'major 'minor 'incremental) = 'major
(define project-directory (build-path (current-directory) "my-project")) (define build! (make-polyglot-builder project-directory #:entry-assets '("index.md"))) (define (asset-paths . names) (map (lambda (el) (build-path project-directory "assets" el)) names)) (build!) (build! #:changed (asset-paths "contact.md")) (build! #:removed (asset-paths "junk.md") #:changed (asset-paths "about.md")) ; ...
Beware that live builds may not work as expected if you load a project’s .polyglotrc.rkt file on your own without reload support (See dynamic-rerequire). To be safe and avoid confusion, use only the procedures in polyglot/projects or polyglot/builds to handle workflows.
#:changed and #:removed assets are clear/c names for parity with build-polyglot-project!. On the other hand, whenever the builder procedure creates a workflow object W, it will stage each unclear/c asset name A in entry-assets for processing using (send W add! (send W clarify A)) (See unlike-compiler%). By a default convention, "index.md" is the unclear/c name of the initial page of any Polyglot project. You will not be able to add! additional assets to the compiler except through the workflow implementation.
If cycle-after is a positive integer, then after every cycle-after builds the compiler will be replaced with a fresh instance. (collect-garbage gc-request) will follow. This counteracts entropy on the underlying dependency graph during work, reducing the odds of surprises during long work sessions at the cost of periodic rebuilds. It also limits memory consumption for some expensive builds. To disable this feature, set cycle-after to #f.
value
polyglot-live? : (parameter/c boolean?) = #f
If you are writing your own build service using polyglot, set this to #t before instantiating any workflow class. Check this value if you are writing a workflow that behaves differently during live builds, such as kicking off a development server.
While it is possible to set this to #f within the dynamic extent of a workflow that applies other workflows in an opinionated way, be sure you understand the consequences of doing so.
3.2 polyglot CLI
To simplify use, Polyglot comes with a polyglot CLI that acts as a front-end to the polyglot collection. You can also use raco polyglot for backwards compatibility.
The build, demo and develop commands forward events from unlike-assets-logger to STDOUT. The build and demo commands report the number of warnings and errors encountered during processing.
3.2.1 polyglot start: Start a Project
$ polyglot start -f my-functional-website |
$ polyglot start my-imperative-website |
The start command creates a project directory with the given name in the working directory. By default, the project will use polyglot/imperative% and include some supported starter code. If you specify -f or --functional, the project will reflect use of polyglot/functional% instead.
3.2.2 polyglot build: Build a Project Once
The build command accepts a path as an argument and attempts to build a project using a workflow. If a workflow cannot be determined, the build command will try to use polyglot/imperative% for backwards-compatibility reasons. If the path is a relative path, it will be converted to a complete path relative to the current working directory.
The behavior will vary slightly if you specify a directory or a file.
3.2.2.1 Specifying a Directory
$ polyglot build my-website |
When you specify a directory, the build command will try to require polyglot+% from my-website/.polyglotrc.rkt, falling back to polyglot/imperative% on failure. It will then instantiate the selected workflow class, and start processing from my-website/assets/index.md.
3.2.2.2 Specifying an Asset File
$ polyglot build my-website/assets/styles/styles.css |
When you specify a file, the build command will require polyglot+% from the .polyglotrc.rkt in the nearest project directory, falling back to polyglot/imperative% on failure. It will then instantiate the selected workflow class, and start processing from the asset specified in the command line.
3.2.3 polyglot develop: Build a Project Live
The develop command builds a project once, then rebuilds your website in response to changes in assets detected using robust-watch. It will stop when you press Control-C.
$ polyglot develop my-website |
The develop command will also start a local development server unless -n or --no-server is specified. You can also set a port using -p/--port, or use the default of 8080.
$ polyglot develop -p 6790 my-website |
$ polyglot develop -n my-website # Server won't start |
The process that monitors and rebuilds assets operates independently of the server. If you do not start the development server, the develop command will still rebuild assets in response to changes.
The rules for how the develop command treats paths are the same as the build command.
You can specify a delay, in milliseconds, that must elapse after the last detected change in assets before the command tries rebuilding your site. By default, this is 500 milliseconds. You can use this to aggregate changes and avoid triggering too many builds when saving changes rapidly in your project.
$ polyglot develop --delay 1000 my-website |
3.2.4 polyglot demo: Build Demo Project
$ polyglot demo |
The demo command is a special case of build that targets the README from Polyglot’s own source code. The distribution directory will appear in the working directory. This command is meant to verify that a Polyglot installation is supported on the target platform and is working as intended.
3.2.5 polyglot publish: Publish to S3
The publish command builds a project once, then writes the contents of a project’s distribution directory to an AWS S3 bucket. The rules for how the publish command treats paths are the same as the build command.
$ polyglot publish my-website my-bucket |
Before you use this command, read this entire section. If you do not agree with ANY of it, then use the AWS CLI or the aws/s3 library to publish your website.
Use the -d or --dry-run switch to avoid writing content to S3 and instead merely report what the command would otherwise do to the bucket.
$ polyglot publish -d my-website my-bucket |
Use the -r or --region switch to change the applicable S3 region.
$ polyglot publish -r us-east-2 my-website my-bucket |
Use the --delete-diff switch to delete all objects in the S3 bucket that are not part of the distribution uploaded to the bucket. Most people won’t need this.
$ polyglot publish --delete-diff my-website my-bucket |
3.2.5.1 Assumptions
The bucket is configured for static web hosting.
HTML files should never be cached.
All other files should be cached forever.
3.2.5.2 Process
Authenticate against AWS with read-keys/aws-cli.
Read all keys in the bucket and compare them to the local contents of the dist directory. Remember the elements that are remote but not local.
Uploads the contents of the dist directory to the root of the bucket, overwriting any objects that already exist.
If --delete-diff is set on the command, delete from the bucket the objects marked in Step 2.
If you want to ensure no broken links, then do not ever use --delete-diff. You’ll only want to use that option if the space savings and hygiene are actually worth it, and if everything in the bucket that you need for your website is produced by a Polyglot build.
3.2.6 Shared Command Options
Some command-line flags may be specified after polyglot but before a subcommand.
Use the -v or --verbose option to include debug level events from unlike-assets-logger in STDOUT.
$ polyglot -v build some-site |
Use the -b or --by-module option with a path to a Racket module to forcibly use that module in place of a project’s .polyglotrc.rkt.
$ polyglot -b /etc/polyglot.d/shared-config.rkt build some-site |