@greenpandastudios/aug-cli 0.19.0 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -6
- package/THIRD_PARTY_NOTICES.md +4 -0
- package/bin/aug.mjs +12 -2
- package/docs/about.md +27 -0
- package/docs/api/crypto.md +103 -69
- package/docs/api/io.md +35 -33
- package/docs/api/json.md +3 -3
- package/docs/api/memory.md +23 -19
- package/docs/api/time.md +10 -9
- package/docs/api/web.md +33 -38
- package/docs/compatibility.md +3 -3
- package/docs/contributing-benchmarks.md +38 -0
- package/docs/dev-containers.md +95 -0
- package/docs/diagnostics.md +15 -5
- package/docs/docker.md +174 -12
- package/docs/editor.md +35 -0
- package/docs/example-projects.json +206 -24
- package/docs/examples/approved-design/counters.md +34 -126
- package/docs/examples/approved-design/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/approved-design/domain/app.md +13 -77
- package/docs/examples/approved-design/domain/export.md +5 -19
- package/docs/examples/approved-design/domain/models.md +4 -23
- package/docs/examples/approved-design/domain/numbers.md +24 -114
- package/docs/examples/approved-design/index.md +16 -7
- package/docs/examples/approved-design/main.md +19 -96
- package/docs/examples/benchmark/index.md +6 -5
- package/docs/examples/benchmark/main.md +7 -35
- package/docs/examples/cli-args/index.md +6 -5
- package/docs/examples/cli-args/main.md +6 -31
- package/docs/examples/collections/index.md +6 -5
- package/docs/examples/collections/main.md +7 -35
- package/docs/examples/collections-benchmark/index.md +6 -5
- package/docs/examples/collections-benchmark/main.md +7 -35
- package/docs/examples/cpu-benchmark/index.md +6 -5
- package/docs/examples/cpu-benchmark/main.md +5 -24
- package/docs/examples/developer-workflow/calculator.md +39 -186
- package/docs/examples/developer-workflow/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/developer-workflow/index.md +16 -7
- package/docs/examples/developer-workflow/logging/console.md +10 -56
- package/docs/examples/developer-workflow/logging/export.md +4 -14
- package/docs/examples/developer-workflow/logging/logger.md +7 -43
- package/docs/examples/developer-workflow/main.md +17 -69
- package/docs/examples/drop/index.md +6 -5
- package/docs/examples/drop/main.md +7 -27
- package/docs/examples/drop/resource.md +7 -30
- package/docs/examples/errors/errors.md +7 -27
- package/docs/examples/errors/index.md +6 -5
- package/docs/examples/errors/main.md +7 -28
- package/docs/examples/ffi/index.md +6 -5
- package/docs/examples/ffi/main.md +6 -20
- package/docs/examples/ffi/native.md +8 -34
- package/docs/examples/generic-di/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/generic-di/index.md +6 -5
- package/docs/examples/generic-di/main.md +9 -39
- package/docs/examples/generic-di/types.md +23 -92
- package/docs/examples/generics/index.md +6 -5
- package/docs/examples/generics/main.md +10 -47
- package/docs/examples/generics/types.md +25 -100
- package/docs/examples/hello/app/export.md +4 -12
- package/docs/examples/hello/app/greeter.md +13 -91
- package/docs/examples/hello/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/hello/index.md +17 -6
- package/docs/examples/hello/logging/console.md +10 -54
- package/docs/examples/hello/logging/export.md +4 -14
- package/docs/examples/hello/logging/logger.md +7 -45
- package/docs/examples/hello/main.md +9 -39
- package/docs/examples/http-benchmark/index.md +6 -5
- package/docs/examples/http-benchmark/main.md +6 -20
- package/docs/examples/http-benchmark/routes.md +9 -31
- package/docs/examples/index.md +46 -29
- package/docs/examples/interceptors/app.md +20 -139
- package/docs/examples/interceptors/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/interceptors/index.md +6 -5
- package/docs/examples/interceptors/interceptors.md +24 -148
- package/docs/examples/interceptors/logging.md +13 -76
- package/docs/examples/interceptors/main.md +10 -65
- package/docs/examples/json-benchmark/data.md +4 -20
- package/docs/examples/json-benchmark/dependencies/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +67 -0
- package/docs/examples/json-benchmark/index.md +7 -5
- package/docs/examples/json-benchmark/main-yaml.md +20 -0
- package/docs/examples/json-benchmark/main.md +10 -49
- package/docs/examples/new-syntax/console.md +10 -52
- package/docs/examples/new-syntax/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/new-syntax/greeter.md +13 -71
- package/docs/examples/new-syntax/index.md +6 -5
- package/docs/examples/new-syntax/logger.md +7 -43
- package/docs/examples/new-syntax/main.md +10 -53
- package/docs/examples/new-syntax/math.md +6 -24
- package/docs/examples/oidc-login/client/contracts.md +10 -61
- package/docs/examples/oidc-login/client/endpoints.md +32 -154
- package/docs/examples/oidc-login/client/export.md +5 -23
- package/docs/examples/oidc-login/client/login.md +234 -344
- package/docs/examples/oidc-login/client/logout.md +38 -143
- package/docs/examples/oidc-login/client/protocol.md +183 -304
- package/docs/examples/oidc-login/client/session.md +41 -149
- package/docs/examples/oidc-login/client/views.md +13 -58
- package/docs/examples/oidc-login/common/export.md +6 -26
- package/docs/examples/oidc-login/common/headers.md +42 -72
- package/docs/examples/oidc-login/common/keys.md +40 -164
- package/docs/examples/oidc-login/common/settings.md +24 -40
- package/docs/examples/oidc-login/common/views.md +7 -28
- package/docs/examples/oidc-login/dependencies/packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md +205 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +67 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +267 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md +415 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.md +271 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +89 -0
- package/docs/examples/oidc-login/index.md +8 -7
- package/docs/examples/oidc-login/main-yaml.md +7 -0
- package/docs/examples/oidc-login/main.md +26 -153
- package/docs/examples/oidc-login/provider/authorization.md +232 -275
- package/docs/examples/oidc-login/provider/contracts.md +24 -146
- package/docs/examples/oidc-login/provider/credentials.md +24 -57
- package/docs/examples/oidc-login/provider/discovery.md +48 -122
- package/docs/examples/oidc-login/provider/export.md +11 -37
- package/docs/examples/oidc-login/provider/token.md +159 -237
- package/docs/examples/oidc-login/provider/userinfo.md +47 -102
- package/docs/examples/oidc-login/provider/views.md +13 -53
- package/docs/examples/ownership/counter.md +17 -63
- package/docs/examples/ownership/index.md +6 -5
- package/docs/examples/ownership/main.md +7 -30
- package/docs/examples/ownership-transfer/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/ownership-transfer/index.md +6 -5
- package/docs/examples/ownership-transfer/main.md +10 -52
- package/docs/examples/ownership-transfer/resource.md +15 -67
- package/docs/examples/packages-app/dependencies/packages/@example/aug-math/0.1.0/arithmetic.md +12 -50
- package/docs/examples/packages-app/index.md +7 -6
- package/docs/examples/packages-app/main.md +7 -25
- package/docs/examples/packages-math/aug-package-json.md +1 -1
- package/docs/examples/packages-math/index.md +7 -6
- package/docs/examples/packages-math/src/arithmetic.md +12 -50
- package/docs/examples/packages-math/src/export.md +4 -12
- package/docs/examples/startup-benchmark/index.md +6 -5
- package/docs/examples/startup-benchmark/main.md +5 -17
- package/docs/examples/visibility/counter.md +19 -67
- package/docs/examples/visibility/index.md +6 -5
- package/docs/examples/visibility/main.md +7 -31
- package/docs/examples/weather-api/forecasts.md +168 -0
- package/docs/examples/weather-api/index.md +42 -0
- package/docs/examples/weather-api/main-yaml.md +21 -0
- package/docs/examples/weather-api/main.md +65 -0
- package/docs/examples.json +10 -0
- package/docs/getting-started.md +105 -2
- package/docs/grammar.md +6 -4
- package/docs/guides/change-a-module.md +64 -0
- package/docs/guides/index.md +27 -0
- package/docs/index.md +51 -29
- package/docs/language-conformance.md +1 -1
- package/docs/language-constructs.md +22 -22
- package/docs/language-design-audit.md +1 -1
- package/docs/learn/data-and-errors.md +77 -0
- package/docs/learn/index.md +30 -0
- package/docs/learn/modules-and-dependencies.md +73 -0
- package/docs/learn/state-and-tests.md +71 -0
- package/docs/learn/values-and-functions.md +62 -0
- package/docs/lesson-failures.json +8 -0
- package/docs/maintaining-docs.md +16 -4
- package/docs/packages.md +72 -126
- package/docs/performance.md +13 -41
- package/docs/production-readiness.md +5 -4
- package/docs/public/downloads/approved-design.zip +0 -0
- package/docs/public/downloads/benchmark.zip +0 -0
- package/docs/public/downloads/cli-args.zip +0 -0
- package/docs/public/downloads/collections-benchmark.zip +0 -0
- package/docs/public/downloads/collections.zip +0 -0
- package/docs/public/downloads/cpu-benchmark.zip +0 -0
- package/docs/public/downloads/developer-workflow.zip +0 -0
- package/docs/public/downloads/drop.zip +0 -0
- package/docs/public/downloads/errors.zip +0 -0
- package/docs/public/downloads/ffi.zip +0 -0
- package/docs/public/downloads/generic-di.zip +0 -0
- package/docs/public/downloads/generics.zip +0 -0
- package/docs/public/downloads/hello.zip +0 -0
- package/docs/public/downloads/http-benchmark.zip +0 -0
- package/docs/public/downloads/interceptors.zip +0 -0
- package/docs/public/downloads/json-benchmark.zip +0 -0
- package/docs/public/downloads/new-syntax.zip +0 -0
- package/docs/public/downloads/oidc-login.zip +0 -0
- package/docs/public/downloads/ownership-transfer.zip +0 -0
- package/docs/public/downloads/ownership.zip +0 -0
- package/docs/public/downloads/packages-app.zip +0 -0
- package/docs/public/downloads/packages-math.zip +0 -0
- package/docs/public/downloads/startup-benchmark.zip +0 -0
- package/docs/public/downloads/visibility.zip +0 -0
- package/docs/public/downloads/weather-api.zip +0 -0
- package/docs/reference.md +23 -17
- package/docs/releasing.md +29 -15
- package/docs/research/code-to-natural-language.md +108 -0
- package/docs/research/ecosystem-workflow.md +41 -0
- package/docs/research/wiki-editorial-design.md +71 -0
- package/docs/roadmap.md +1 -1
- package/docs/specifications.md +27 -11
- package/docs/testing.md +19 -5
- package/docs/tooling.md +25 -12
- package/docs/weather-api.md +65 -0
- package/docs/web.md +50 -18
- package/docs/writing-docs.md +49 -0
- package/examples/{hello/.aug-spec/august/0.19.0 → approved-design/.aug-spec/august/0.20.1}/io/contracts.aug +4 -3
- package/examples/approved-design/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/approved-design/.aug-spec/manifest.json +3 -3
- package/examples/approved-design/counters.aug +5 -4
- package/examples/approved-design/counters.aug.md +25 -132
- package/examples/approved-design/domain/app.aug +2 -1
- package/examples/approved-design/domain/app.aug.md +10 -80
- package/examples/approved-design/domain/export.aug +1 -0
- package/examples/approved-design/domain/export.aug.md +4 -20
- package/examples/approved-design/domain/models.aug +1 -0
- package/examples/approved-design/domain/models.aug.md +3 -25
- package/examples/approved-design/domain/numbers.aug +3 -2
- package/examples/approved-design/domain/numbers.aug.md +19 -116
- package/examples/approved-design/main.aug +1 -0
- package/examples/approved-design/main.aug.md +12 -95
- package/examples/benchmark/.aug-spec/manifest.json +1 -1
- package/examples/benchmark/main.aug +1 -0
- package/examples/benchmark/main.aug.md +6 -36
- package/examples/cli-args/.aug-spec/manifest.json +1 -1
- package/examples/cli-args/main.aug +1 -0
- package/examples/cli-args/main.aug.md +5 -32
- package/examples/collections/.aug-spec/manifest.json +1 -1
- package/examples/collections/main.aug +1 -0
- package/examples/collections/main.aug.md +6 -36
- package/examples/{generic-di/.aug-spec/august/0.19.0 → developer-workflow/.aug-spec/august/0.20.1}/io/contracts.aug +4 -3
- package/examples/developer-workflow/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/developer-workflow/.aug-spec/manifest.json +3 -3
- package/examples/developer-workflow/calculator.aug +3 -2
- package/examples/developer-workflow/calculator.aug.md +28 -189
- package/examples/developer-workflow/logging/console.aug +2 -1
- package/examples/developer-workflow/logging/console.aug.md +7 -57
- package/examples/developer-workflow/logging/export.aug +1 -0
- package/examples/developer-workflow/logging/export.aug.md +3 -15
- package/examples/developer-workflow/logging/logger.aug +1 -0
- package/examples/developer-workflow/logging/logger.aug.md +6 -46
- package/examples/developer-workflow/main.aug +1 -0
- package/examples/developer-workflow/main.aug.md +10 -68
- package/examples/drop/.aug-spec/manifest.json +1 -1
- package/examples/drop/main.aug +1 -0
- package/examples/drop/main.aug.md +6 -28
- package/examples/drop/resource.aug +1 -0
- package/examples/drop/resource.aug.md +6 -34
- package/examples/errors/.aug-spec/manifest.json +1 -1
- package/examples/errors/errors.aug +2 -1
- package/examples/errors/errors.aug.md +4 -27
- package/examples/errors/main.aug +1 -0
- package/examples/errors/main.aug.md +6 -29
- package/examples/ffi/.aug-spec/manifest.json +1 -1
- package/examples/ffi/main.aug +1 -0
- package/examples/ffi/main.aug.md +5 -21
- package/examples/ffi/native.aug +2 -1
- package/examples/ffi/native.aug.md +5 -35
- package/examples/{approved-design/.aug-spec/august/0.19.0 → generic-di/.aug-spec/august/0.20.1}/io/contracts.aug +4 -3
- package/examples/generic-di/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/generic-di/.aug-spec/manifest.json +3 -3
- package/examples/generic-di/main.aug +1 -0
- package/examples/generic-di/main.aug.md +8 -40
- package/examples/generic-di/types.aug +3 -2
- package/examples/generic-di/types.aug.md +18 -97
- package/examples/generics/.aug-spec/manifest.json +1 -1
- package/examples/generics/main.aug +1 -0
- package/examples/generics/main.aug.md +9 -48
- package/examples/generics/types.aug +4 -3
- package/examples/generics/types.aug.md +18 -104
- package/examples/{developer-workflow/.aug-spec/august/0.19.0 → hello/.aug-spec/august/0.20.1}/io/contracts.aug +4 -3
- package/examples/hello/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/hello/.aug-spec/manifest.json +3 -3
- package/examples/hello/app/export.aug +1 -0
- package/examples/hello/app/export.aug.md +3 -13
- package/examples/hello/app/greeter.aug +2 -1
- package/examples/hello/app/greeter.aug.md +10 -94
- package/examples/hello/logging/console.aug +2 -1
- package/examples/hello/logging/console.aug.md +7 -55
- package/examples/hello/logging/export.aug +1 -0
- package/examples/hello/logging/export.aug.md +3 -15
- package/examples/hello/logging/logger.aug +1 -0
- package/examples/hello/logging/logger.aug.md +6 -48
- package/examples/hello/main.aug +1 -0
- package/examples/hello/main.aug.md +8 -40
- package/examples/interceptors/.aug-spec/august/0.20.1/io/contracts.aug +37 -0
- package/examples/interceptors/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/interceptors/.aug-spec/manifest.json +3 -3
- package/examples/interceptors/app.aug +3 -2
- package/examples/interceptors/app.aug.md +15 -141
- package/examples/interceptors/interceptors.aug +3 -2
- package/examples/interceptors/interceptors.aug.md +19 -152
- package/examples/interceptors/logging.aug +2 -1
- package/examples/interceptors/logging.aug.md +10 -79
- package/examples/interceptors/main.aug +1 -0
- package/examples/interceptors/main.aug.md +9 -66
- package/examples/new-syntax/.aug-spec/august/0.20.1/io/contracts.aug +37 -0
- package/examples/new-syntax/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/new-syntax/.aug-spec/manifest.json +3 -3
- package/examples/new-syntax/console.aug +2 -1
- package/examples/new-syntax/console.aug.md +7 -53
- package/examples/new-syntax/greeter.aug +2 -1
- package/examples/new-syntax/greeter.aug.md +10 -74
- package/examples/new-syntax/logger.aug +1 -0
- package/examples/new-syntax/logger.aug.md +6 -46
- package/examples/new-syntax/main.aug +1 -0
- package/examples/new-syntax/main.aug.md +9 -54
- package/examples/new-syntax/math.aug +2 -1
- package/examples/new-syntax/math.aug.md +3 -24
- package/examples/oidc-login/.aug-spec/manifest.json +13 -13
- package/examples/oidc-login/.aug-spec/packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md +71 -0
- package/examples/oidc-login/.aug-spec/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +17 -0
- package/examples/oidc-login/.aug-spec/packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +125 -0
- package/examples/oidc-login/.aug-spec/{august/0.19.0/crypto → packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40}/contracts.aug +12 -11
- package/examples/oidc-login/.aug-spec/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md +244 -0
- package/examples/oidc-login/.aug-spec/{august/0.19.0/crypto → packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40}/jose.aug +6 -5
- package/examples/oidc-login/.aug-spec/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.aug.md +71 -0
- package/examples/oidc-login/.aug-spec/packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +30 -0
- package/examples/oidc-login/aug.lock.json +100 -0
- package/examples/oidc-login/client/contracts.aug +1 -0
- package/examples/oidc-login/client/contracts.aug.md +9 -66
- package/examples/oidc-login/client/endpoints.aug +6 -5
- package/examples/oidc-login/client/endpoints.aug.md +13 -145
- package/examples/oidc-login/client/export.aug +1 -0
- package/examples/oidc-login/client/export.aug.md +4 -24
- package/examples/oidc-login/client/login.aug +7 -6
- package/examples/oidc-login/client/login.aug.md +25 -303
- package/examples/oidc-login/client/logout.aug +5 -4
- package/examples/oidc-login/client/logout.aug.md +13 -135
- package/examples/oidc-login/client/protocol.aug +7 -6
- package/examples/oidc-login/client/protocol.aug.md +36 -283
- package/examples/oidc-login/client/session.aug +5 -4
- package/examples/oidc-login/client/session.aug.md +12 -139
- package/examples/oidc-login/client/views.aug +3 -2
- package/examples/oidc-login/client/views.aug.md +8 -57
- package/examples/oidc-login/common/export.aug +1 -0
- package/examples/oidc-login/common/export.aug.md +5 -27
- package/examples/oidc-login/common/headers.aug +4 -3
- package/examples/oidc-login/common/headers.aug.md +9 -67
- package/examples/oidc-login/common/keys.aug +6 -5
- package/examples/oidc-login/common/keys.aug.md +29 -165
- package/examples/oidc-login/common/settings.aug +2 -1
- package/examples/oidc-login/common/settings.aug.md +5 -39
- package/examples/oidc-login/common/views.aug +2 -1
- package/examples/oidc-login/common/views.aug.md +4 -28
- package/examples/oidc-login/main.aug +6 -16
- package/examples/oidc-login/main.aug.md +17 -146
- package/examples/oidc-login/main.yaml +7 -0
- package/examples/oidc-login/provider/authorization.aug +7 -6
- package/examples/oidc-login/provider/authorization.aug.md +23 -238
- package/examples/oidc-login/provider/contracts.aug +1 -0
- package/examples/oidc-login/provider/contracts.aug.md +23 -158
- package/examples/oidc-login/provider/credentials.aug +3 -2
- package/examples/oidc-login/provider/credentials.aug.md +9 -53
- package/examples/oidc-login/provider/discovery.aug +4 -3
- package/examples/oidc-login/provider/discovery.aug.md +11 -118
- package/examples/oidc-login/provider/export.aug +1 -0
- package/examples/oidc-login/provider/export.aug.md +6 -34
- package/examples/oidc-login/provider/token.aug +6 -5
- package/examples/oidc-login/provider/token.aug.md +16 -204
- package/examples/oidc-login/provider/userinfo.aug +4 -3
- package/examples/oidc-login/provider/userinfo.aug.md +10 -92
- package/examples/oidc-login/provider/views.aug +3 -2
- package/examples/oidc-login/provider/views.aug.md +8 -52
- package/examples/ownership/.aug-spec/manifest.json +1 -1
- package/examples/ownership/counter.aug +3 -2
- package/examples/ownership/counter.aug.md +12 -66
- package/examples/ownership/main.aug +1 -0
- package/examples/ownership/main.aug.md +6 -31
- package/examples/ownership-transfer/.aug-spec/august/0.20.1/io/contracts.aug +37 -0
- package/examples/ownership-transfer/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/ownership-transfer/.aug-spec/manifest.json +3 -3
- package/examples/ownership-transfer/main.aug +1 -0
- package/examples/ownership-transfer/main.aug.md +9 -53
- package/examples/ownership-transfer/resource.aug +2 -1
- package/examples/ownership-transfer/resource.aug.md +12 -71
- package/examples/packages/app/.aug-spec/manifest.json +1 -1
- package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug +2 -1
- package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug.md +9 -51
- package/examples/packages/app/main.aug +1 -0
- package/examples/packages/app/main.aug.md +6 -26
- package/examples/packages/math/.aug-spec/manifest.json +1 -1
- package/examples/packages/math/aug-package.json +1 -1
- package/examples/packages/math/src/arithmetic.aug +2 -1
- package/examples/packages/math/src/arithmetic.aug.md +9 -51
- package/examples/packages/math/src/export.aug +1 -0
- package/examples/packages/math/src/export.aug.md +3 -13
- package/examples/visibility/.aug-spec/manifest.json +1 -1
- package/examples/visibility/counter.aug +4 -3
- package/examples/visibility/counter.aug.md +12 -68
- package/examples/visibility/main.aug +1 -0
- package/examples/visibility/main.aug.md +6 -32
- package/examples/weather-api/.aug-spec/manifest.json +8 -0
- package/examples/weather-api/AGENTS.md +17 -0
- package/examples/weather-api/README.md +19 -0
- package/examples/weather-api/forecasts.aug +47 -0
- package/examples/weather-api/forecasts.aug.md +32 -0
- package/examples/weather-api/main.aug +4 -0
- package/examples/weather-api/main.aug.md +15 -0
- package/examples/weather-api/main.yaml +5 -0
- package/examples/weather-api/weather.http +5 -0
- package/package.json +3 -4
- package/scripts/bootstrap-native.mjs +181 -106
- package/scripts/native-setup.mjs +98 -0
- package/scripts/native-toolchain.mjs +28 -0
- package/src/builtins.js +1 -1
- package/src/checker.js +259 -72
- package/src/cli.js +114 -20
- package/src/codegen.js +1 -1
- package/src/config.js +1 -1
- package/src/contracts.js +10 -0
- package/src/editor.js +71 -16
- package/src/fixes.js +90 -2
- package/src/formatter.js +19 -8
- package/src/git-packages.js +110 -0
- package/src/help.js +24 -23
- package/src/http-contracts.js +14 -0
- package/src/http-policies.js +5 -5
- package/src/libraries.js +1 -1
- package/src/lsp.js +14 -5
- package/src/native.js +19 -13
- package/src/navigation.js +4 -2
- package/src/openapi.js +5 -4
- package/src/package-locking.js +45 -0
- package/src/package-manager.js +251 -67
- package/src/parser.js +13 -5
- package/src/policies.js +3 -3
- package/src/project-init.js +78 -4
- package/src/project.js +9 -7
- package/src/semantic.js +46 -2
- package/src/snippets.js +59 -0
- package/src/spec-hints.js +56 -0
- package/src/spec-tree.js +241 -0
- package/src/spec.js +626 -303
- package/docs/examples/approved-design/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/developer-workflow/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/generic-di/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/hello/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/interceptors/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/json-benchmark/dependencies/august/0.19.0/json/contracts.md +0 -103
- package/docs/examples/new-syntax/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/contracts.md +0 -925
- package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/jose.md +0 -434
- package/docs/examples/oidc-login/dependencies/august/0.19.0/json/contracts.md +0 -103
- package/docs/examples/oidc-login/dependencies/august/0.19.0/memory/store.md +0 -374
- package/docs/examples/oidc-login/dependencies/august/0.19.0/time/contracts.md +0 -150
- package/docs/examples/oidc-login/dependencies/august/0.19.0/web/contracts.md +0 -532
- package/docs/examples/ownership-transfer/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/examples/approved-design/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/developer-workflow/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/generic-di/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/hello/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
- package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
- package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/contracts.aug.md +0 -791
- package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/jose.aug.md +0 -266
- package/examples/oidc-login/.aug-spec/august/0.19.0/json/contracts.aug.md +0 -55
- package/examples/oidc-login/.aug-spec/august/0.19.0/memory/store.aug.md +0 -250
- package/examples/oidc-login/.aug-spec/august/0.19.0/time/contracts.aug.md +0 -96
- package/examples/oidc-login/.aug-spec/august/0.19.0/web/contracts.aug.md +0 -420
- package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
- package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- /package/examples/oidc-login/.aug-spec/{august/0.19.0/memory → packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/store.aug +0 -0
- /package/examples/oidc-login/.aug-spec/{august/0.19.0/json → packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
- /package/examples/oidc-login/.aug-spec/{august/0.19.0/web → packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
- /package/examples/oidc-login/.aug-spec/{august/0.19.0/time → packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!-- Generated by aug spec. Edit the August source, then regenerate. -->
|
|
2
|
+
|
|
3
|
+
# `forecasts.aug`
|
|
4
|
+
|
|
5
|
+
Plain handler results default to HTTP 200 unless another status is declared. HttpResponse values choose their own status. Unhandled request failures return HTTP 500 and cancel the request tasks.
|
|
6
|
+
|
|
7
|
+
<a id="symbol-WeatherForecast"></a>
|
|
8
|
+
## `WeatherForecast` · immutable record · [source](forecasts.aug#L3)
|
|
9
|
+
|
|
10
|
+
The JSON shape returned by the forecast endpoint. Temperatures use whole degrees. It takes `date` as a string, kept read-only, `temperatureC` and `temperatureF` as integers, kept read-only, and `summary` as a string, kept read-only.
|
|
11
|
+
|
|
12
|
+
<a id="symbol-weatherForecast"></a>
|
|
13
|
+
## `weatherForecast` · [source](forecasts.aug#L6)
|
|
14
|
+
|
|
15
|
+
`weatherForecast` handles `GET /weatherforecast`. Return five simulated forecasts. Fixed data keeps the example and its tests reproducible. It returns a list of 5 [`WeatherForecast`](forecasts.aug.md#symbol-WeatherForecast) records, with `(date, temperatureC, temperatureF, summary)` values of `("2026-01-01", 0, 32, "Freezing")`, `("2026-01-02", 10, 50, "Cool")`, `("2026-01-03", 20, 68, "Mild")`, `("2026-01-04", 30, 86, "Warm")`, and `("2026-01-05", 35, 95, "Hot")`, in that order.
|
|
16
|
+
|
|
17
|
+
<a id="symbol-test weatherForecast client"></a>
|
|
18
|
+
## `test weatherForecast client` · [source](forecasts.aug#L40)
|
|
19
|
+
|
|
20
|
+
Tests [`weatherForecast`](forecasts.aug.md#symbol-weatherForecast). Each case gets fresh setup and dependencies.
|
|
21
|
+
|
|
22
|
+
### `forecasts`
|
|
23
|
+
|
|
24
|
+
#### `returns_json` · [source](forecasts.aug#L42)
|
|
25
|
+
|
|
26
|
+
It sets `response` to `client.request` with `method` `"GET"` and `path` `"/weatherforecast"`. The test requires `response.status` equals `200`.
|
|
27
|
+
|
|
28
|
+
#### `rejects_other_methods` · [source](forecasts.aug#L45)
|
|
29
|
+
|
|
30
|
+
It sets `response` to `client.request` with `method` `"POST"` and `path` `"/weatherforecast"`. The test requires `response.status` equals `405`.
|
|
31
|
+
|
|
32
|
+
Built-in operations follow the [language reference](https://greenpandastudios.github.io/augscript/language-constructs).
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!-- Generated by aug spec. Edit the August source, then regenerate. -->
|
|
2
|
+
|
|
3
|
+
# `main.aug`
|
|
4
|
+
|
|
5
|
+
## HTTP configuration
|
|
6
|
+
|
|
7
|
+
Listen on `127.0.0.1`. Limit request bodies to 1048576 bytes and buffered responses to 4194304 bytes. Serve OpenAPI at `/openapi.json` and API docs at `/docs`.
|
|
8
|
+
|
|
9
|
+
## Startup
|
|
10
|
+
|
|
11
|
+
It serves [`weatherForecast`](forecasts.aug.md#symbol-weatherForecast) on port `8787`.
|
|
12
|
+
|
|
13
|
+
## Dependencies
|
|
14
|
+
|
|
15
|
+
It uses [`weatherForecast`](forecasts.aug.md#symbol-weatherForecast) from `forecasts`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@greenpandastudios/aug-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.1",
|
|
4
4
|
"description": "August compiler, native build CLI, tests and language server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,9 +23,8 @@
|
|
|
23
23
|
"THIRD_PARTY_NOTICES.md"
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@greenpandastudios/aug-stdlib": "0.
|
|
27
|
-
"
|
|
28
|
-
"@greenpandastudios/aug-crypto": "0.19.0"
|
|
26
|
+
"@greenpandastudios/aug-stdlib": "0.20.1",
|
|
27
|
+
"tar": "7.5.22"
|
|
29
28
|
},
|
|
30
29
|
"publishConfig": {
|
|
31
30
|
"access": "public",
|
|
@@ -1,121 +1,196 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/** Build the pinned C dependencies privately; never install into system directories. */
|
|
3
3
|
import { createHash } from 'node:crypto';
|
|
4
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync, openSync, closeSync } from 'node:fs';
|
|
5
|
-
import {
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, openSync, closeSync, renameSync, rmSync, statSync } from 'node:fs';
|
|
5
|
+
import { join, resolve } from 'node:path';
|
|
6
6
|
import { spawnSync } from 'node:child_process';
|
|
7
7
|
import { availableParallelism } from 'node:os';
|
|
8
8
|
import { nativeHome } from './native-home.mjs';
|
|
9
|
+
import { cCompiler, requireBuildTool } from './native-toolchain.mjs';
|
|
10
|
+
import { dependencyArtifacts, dependencyReady } from './native-setup.mjs';
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (onlyIndex >= 0 && (!extractOnly || !selected?.length || selected.some(name => !lock.dependencies.some(dependency => dependency.name === name))))
|
|
16
|
-
throw new Error('--only requires --extract-only and comma-separated names from native-dependencies.lock.json.');
|
|
17
|
-
const directory = nativeHome(root);
|
|
18
|
-
const prefix = join(directory, 'prefix');
|
|
19
|
-
const downloads = join(directory, 'downloads');
|
|
20
|
-
const sources = join(directory, 'sources');
|
|
21
|
-
const logs = join(directory, 'logs');
|
|
22
|
-
for (const path of [prefix, downloads, sources, logs]) mkdirSync(path, { recursive: true });
|
|
23
|
-
if (!extractOnly && !lock.platforms.includes(process.platform)) throw new Error(`Full native bootstrap supports ${lock.platforms.join(' and ')}; this host is ${process.platform}. Use --extract-only --only minicoro,yyjson for portable source dependencies.`);
|
|
24
|
-
|
|
25
|
-
function run(command, args, cwd, label, env = process.env) {
|
|
26
|
-
const path = join(logs, label + '.log');
|
|
27
|
-
const descriptor = openSync(path, 'w');
|
|
28
|
-
let result;
|
|
29
|
-
try { result = spawnSync(command, args, { cwd, env, stdio: ['ignore', descriptor, descriptor] }); }
|
|
30
|
-
finally { closeSync(descriptor); }
|
|
31
|
-
if (result.error || result.status !== 0) throw new Error(`${label} failed: ${result.error?.message ?? result.status}. See ${path}\n` + readFileSync(path, 'utf8').split('\n').slice(-24).join('\n'));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const dependencies = lock.dependencies.filter(dependency => (!dependency.platforms || dependency.platforms.includes(process.platform)) && (!selected || selected.includes(dependency.name)));
|
|
35
|
-
if (selected?.some(name => !dependencies.some(dependency => dependency.name === name)))
|
|
36
|
-
throw new Error(`One or more selected dependencies do not support ${process.platform}.`);
|
|
37
|
-
for (const dependency of dependencies) {
|
|
38
|
-
const archive = join(downloads, dependency.archive);
|
|
39
|
-
if (!existsSync(archive)) {
|
|
40
|
-
process.stdout.write(`Downloading ${dependency.name} ${dependency.version}\n`);
|
|
41
|
-
const response = await fetch(dependency.url);
|
|
42
|
-
if (!response.ok) throw new Error(`${dependency.name}: HTTP ${response.status}`);
|
|
43
|
-
writeFileSync(archive, Buffer.from(await response.arrayBuffer()));
|
|
12
|
+
async function setup() {
|
|
13
|
+
if (Number(process.versions.node.split('.')[0]) < 24) throw new Error(`August native setup needs Node.js 24 or newer; this is ${process.versions.node}.`);
|
|
14
|
+
if (process.argv.includes('--help')) {
|
|
15
|
+
process.stdout.write('Usage: aug-native [--profile crypto|web] [--offline]\n aug-native --extract-only [--only minicoro,yyjson] [--offline]\n\nNative commands prepare dependencies automatically. Use this command to prewarm a cache without running a program.\nAUG_NATIVE_HOME selects the cache; system build tools remain prerequisites.\n');
|
|
16
|
+
return;
|
|
44
17
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
writeFileSync(join(source, '.archive-sha256'), hash + '\n');
|
|
52
|
-
} else if (readFileSync(join(source, '.archive-sha256'), 'utf8').trim() !== hash) {
|
|
53
|
-
throw new Error(`${dependency.name}: source tree differs from the dependency lock; choose a new build directory.`);
|
|
18
|
+
for (let index = 2; index < process.argv.length; index++) {
|
|
19
|
+
const option = process.argv[index];
|
|
20
|
+
if (['--only', '--profile'].includes(option)) {
|
|
21
|
+
if (!process.argv[index + 1] || process.argv[index + 1].startsWith('--')) throw new Error(`${option} needs a value. See aug-native --help.`);
|
|
22
|
+
index++;
|
|
23
|
+
} else if (!['--extract-only', '--offline'].includes(option)) throw new Error(`Unknown option ${option}. See aug-native --help.`);
|
|
54
24
|
}
|
|
25
|
+
const root = resolve(import.meta.dirname, '..');
|
|
26
|
+
const lock = JSON.parse(readFileSync(join(import.meta.dirname, 'native-dependencies.lock.json'), 'utf8'));
|
|
27
|
+
const extractOnly = process.argv.includes('--extract-only');
|
|
28
|
+
const onlyIndex = process.argv.indexOf('--only');
|
|
29
|
+
const selected = onlyIndex >= 0 ? process.argv[onlyIndex + 1]?.split(',') : undefined;
|
|
30
|
+
const profileIndex = process.argv.indexOf('--profile');
|
|
31
|
+
const profile = profileIndex >= 0 ? process.argv[profileIndex + 1] : 'web';
|
|
32
|
+
const offline = process.argv.includes('--offline');
|
|
33
|
+
if (!['crypto', 'web'].includes(profile)) throw new Error('Use --profile crypto or --profile web.');
|
|
34
|
+
if (onlyIndex >= 0 && (!extractOnly || !selected?.length || selected.some(name => !lock.dependencies.some(dependency => dependency.name === name))))
|
|
35
|
+
throw new Error('--only requires --extract-only and comma-separated names from native-dependencies.lock.json.');
|
|
36
|
+
const directory = nativeHome(root);
|
|
37
|
+
const prefix = join(directory, 'prefix');
|
|
38
|
+
const downloads = join(directory, 'downloads');
|
|
39
|
+
const sources = join(directory, 'sources');
|
|
40
|
+
const logs = join(directory, 'logs');
|
|
41
|
+
for (const path of [prefix, downloads, sources, logs]) mkdirSync(path, { recursive: true });
|
|
42
|
+
if (!extractOnly && !lock.platforms.includes(process.platform)) throw new Error(`Full native bootstrap supports ${lock.platforms.join(' and ')}; this host is ${process.platform}. Use --extract-only --only minicoro,yyjson for portable source dependencies.`);
|
|
43
|
+
const cc = extractOnly ? undefined : cCompiler();
|
|
44
|
+
requireBuildTool('tar');
|
|
45
|
+
if (!extractOnly) { requireBuildTool('make'); requireBuildTool('m4'); if (profile === 'web' && process.platform !== 'darwin') requireBuildTool('cmake'); }
|
|
46
|
+
const release = await acquireLock(directory);
|
|
47
|
+
try {
|
|
48
|
+
|
|
49
|
+
function run(command, args, cwd, label, env = process.env) {
|
|
50
|
+
const path = join(logs, label + '.log');
|
|
51
|
+
const descriptor = openSync(path, 'w');
|
|
52
|
+
let result;
|
|
53
|
+
try { result = spawnSync(command, args, { cwd, env, stdio: ['ignore', descriptor, descriptor] }); }
|
|
54
|
+
finally { closeSync(descriptor); }
|
|
55
|
+
if (result.error || result.status !== 0) throw new Error(`${label} failed: ${result.error?.message ?? result.status}. See ${path}\n` + readFileSync(path, 'utf8').split('\n').slice(-24).join('\n'));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const dependencies = lock.dependencies.filter(dependency => (!dependency.platforms || dependency.platforms.includes(process.platform)) &&
|
|
59
|
+
(!selected || selected.includes(dependency.name)) && (extractOnly || profile === 'web' || ['pkgconf', 'gmp', 'nettle', 'gnutls'].includes(dependency.name)));
|
|
60
|
+
if (selected?.some(name => !dependencies.some(dependency => dependency.name === name)))
|
|
61
|
+
throw new Error(`One or more selected dependencies do not support ${process.platform}.`);
|
|
62
|
+
for (const dependency of dependencies) {
|
|
63
|
+
const archive = join(downloads, dependency.archive);
|
|
64
|
+
if (!existsSync(archive)) {
|
|
65
|
+
if (offline) throw new Error(`Offline setup cannot find the cached ${dependency.name} archive at ${archive}.\nRun aug run once with network access, then retry aug run --offline.`);
|
|
66
|
+
process.stdout.write(`Downloading ${dependency.name} ${dependency.version}\n`);
|
|
67
|
+
let bytes;
|
|
68
|
+
try {
|
|
69
|
+
const response = await fetch(dependency.url, { signal: AbortSignal.timeout(120000) });
|
|
70
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
71
|
+
bytes = Buffer.from(await response.arrayBuffer());
|
|
72
|
+
} catch (error) { throw new Error(`Could not download ${dependency.name}: ${error.message}.\nCheck your internet/proxy connection and retry aug run. URL: ${dependency.url}`); }
|
|
73
|
+
if (createHash('sha256').update(bytes).digest('hex') !== dependency.sha256)
|
|
74
|
+
throw new Error(`Downloaded ${dependency.name} failed its checksum. No files were installed. Check your connection and retry aug run.`);
|
|
75
|
+
const temporary = archive + '.tmp';
|
|
76
|
+
try { writeFileSync(temporary, bytes); renameSync(temporary, archive); }
|
|
77
|
+
finally { rmSync(temporary, { force: true }); }
|
|
78
|
+
}
|
|
79
|
+
const hash = createHash('sha256').update(readFileSync(archive)).digest('hex');
|
|
80
|
+
if (hash !== dependency.sha256) throw new Error(`${dependency.name}: cached archive checksum mismatch at ${archive}.\nRemove that archive and retry aug run to download the verified copy.`);
|
|
81
|
+
const source = join(sources, dependency.name);
|
|
82
|
+
if (existsSync(join(source, '.archive-sha256')) && readFileSync(join(source, '.archive-sha256'), 'utf8').trim() !== hash)
|
|
83
|
+
throw new Error(`${dependency.name}: source tree differs from the dependency lock. Set AUG_NATIVE_HOME to an empty directory and retry aug run.`);
|
|
84
|
+
if (!existsSync(join(source, '.archive-sha256')) || dependencyArtifacts(dependency.name).filter(file => file.startsWith('sources/')).some(file => !existsSync(join(directory, file)))) {
|
|
85
|
+
mkdirSync(source, { recursive: true });
|
|
86
|
+
run('tar', ['-xf', archive, '-C', source, '--strip-components=1'], directory, 'extract-' + dependency.name);
|
|
87
|
+
writeFileSync(join(source, '.archive-sha256'), hash + '\n');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (extractOnly) return;
|
|
91
|
+
|
|
92
|
+
const sdk = '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk';
|
|
93
|
+
const mac = process.platform === 'darwin';
|
|
94
|
+
const sysroot = mac && existsSync(sdk) ? ' -isysroot ' + sdk : '';
|
|
95
|
+
const environment = { ...process.env, ...(mac && existsSync(sdk) && !process.env.SDKROOT ? { SDKROOT: sdk } : {}), CC: cc, CC_FOR_BUILD: cc, CXX: process.env.CXX ?? cc.replace(/clang$/, 'clang++').replace(/gcc$/, 'g++').replace(/^cc$/, 'c++'),
|
|
96
|
+
CFLAGS: `-O2 -fPIC${sysroot}`,
|
|
97
|
+
CXXFLAGS: `-O2 -fPIC${sysroot}`,
|
|
98
|
+
CPPFLAGS: `-I${prefix}/include${sysroot}`, LDFLAGS: `-L${prefix}/lib -Wl,-rpath,${prefix}/lib`,
|
|
99
|
+
PKG_CONFIG: join(prefix, 'bin', 'pkgconf'), PKG_CONFIG_PATH: join(prefix, 'lib', 'pkgconfig'),
|
|
100
|
+
LD_LIBRARY_PATH: `${prefix}/lib${process.env.LD_LIBRARY_PATH ? ':' + process.env.LD_LIBRARY_PATH : ''}`,
|
|
101
|
+
PATH: join(prefix, 'bin') + ':' + process.env.PATH,
|
|
102
|
+
};
|
|
103
|
+
const parallel = String(Math.min(8, availableParallelism()));
|
|
104
|
+
for (const name of ['pkgconf', 'gmp', 'nettle', 'gnutls']) {
|
|
105
|
+
const marker = join(prefix, '.built-' + name);
|
|
106
|
+
const checksum = lock.dependencies.find(dependency => dependency.name === name).sha256;
|
|
107
|
+
if (existsSync(marker)) {
|
|
108
|
+
if (readFileSync(marker, 'utf8').trim() !== checksum) throw new Error(`${name}: installed build differs from the dependency lock; choose a new build directory.`);
|
|
109
|
+
if (dependencyArtifacts(name).every(file => existsSync(join(directory, file)))) continue;
|
|
110
|
+
}
|
|
111
|
+
const source = join(sources, name);
|
|
112
|
+
const extra = name === 'gmp' ? ['--disable-cxx', '--with-pic'] : name === 'nettle' ? ['--disable-documentation'] : name === 'gnutls' ? [
|
|
113
|
+
'--disable-doc', '--disable-tests', '--disable-tools', '--disable-cxx', '--disable-guile',
|
|
114
|
+
'--disable-nls', '--disable-idn', '--without-p11-kit', '--without-brotli', '--without-zstd',
|
|
115
|
+
'--with-included-libtasn1', '--with-included-unistring', '--disable-libdane',
|
|
116
|
+
] : [];
|
|
117
|
+
// GnuTLS 3.8.13's audit header does not define this diagnostic-only macro
|
|
118
|
+
// when Clang 14 reports __has_c_attribute but lacks [[maybe_unused]].
|
|
119
|
+
const buildEnvironment = name === 'gnutls' && !mac ?
|
|
120
|
+
{...environment, CFLAGS: environment.CFLAGS + ' -DCRAU_MAYBE_UNUSED='} : environment;
|
|
121
|
+
process.stdout.write(`Building ${name}; logs: ${logs}\n`);
|
|
122
|
+
// A relative invocation keeps Autoconf's srcdir local. An absolute alias (e.g. /var -> /private/var)
|
|
123
|
+
// can make GnuTLS treat this as a VPATH build and replace GNUmakefile with a link to itself.
|
|
124
|
+
run('./configure', ['--prefix=' + prefix, '--libdir=' + join(prefix, 'lib'), '--enable-shared', '--disable-static', ...extra], source, name + '-configure', buildEnvironment);
|
|
125
|
+
run('make', ['-j' + parallel], source, name + '-build', buildEnvironment);
|
|
126
|
+
run('make', ['install'], source, name + '-install', buildEnvironment);
|
|
127
|
+
if (name === 'nettle') run(join(prefix, 'bin', 'pkgconf'), ['--modversion', 'nettle', 'hogweed'], root, 'nettle-pkgconf', environment);
|
|
128
|
+
writeFileSync(marker, checksum + '\n');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (profile === 'web') {
|
|
132
|
+
const cmake = mac ? join(sources, 'cmake', 'CMake.app', 'Contents', 'bin', 'cmake') : 'cmake';
|
|
133
|
+
const build = join(directory, 'build-libwebsockets');
|
|
134
|
+
const webMarker = join(prefix, '.built-libwebsockets');
|
|
135
|
+
const webChecksum = lock.dependencies.find(dependency => dependency.name === 'libwebsockets').sha256;
|
|
136
|
+
if (existsSync(webMarker) && readFileSync(webMarker, 'utf8').trim() !== webChecksum)
|
|
137
|
+
throw new Error('libwebsockets: installed build differs from the dependency lock; choose a new build directory.');
|
|
138
|
+
if (!existsSync(webMarker) || !dependencyArtifacts('libwebsockets').every(file => existsSync(join(directory, file)))) {
|
|
139
|
+
process.stdout.write(`Building libwebsockets with GnuTLS, HTTP/2 and HTTP/3\n`);
|
|
140
|
+
run(cmake, ['-S', join(sources, 'libwebsockets'), '-B', build,
|
|
141
|
+
'-DCMAKE_BUILD_TYPE=Release', '-DCMAKE_INSTALL_PREFIX=' + prefix, '-DCMAKE_INSTALL_LIBDIR=lib', '-DCMAKE_PREFIX_PATH=' + prefix,
|
|
142
|
+
'-DCMAKE_C_COMPILER=' + cc, ...(mac && existsSync(sdk) && !process.env.SDKROOT ? ['-DCMAKE_OSX_SYSROOT=' + sdk] : []),
|
|
143
|
+
'-DLWS_GNUTLS_LIBRARIES=' + join(prefix, 'lib', mac ? 'libgnutls.dylib' : 'libgnutls.so'),
|
|
144
|
+
'-DLWS_GNUTLS_INCLUDE_DIRS=' + join(prefix, 'include'),
|
|
145
|
+
'-DLWS_WITH_GNUTLS=ON', '-DLWS_WITH_HTTP2=ON', '-DLWS_WITH_HTTP3=ON',
|
|
146
|
+
'-DLWS_WITH_STATIC=ON', '-DLWS_WITH_SHARED=OFF', '-DLWS_WITHOUT_TESTAPPS=ON',
|
|
147
|
+
'-DLWS_WITHOUT_TEST_SERVER=ON', '-DLWS_WITHOUT_TEST_CLIENT=ON',
|
|
148
|
+
'-DLWS_WITH_LIBUV=OFF', '-DLWS_WITH_LIBEVENT=OFF', '-DLWS_WITH_LIBEV=OFF',
|
|
149
|
+
'-DLWS_WITH_GLIB=OFF', '-DLWS_WITHOUT_EXTENSIONS=ON', '-DLWS_WITH_ZLIB=OFF',
|
|
150
|
+
], root, 'libwebsockets-configure', environment);
|
|
151
|
+
run(cmake, ['--build', build, '--parallel', parallel], root, 'libwebsockets-build', environment);
|
|
152
|
+
run(cmake, ['--install', build], root, 'libwebsockets-install', environment);
|
|
153
|
+
writeFileSync(webMarker, webChecksum + '\n');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
writeFileSync(join(prefix, 'aug-native-manifest.json'), JSON.stringify({ platform: process.platform, architecture: process.arch,
|
|
157
|
+
dependencies: lock.dependencies.filter(dependency => dependencyReady(directory, dependency)).map(({name, version, revision, sha256}) => ({name, version, revision, sha256})) }, null, 2) + '\n');
|
|
158
|
+
process.stdout.write(`Native dependencies ready at ${prefix}\n`);
|
|
159
|
+
} finally { release(); }
|
|
55
160
|
}
|
|
56
|
-
if (extractOnly) process.exit(0);
|
|
57
161
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
162
|
+
/** One writer per cache. An interrupted setup leaves a recoverable PID lock. */
|
|
163
|
+
async function acquireLock(directory) {
|
|
164
|
+
const path = join(directory, '.setup-lock');
|
|
165
|
+
const started = Date.now(); let announced = false;
|
|
166
|
+
while (true) {
|
|
167
|
+
try {
|
|
168
|
+
const descriptor = openSync(path, 'wx');
|
|
169
|
+
try { writeFileSync(descriptor, JSON.stringify({ pid: process.pid })); }
|
|
170
|
+
finally { closeSync(descriptor); }
|
|
171
|
+
return () => rmSync(path, { force: true });
|
|
172
|
+
} catch (error) {
|
|
173
|
+
if (error.code !== 'EEXIST') throw error;
|
|
174
|
+
try {
|
|
175
|
+
const owner = JSON.parse(readFileSync(path, 'utf8'));
|
|
176
|
+
if (Number.isInteger(owner.pid) && owner.pid > 0) {
|
|
177
|
+
try { process.kill(owner.pid, 0); }
|
|
178
|
+
catch (error) { if (error.code === 'ESRCH') { rmSync(path, { force: true }); continue; } }
|
|
179
|
+
} else if (Date.now() - statSync(path).mtimeMs > 30000) { rmSync(path, { force: true }); continue; }
|
|
180
|
+
} catch (error) {
|
|
181
|
+
if (error.code === 'ENOENT') continue;
|
|
182
|
+
if (error instanceof SyntaxError && Date.now() - statSync(path).mtimeMs > 30000) { rmSync(path, { force: true }); continue; }
|
|
183
|
+
}
|
|
184
|
+
if (!announced) { process.stdout.write('Waiting for another August process to prepare the native cache.\n'); announced = true; }
|
|
185
|
+
if (Date.now() - started > 600000) throw new Error(`Another native setup still holds ${path}. Wait for it to finish, then retry aug run.`);
|
|
186
|
+
await new Promise(accept => setTimeout(accept, 500));
|
|
187
|
+
}
|
|
77
188
|
}
|
|
78
|
-
const source = join(sources, name);
|
|
79
|
-
const extra = name === 'gmp' ? ['--disable-cxx', '--with-pic'] : name === 'nettle' ? ['--disable-documentation'] : name === 'gnutls' ? [
|
|
80
|
-
'--disable-doc', '--disable-tests', '--disable-tools', '--disable-cxx', '--disable-guile',
|
|
81
|
-
'--disable-nls', '--disable-idn', '--without-p11-kit', '--without-brotli', '--without-zstd',
|
|
82
|
-
'--with-included-libtasn1', '--with-included-unistring', '--disable-libdane',
|
|
83
|
-
] : [];
|
|
84
|
-
// GnuTLS 3.8.13's audit header does not define this diagnostic-only macro
|
|
85
|
-
// when Clang 14 reports __has_c_attribute but lacks [[maybe_unused]].
|
|
86
|
-
const buildEnvironment = name === 'gnutls' && !mac ?
|
|
87
|
-
{...environment, CFLAGS: environment.CFLAGS + ' -DCRAU_MAYBE_UNUSED='} : environment;
|
|
88
|
-
process.stdout.write(`Building ${name}; logs: ${logs}\n`);
|
|
89
|
-
run(join(source, 'configure'), ['--prefix=' + prefix, '--libdir=' + join(prefix, 'lib'), '--enable-shared', '--disable-static', ...extra], source, name + '-configure', buildEnvironment);
|
|
90
|
-
run('/usr/bin/make', ['-j' + parallel], source, name + '-build', buildEnvironment);
|
|
91
|
-
run('/usr/bin/make', ['install'], source, name + '-install', buildEnvironment);
|
|
92
|
-
if (name === 'nettle') run(join(prefix, 'bin', 'pkgconf'), ['--modversion', 'nettle', 'hogweed'], root, 'nettle-pkgconf', environment);
|
|
93
|
-
writeFileSync(marker, checksum + '\n');
|
|
94
189
|
}
|
|
95
190
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
throw new Error('libwebsockets: installed build differs from the dependency lock; choose a new build directory.');
|
|
102
|
-
if (!existsSync(webMarker)) {
|
|
103
|
-
process.stdout.write(`Building libwebsockets with GnuTLS, HTTP/2 and HTTP/3\n`);
|
|
104
|
-
run(cmake, ['-S', join(sources, 'libwebsockets'), '-B', build,
|
|
105
|
-
'-DCMAKE_BUILD_TYPE=Release', '-DCMAKE_INSTALL_PREFIX=' + prefix, '-DCMAKE_INSTALL_LIBDIR=lib', '-DCMAKE_PREFIX_PATH=' + prefix,
|
|
106
|
-
'-DCMAKE_C_COMPILER=' + cc, ...(mac ? ['-DCMAKE_OSX_SYSROOT=' + sdk] : []),
|
|
107
|
-
'-DLWS_GNUTLS_LIBRARIES=' + join(prefix, 'lib', mac ? 'libgnutls.dylib' : 'libgnutls.so'),
|
|
108
|
-
'-DLWS_GNUTLS_INCLUDE_DIRS=' + join(prefix, 'include'),
|
|
109
|
-
'-DLWS_WITH_GNUTLS=ON', '-DLWS_WITH_HTTP2=ON', '-DLWS_WITH_HTTP3=ON',
|
|
110
|
-
'-DLWS_WITH_STATIC=ON', '-DLWS_WITH_SHARED=OFF', '-DLWS_WITHOUT_TESTAPPS=ON',
|
|
111
|
-
'-DLWS_WITHOUT_TEST_SERVER=ON', '-DLWS_WITHOUT_TEST_CLIENT=ON',
|
|
112
|
-
'-DLWS_WITH_LIBUV=OFF', '-DLWS_WITH_LIBEVENT=OFF', '-DLWS_WITH_LIBEV=OFF',
|
|
113
|
-
'-DLWS_WITH_GLIB=OFF', '-DLWS_WITHOUT_EXTENSIONS=ON', '-DLWS_WITH_ZLIB=OFF',
|
|
114
|
-
], root, 'libwebsockets-configure', environment);
|
|
115
|
-
run(cmake, ['--build', build, '--parallel', parallel], root, 'libwebsockets-build', environment);
|
|
116
|
-
run(cmake, ['--install', build], root, 'libwebsockets-install', environment);
|
|
117
|
-
writeFileSync(webMarker, webChecksum + '\n');
|
|
191
|
+
try { await setup(); }
|
|
192
|
+
catch (error) {
|
|
193
|
+
const permission = ['EACCES', 'EPERM', 'EROFS'].includes(error.code) ? '\nChoose a writable cache: set AUG_NATIVE_HOME to a directory you own and retry aug run.' : '';
|
|
194
|
+
process.stderr.write(`Native setup: ${error.message}${permission}\n`);
|
|
195
|
+
process.exitCode = 1;
|
|
118
196
|
}
|
|
119
|
-
writeFileSync(join(prefix, 'aug-native-manifest.json'), JSON.stringify({ platform: process.platform, architecture: process.arch,
|
|
120
|
-
dependencies: dependencies.map(({name, version, revision, sha256}) => ({name, version, revision, sha256})) }, null, 2) + '\n');
|
|
121
|
-
process.stdout.write(`Native dependencies ready at ${prefix}\n`);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join, resolve } from 'node:path';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
4
|
+
import { nativeHome } from './native-home.mjs';
|
|
5
|
+
import { cCompiler } from './native-toolchain.mjs';
|
|
6
|
+
|
|
7
|
+
/** Inspect C identifiers, excluding comments and string literals. Shared with the linker. */
|
|
8
|
+
export function nativeRequirements(generated) {
|
|
9
|
+
const code = generated.replace(/\/\*[\s\S]*?\*\/|\/\/[^\n]*|"(?:\\[\s\S]|[^"\\])*"|'(?:\\[\s\S]|[^'\\])*'/g, ' ');
|
|
10
|
+
const web = /\b(?:_?aug_http_|aug_headers_)\w*/.test(code);
|
|
11
|
+
return { web, crypto: web || /\b_aug_crypto_\w*/.test(code),
|
|
12
|
+
tasks: web || /\baug_task_\w*/.test(code), json: web || /\b_?aug_json_\w*/.test(code),
|
|
13
|
+
html: web || /\baug_html_\w*/.test(code), time: /\b_aug_time_\w*/.test(code) };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const artifacts = {
|
|
17
|
+
minicoro: ['sources/minicoro/minicoro.h'], yyjson: ['sources/yyjson/src/yyjson.c', 'sources/yyjson/src/yyjson.h'],
|
|
18
|
+
pkgconf: ['prefix/bin/pkgconf'], gmp: ['prefix/include/gmp.h'],
|
|
19
|
+
nettle: ['prefix/include/nettle/nettle-types.h'], gnutls: ['prefix/include/gnutls/gnutls.h'],
|
|
20
|
+
libwebsockets: ['prefix/lib/libwebsockets.a', 'prefix/include/libwebsockets.h'],
|
|
21
|
+
};
|
|
22
|
+
export function dependencyArtifacts(name) {
|
|
23
|
+
const library = { gmp: ['gmp'], nettle: ['nettle', 'hogweed'], gnutls: ['gnutls'] }[name] ?? [];
|
|
24
|
+
return [...(artifacts[name] ?? []), ...library.map(item => `prefix/lib/lib${item}.${process.platform === 'darwin' ? 'dylib' : 'so'}`)];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function dependencyReady(directory, dependency) {
|
|
28
|
+
const marker = join(directory, ['minicoro', 'yyjson'].includes(dependency.name) ?
|
|
29
|
+
`sources/${dependency.name}/.archive-sha256` : `prefix/.built-${dependency.name}`);
|
|
30
|
+
return existsSync(marker) && readFileSync(marker, 'utf8').trim() === dependency.sha256 &&
|
|
31
|
+
dependencyArtifacts(dependency.name).every(file => existsSync(join(directory, file)));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Prepare the precise native capabilities emitted by the compiler, keeping stdout for the program. */
|
|
35
|
+
export async function prepareNativeDependencies(generated, { offline = false, progress = message => process.stderr.write(message) } = {}) {
|
|
36
|
+
const needs = nativeRequirements(generated);
|
|
37
|
+
cCompiler(); // Fail before downloading when the host cannot compile the application.
|
|
38
|
+
if (!needs.json && !needs.tasks && !needs.crypto) return;
|
|
39
|
+
const root = resolve(import.meta.dirname, '..'), directory = nativeHome(root);
|
|
40
|
+
const lock = JSON.parse(readFileSync(join(import.meta.dirname, 'native-dependencies.lock.json'), 'utf8'));
|
|
41
|
+
const names = [...(needs.json ? ['yyjson'] : []), ...(needs.tasks ? ['minicoro'] : []),
|
|
42
|
+
...(needs.crypto ? ['pkgconf', 'gmp', 'nettle', 'gnutls'] : []), ...(needs.web ? ['libwebsockets'] : [])];
|
|
43
|
+
const required = lock.dependencies.filter(item => names.includes(item.name));
|
|
44
|
+
const manifestPath = join(directory, 'prefix/aug-native-manifest.json');
|
|
45
|
+
let manifest;
|
|
46
|
+
if (needs.crypto && existsSync(manifestPath)) {
|
|
47
|
+
try {
|
|
48
|
+
manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
49
|
+
if (!manifest || typeof manifest.platform !== 'string' || typeof manifest.architecture !== 'string' || !Array.isArray(manifest.dependencies))
|
|
50
|
+
throw new Error('Invalid metadata');
|
|
51
|
+
}
|
|
52
|
+
catch { throw new Error(`Native cache metadata is unreadable: ${manifestPath}\nSet AUG_NATIVE_HOME to an empty directory and retry aug run.`); }
|
|
53
|
+
if (manifest.platform !== process.platform || manifest.architecture !== process.arch)
|
|
54
|
+
throw new Error(`Native cache targets ${manifest.platform}/${manifest.architecture}; this computer is ${process.platform}/${process.arch}.\nSet AUG_NATIVE_HOME to a cache built on this computer, or unset it and retry aug run.`);
|
|
55
|
+
}
|
|
56
|
+
const libraries = required.filter(item => !['yyjson', 'minicoro'].includes(item.name));
|
|
57
|
+
const manifestReady = !needs.crypto || libraries.every(item => manifest?.dependencies?.some(entry => entry.name === item.name && entry.sha256 === item.sha256));
|
|
58
|
+
if (manifestReady && required.every(item => dependencyReady(directory, item))) return;
|
|
59
|
+
const capabilities = [needs.json && 'JSON', needs.tasks && 'tasks', needs.crypto && 'crypto', needs.web && 'HTTP'].filter(Boolean).join(', ');
|
|
60
|
+
progress(`Preparing native dependencies for ${capabilities} (cached at ${directory}). First use may take a few minutes.\n`);
|
|
61
|
+
const args = needs.crypto ? ['--profile', needs.web ? 'web' : 'crypto'] : ['--extract-only', '--only', names.join(',')];
|
|
62
|
+
// Crypto source packages can use JSON or tasks without needing HTTP. The
|
|
63
|
+
// crypto profile builds libraries only, so prepare those source dependencies
|
|
64
|
+
// separately. The web profile already includes both.
|
|
65
|
+
const portable = needs.crypto && !needs.web ? required.filter(item =>
|
|
66
|
+
['yyjson', 'minicoro'].includes(item.name) && !dependencyReady(directory, item)).map(item => item.name) : [];
|
|
67
|
+
const preparations = [...(portable.length ? [['--extract-only', '--only', portable.join(',')]] : []), args];
|
|
68
|
+
for (const preparation of preparations) {
|
|
69
|
+
if (offline) preparation.push('--offline');
|
|
70
|
+
await new Promise((accept, reject) => {
|
|
71
|
+
const child = spawn(process.execPath, [join(import.meta.dirname, 'bootstrap-native.mjs'), ...preparation], {
|
|
72
|
+
stdio: ['ignore', 'pipe', 'pipe'], detached: process.platform !== 'win32' });
|
|
73
|
+
let detail = '', interrupted;
|
|
74
|
+
const stop = signal => {
|
|
75
|
+
interrupted = signal;
|
|
76
|
+
try { if (process.platform !== 'win32' && child.pid) process.kill(-child.pid, signal); else child.kill(signal); }
|
|
77
|
+
catch (error) { if (error.code !== 'ESRCH') child.kill(signal); }
|
|
78
|
+
};
|
|
79
|
+
const interrupt = () => stop('SIGINT'), terminate = () => stop('SIGTERM');
|
|
80
|
+
process.once('SIGINT', interrupt); process.once('SIGTERM', terminate);
|
|
81
|
+
const cleanup = () => { process.off('SIGINT', interrupt); process.off('SIGTERM', terminate); };
|
|
82
|
+
child.stdout.on('data', data => progress(data.toString()));
|
|
83
|
+
child.stderr.on('data', data => { detail = (detail + data.toString()).slice(-12000); progress(data.toString()); });
|
|
84
|
+
child.on('error', error => { cleanup(); reject(new Error(`Cannot start native dependency setup: ${error.message}\nRetry aug run after checking your Node installation.`)); });
|
|
85
|
+
child.on('close', (status, signal) => {
|
|
86
|
+
cleanup();
|
|
87
|
+
if (interrupted) {
|
|
88
|
+
const error = new Error(`Native setup cancelled by ${interrupted}. Retry aug run to resume using the completed dependencies.`);
|
|
89
|
+
error.exitCode = interrupted === 'SIGINT' ? 130 : 143; reject(error);
|
|
90
|
+
} else if (status === 0) accept();
|
|
91
|
+
else reject(new Error(`Native dependency setup ${signal ? `stopped by ${signal}` : `failed (exit ${status})`}. ${detail ? 'See the error above.' : `Check the setup logs in ${join(directory, 'logs')}.`}\nRetry aug run after addressing it; completed dependencies will be reused.`));
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
const missing = required.filter(item => !dependencyReady(directory, item)).map(item => item.name);
|
|
96
|
+
if (missing.length)
|
|
97
|
+
throw new Error(`Native setup did not prepare ${missing.join(', ')} in ${directory}.\nCheck the setup logs in ${join(directory, 'logs')} and retry aug run; completed dependencies will be reused.`);
|
|
98
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
|
|
4
|
+
export function compilerHelp() {
|
|
5
|
+
const install = process.platform === 'darwin' ? 'Install the Apple Command Line Tools with: xcode-select --install' :
|
|
6
|
+
process.platform === 'linux' ? 'Install a C toolchain (Debian/Ubuntu: sudo apt-get install build-essential; Fedora: sudo dnf install gcc make).' :
|
|
7
|
+
'Use a Linux Dev Container or install a C11 compiler with POSIX threads support.';
|
|
8
|
+
return `${install}\nIf a compiler is already installed, set CC to its executable path and retry aug run.`;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Select an executable, including installations with only Apple's Command Line Tools. */
|
|
12
|
+
export function cCompiler() {
|
|
13
|
+
const xcode = '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang';
|
|
14
|
+
const candidates = process.env.CC ? [process.env.CC] : [...(existsSync(xcode) ? [xcode] : []), 'clang', 'cc', 'gcc'];
|
|
15
|
+
for (const command of candidates) {
|
|
16
|
+
const result = spawnSync(command, ['--version'], { encoding: 'utf8', timeout: 10000 });
|
|
17
|
+
if (!result.error && result.status === 0) return command;
|
|
18
|
+
}
|
|
19
|
+
throw new Error(`Cannot use a C compiler${process.env.CC ? ` from CC=${process.env.CC}` : ' on this computer'}.\n${compilerHelp()}`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function requireBuildTool(command, args = ['--version']) {
|
|
23
|
+
const result = spawnSync(command, args, { encoding: 'utf8', timeout: 10000 });
|
|
24
|
+
if (!result.error && result.status === 0) return;
|
|
25
|
+
const install = process.platform === 'darwin' ? 'Install the Apple Command Line Tools with xcode-select --install.' :
|
|
26
|
+
'Install the build tools (Debian/Ubuntu: sudo apt-get install build-essential m4 cmake zlib1g-dev; Fedora: sudo dnf install gcc make m4 cmake zlib-devel).';
|
|
27
|
+
throw new Error(`Native dependency setup needs ${command}, but it could not run.\n${install}\nRetry aug run after installing it.`);
|
|
28
|
+
}
|
package/src/builtins.js
CHANGED
|
@@ -85,7 +85,7 @@ export const builtinFunctions = [
|
|
|
85
85
|
{ name: 'exit', parameters: [{ label: 'status', type: 'int' }], returns: 'void', documentation: 'Exit from main with a status from 0 to 255 after cancellation and cleanup.', native: 'exit' },
|
|
86
86
|
{ name: 'c_int', parameters: [{ label: 'value', type: 'int' }], returns: 'c_int', errors: ['ConversionError'], documentation: 'Checked conversion to a signed 32-bit C int. Overflow raises ConversionError. AugScript int maps to int64_t at the C boundary.', native: 'to_c_int' },
|
|
87
87
|
{ name: 'int', parameters: [{ label: 'value', type: 'c_int' }], returns: 'int', documentation: 'Widen a C int to the signed 64-bit AugScript integer without loss.', native: 'to_int' },
|
|
88
|
-
{ name: 'print', parameters: [{ label: 'value', type: 'any' }], returns: 'void', documentation: '
|
|
88
|
+
{ name: 'print', parameters: [{ label: 'value', type: 'any' }], returns: 'void', documentation: 'Write application startup or test output. Other callables receive a Console dependency and call console.write; their bodies infer that capability use.', native: 'print' },
|
|
89
89
|
{ name: 'assert', parameters: [{ label: 'condition', type: 'bool' }], returns: 'void', documentation: 'Assert a bool in a test case or its setup. Catching an assertion failure cannot make the case pass; every case must execute an assertion.', native: 'assert' },
|
|
90
90
|
{ name: 'arguments', parameters: [], returns: 'List<string>', documentation: 'Composition arguments. Other callables receive the Arguments capability.', native: 'arguments' },
|
|
91
91
|
{ name: 'read_file', parameters: [{ label: 'path', type: 'string' }], returns: 'string', errors: ['FileError'], documentation: 'Root-only UTF-8 text input. Other callables receive FileReader. Invalid Unicode and NUL raise FileError.', native: 'read_file' },
|