g2a-com / klio Goto Github PK
View Code? Open in Web Editor NEWCrossover between a CLI framework and a package manager
License: MIT License
Crossover between a CLI framework and a package manager
License: MIT License
When klio.yaml is empty, klio get
fails with following error:
[INFO] Installed [email protected] from file:///Users/qzb/Workspace/klio/registry.yaml as deploy
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x48 pc=0x1389186]
goroutine 1 [running]:
gopkg.in/yaml%2ev3.handleErr(0xc0002370e0)
/Users/qzb/.go/pkg/mod/gopkg.in/[email protected]/yaml.go:294 +0x85
panic(0x1462f60, 0x17ac0c0)
/usr/local/opt/go/libexec/src/runtime/panic.go:969 +0x175
github.com/g2a-com/klio/internal/schema.ProjectConfig.MarshalYAML(0xc000238750, 0x23, 0x1, 0x0, 0x0, 0xc000020230, 0x1, 0x1, 0x0, 0x0, ...)
/Users/qzb/Workspace/klio/internal/schema/schema.go:62 +0x46
gopkg.in/yaml%2ev3.(*encoder).marshal(0xc00035a000, 0x0, 0x0, 0x1465200, 0xc0000c3310, 0x16)
/Users/qzb/.go/pkg/mod/gopkg.in/[email protected]/encode.go:135 +0x196
gopkg.in/yaml%2ev3.(*encoder).marshalDoc(0xc00035a000, 0x0, 0x0, 0x1465200, 0xc0000c3310, 0x16)
/Users/qzb/.go/pkg/mod/gopkg.in/[email protected]/encode.go:105 +0x137
gopkg.in/yaml%2ev3.(*Encoder).Encode(0xc000237138, 0x1465200, 0xc0000c3310, 0x0, 0x0)
/Users/qzb/.go/pkg/mod/gopkg.in/[email protected]/yaml.go:251 +0xea
github.com/g2a-com/klio/internal/schema.SaveConfigFile(0x1465200, 0xc0000c3310, 0xc000238750, 0x23, 0x1, 0xc000020230)
/Users/qzb/Workspace/klio/internal/schema/util.go:72 +0x4cd
github.com/g2a-com/klio/internal/schema.SaveProjectConfig(...)
/Users/qzb/Workspace/klio/internal/schema/util.go:99
github.com/g2a-com/klio/internal/cmd/get.run(0x14cc754, 0x4, 0x0, 0x0, 0x0, 0x0, 0xc000241190, 0x9, 0xc000241188, 0x5, ...)
/Users/qzb/Workspace/klio/internal/cmd/get/get.go:126 +0x3d0
github.com/g2a-com/klio/internal/cmd/get.NewCommand.func1(0xc000243680, 0xc0001e7830, 0x1, 0x3)
/Users/qzb/Workspace/klio/internal/cmd/get/get.go:31 +0xc5
github.com/spf13/cobra.(*Command).execute(0xc000243680, 0xc0001e77a0, 0x3, 0x3, 0xc000243680, 0xc0001e77a0)
/Users/qzb/.go/pkg/mod/github.com/spf13/[email protected]/command.go:766 +0x2c2
github.com/spf13/cobra.(*Command).ExecuteC(0xc000243400, 0x4, 0x0, 0x0)
/Users/qzb/.go/pkg/mod/github.com/spf13/[email protected]/command.go:852 +0x2fe
github.com/spf13/cobra.(*Command).Execute(...)
/Users/qzb/.go/pkg/mod/github.com/spf13/[email protected]/command.go:800
github.com/g2a-com/klio/pkg/cli.(*CLI).Execute(0xc000237f38, 0x1775520, 0xc000000180)
/Users/qzb/Workspace/klio/pkg/cli/cli.go:38 +0x389
main.main()
/Users/qzb/Workspace/klio/cmd/klio/klio.go:17 +0x73
This error doesn't occur when klio.yaml contains dependencies property:
dependencies: {}
New registry format supports annotating dependencies (and whole registry as well). We can use this feature to provide better prompts about updates. I don't know yet how this annotations should look, but I have few ideas for how they could be used:
I'm not sure if we want all of these to be implemented, let me know what do you think.
To install klio
you need go
and some basic knowledge about compiling. It's not very user friendly.
It would be awesome to have oneliner to install klio
on every platform.
Don't have much experience with windows and linux platforms but for macOS there is awesome tool called brew
.
Basically there are two ways to use brew
, official - which requires some "popularity" for library and TAP (https://docs.brew.sh/Taps). As a temporary solution I think we can use tap. It works very well with goreleaser
and github actions to make it fully automated.
Decide the license for klio project - core repository and other subrepositories (for example for dedicated commands) and place LICENSE file in root of repository.
When you try to install command with the same name as one of builtins, klio seems to work:
$ klio get hello --as get --from https://raw.githubusercontent.com/g2a-com/klio-example-command/main/registry.yaml
[INFO] Installed [email protected] from https://raw.githubusercontent.com/g2a-com/klio-example-command/main/registry.yaml as get
[INFO] Updated dependencies in the klio.yaml file
But when you try to use such command, turns out that klio ignores it and runs builtin (as it should). It would be less confusing to simply exit with error during installation.
Create great documentation and produce godoc integration
Current name and description of the CLI have to be changed (obviously). To make such change possible, current CLI should be turned into a Go library which will be used to implement kilo
command, and (possibly) other, branded versions of the CLI.
A proper pipeline of tests should be established with Github actions.
Scope:
Bash / Zsh shells should be supported in first version.
Two commands should be created which output completion scripts for particular shell
klio completion bash
klio completion zsh
Klio shell completions should have a mechanism for including completions from upstream commands (not being part of klio core)
Currently klio get
doesn't indicate progress when downloading commands. Usually it's not an issue, but sometimes it stucks for quite a long time (and ruins user experience).
Klio runs into an error while running with specified commmand get and within project scope
Release step from release-please ends up with error:
2022-06-03T21:35:01.5096821Z ##[group]Run GoogleCloudPlatform/release-please-action@v2
2022-06-03T21:35:01.5097362Z with:
2022-06-03T21:35:01.5097647Z release-type: go
2022-06-03T21:35:01.5097943Z package-name: klio
2022-06-03T21:35:01.5098596Z token: ***
2022-06-03T21:35:01.5098838Z fork: false
2022-06-03T21:35:01.5099095Z clean: true
2022-06-03T21:35:01.5099398Z bump-minor-pre-major: false
2022-06-03T21:35:01.5099779Z bump-patch-for-minor-pre-major: false
2022-06-03T21:35:01.5100165Z monorepo-tags: false
2022-06-03T21:35:01.5100614Z pull-request-title-pattern: chore${scope}: release${component} ${version}
2022-06-03T21:35:01.5101033Z ##[endgroup]
2022-06-03T21:35:01.8942020Z (node:1513) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
2022-06-03T21:35:02.8001030Z ⚠ No merged release PR found
2022-06-03T21:35:02.8005211Z ✖ Unable to build candidate
2022-06-03T21:35:08.8284510Z ✔ found 2 commits since c33f93c
2022-06-03T21:35:08.8364586Z ✔ release as patch: There are 0 BREAKING CHANGES and 0 features
2022-06-03T21:35:09.1820256Z ⚠ CHANGELOG.md not found
2022-06-03T21:35:09.1820764Z ✔ creating CHANGELOG.md
2022-06-03T21:35:09.1828734Z ✔ Starting GitHub PR workflow...
2022-06-03T21:35:09.2907843Z ✔ Successfully found branch HEAD sha "c7c642369d87ca81f6af5b920c71161cbcc54ab8".
2022-06-03T21:35:09.5748480Z ✖ Error when creating branch
2022-06-03T21:35:09.5782313Z ✖ RequestError [HttpError]: Error creating Pull Request: Resource not accessible by integration
2022-06-03T21:35:09.5782892Z ✔ Retry attempt #1...
2022-06-03T21:35:09.5784017Z at /home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:9981:21
2022-06-03T21:35:09.5785154Z at processTicksAndRejections (internal/process/task_queues.js:97:5)
2022-06-03T21:35:09.5786838Z at async createBranch (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:11767:26)
2022-06-03T21:35:09.5787996Z at async Object.branch (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:11795:9)
2022-06-03T21:35:09.5788792Z at async retry.retries (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:12469:48)
2022-06-03T21:35:09.5789657Z at async Object.createPullRequest (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:12469:24)
2022-06-03T21:35:09.5790431Z at async /home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:60463:30
2022-06-03T21:35:09.5792193Z at async GitHub.openPR (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:61570:20)
2022-06-03T21:35:09.5793010Z at async Go.openPR (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:63386:20)
2022-06-03T21:35:09.5793748Z at async Go._run (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:63238:32) {
2022-06-03T21:35:09.5794197Z status: 403,
2022-06-03T21:35:09.5795004Z response: {
2022-06-03T21:35:09.5795743Z url: 'https://api.github.com/repos/g2a-com/klio/git/refs',
2022-06-03T21:35:09.5796130Z status: 403,
2022-06-03T21:35:09.5796783Z headers: {
2022-06-03T21:35:09.5797541Z 'access-control-allow-origin': '',
2022-06-03T21:35:09.5798751Z 'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset',
2022-06-03T21:35:09.5799676Z connection: 'close',
2022-06-03T21:35:09.5800475Z 'content-encoding': 'gzip',
2022-06-03T21:35:09.5800969Z 'content-security-policy': "default-src 'none'",
2022-06-03T21:35:09.5801515Z 'content-type': 'application/json; charset=utf-8',
2022-06-03T21:35:09.5802205Z date: 'Fri, 03 Jun 2022 21:35:09 GMT',
2022-06-03T21:35:09.5802980Z 'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin',
2022-06-03T21:35:09.5803516Z server: 'GitHub.com',
2022-06-03T21:35:09.5804063Z 'strict-transport-security': 'max-age=31536000; includeSubdomains; preload',
2022-06-03T21:35:09.5804588Z 'transfer-encoding': 'chunked',
2022-06-03T21:35:09.5805066Z vary: 'Accept-Encoding, Accept, X-Requested-With',
2022-06-03T21:35:09.5805547Z 'x-content-type-options': 'nosniff',
2022-06-03T21:35:09.5805961Z 'x-frame-options': 'deny',
2022-06-03T21:35:09.5806420Z 'x-github-media-type': 'github.v3; format=json',
2022-06-03T21:35:09.5806939Z 'x-github-request-id': '07C5:6420:B4D360:18CF26B:629A7E8D',
2022-06-03T21:35:09.5807811Z 'x-ratelimit-limit': '1000',
2022-06-03T21:35:09.5808217Z 'x-ratelimit-remaining': '988',
2022-06-03T21:35:09.5808667Z 'x-ratelimit-reset': '1654295702',
2022-06-03T21:35:09.5809092Z 'x-ratelimit-resource': 'core',
2022-06-03T21:35:09.5809506Z 'x-ratelimit-used': '12',
2022-06-03T21:35:09.5809895Z 'x-xss-protection': '0'
2022-06-03T21:35:09.5810204Z },
2022-06-03T21:35:09.5810411Z data: {
2022-06-03T21:35:09.5810811Z message: 'Resource not accessible by integration',
2022-06-03T21:35:09.5811408Z documentation_url: 'https://docs.github.com/rest/reference/git#create-a-reference'
2022-06-03T21:35:09.5811806Z }
2022-06-03T21:35:09.5812012Z },
2022-06-03T21:35:09.5812191Z request: {
2022-06-03T21:35:09.5812549Z method: 'POST',
2022-06-03T21:35:09.5813017Z url: 'https://api.github.com/repos/g2a-com/klio/git/refs',
2022-06-03T21:35:09.5813365Z headers: {
2022-06-03T21:35:09.5813719Z accept: 'application/vnd.github.v3+json',
2022-06-03T21:35:09.5814304Z 'user-agent': 'octokit-rest.js/18.12.0 octokit-core.js/3.5.1 Node.js/12.22.7 (linux; x64)',
2022-06-03T21:35:09.5814795Z authorization: 'token [REDACTED]',
2022-06-03T21:35:09.5815251Z 'content-type': 'application/json; charset=utf-8'
2022-06-03T21:35:09.5815600Z },
2022-06-03T21:35:09.5816150Z body: '{"ref":"refs/heads/release-v1.0.1","sha":"c7c642369d87ca81f6af5b920c71161cbcc54ab8"}',
2022-06-03T21:35:09.5816605Z request: { hook: [Function: bound bound register] }
2022-06-03T21:35:09.5816915Z }
2022-06-03T21:35:09.5817111Z }
2022-06-03T21:35:12.6906378Z ✔ Successfully found branch HEAD sha "c7c642369d87ca81f6af5b920c71161cbcc54ab8".
2022-06-03T21:35:12.9492115Z ✖ Error when creating branch
2022-06-03T21:35:12.9497462Z ✖ RequestError [HttpError]: Error creating Pull Request: Resource not accessible by integration
2022-06-03T21:35:12.9498433Z at /home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:9981:21
2022-06-03T21:35:12.9498882Z ✔ Retry attempt #2...
2022-06-03T21:35:12.9499826Z at processTicksAndRejections (internal/process/task_queues.js:97:5)
2022-06-03T21:35:12.9500755Z at async createBranch (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:11767:26)
2022-06-03T21:35:12.9501512Z at async Object.branch (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:11795:9)
2022-06-03T21:35:12.9502252Z at async retry.retries (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:12469:48)
2022-06-03T21:35:12.9503022Z at async Object.createPullRequest (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:12469:24)
2022-06-03T21:35:12.9503756Z at async /home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:60463:30
2022-06-03T21:35:12.9504459Z at async GitHub.openPR (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:61570:20)
2022-06-03T21:35:12.9505180Z at async Go.openPR (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:63386:20)
2022-06-03T21:35:12.9506184Z at async Go._run (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:63238:32) {
2022-06-03T21:35:12.9506580Z status: 403,
2022-06-03T21:35:12.9506792Z response: {
2022-06-03T21:35:12.9507219Z url: 'https://api.github.com/repos/g2a-com/klio/git/refs',
2022-06-03T21:35:12.9507528Z status: 403,
2022-06-03T21:35:12.9507741Z headers: {
2022-06-03T21:35:12.9508089Z 'access-control-allow-origin': '',
2022-06-03T21:35:12.9509327Z 'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset',
2022-06-03T21:35:12.9510229Z connection: 'close',
2022-06-03T21:35:12.9510554Z 'content-encoding': 'gzip',
2022-06-03T21:35:12.9510969Z 'content-security-policy': "default-src 'none'",
2022-06-03T21:35:12.9511436Z 'content-type': 'application/json; charset=utf-8',
2022-06-03T21:35:12.9512120Z date: 'Fri, 03 Jun 2022 21:35:12 GMT',
2022-06-03T21:35:12.9512653Z 'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin',
2022-06-03T21:35:12.9513107Z server: 'GitHub.com',
2022-06-03T21:35:12.9513589Z 'strict-transport-security': 'max-age=31536000; includeSubdomains; preload',
2022-06-03T21:35:12.9514042Z 'transfer-encoding': 'chunked',
2022-06-03T21:35:12.9514476Z vary: 'Accept-Encoding, Accept, X-Requested-With',
2022-06-03T21:35:12.9514884Z 'x-content-type-options': 'nosniff',
2022-06-03T21:35:12.9515252Z 'x-frame-options': 'deny',
2022-06-03T21:35:12.9515665Z 'x-github-media-type': 'github.v3; format=json',
2022-06-03T21:35:12.9516127Z 'x-github-request-id': '07C2:6D13:93B9AD:1176D79:629A7E90',
2022-06-03T21:35:12.9516521Z 'x-ratelimit-limit': '1000',
2022-06-03T21:35:12.9516899Z 'x-ratelimit-remaining': '985',
2022-06-03T21:35:12.9517273Z 'x-ratelimit-reset': '1654295702',
2022-06-03T21:35:12.9517622Z 'x-ratelimit-resource': 'core',
2022-06-03T21:35:12.9517990Z 'x-ratelimit-used': '15',
2022-06-03T21:35:12.9518326Z 'x-xss-protection': '0'
2022-06-03T21:35:12.9518553Z },
2022-06-03T21:35:12.9518760Z data: {
2022-06-03T21:35:12.9519143Z message: 'Resource not accessible by integration',
2022-06-03T21:35:12.9519683Z documentation_url: 'https://docs.github.com/rest/reference/git#create-a-reference'
2022-06-03T21:35:12.9520192Z }
2022-06-03T21:35:12.9520389Z },
2022-06-03T21:35:12.9520578Z request: {
2022-06-03T21:35:12.9520864Z method: 'POST',
2022-06-03T21:35:12.9521275Z url: 'https://api.github.com/repos/g2a-com/klio/git/refs',
2022-06-03T21:35:12.9521577Z headers: {
2022-06-03T21:35:12.9521946Z accept: 'application/vnd.github.v3+json',
2022-06-03T21:35:12.9522482Z 'user-agent': 'octokit-rest.js/18.12.0 octokit-core.js/3.5.1 Node.js/12.22.7 (linux; x64)',
2022-06-03T21:35:12.9522938Z authorization: 'token [REDACTED]',
2022-06-03T21:35:12.9523357Z 'content-type': 'application/json; charset=utf-8'
2022-06-03T21:35:12.9523652Z },
2022-06-03T21:35:12.9524159Z body: '{"ref":"refs/heads/release-v1.0.1","sha":"c7c642369d87ca81f6af5b920c71161cbcc54ab8"}',
2022-06-03T21:35:12.9524545Z request: { hook: [Function: bound bound register] }
2022-06-03T21:35:12.9524827Z }
2022-06-03T21:35:12.9525026Z }
2022-06-03T21:35:21.5893478Z ✔ Successfully found branch HEAD sha "c7c642369d87ca81f6af5b920c71161cbcc54ab8".
2022-06-03T21:35:21.8354511Z ✖ Error when creating branch
2022-06-03T21:35:21.8370512Z ✖ RequestError [HttpError]: Error creating Pull Request: Resource not accessible by integration
2022-06-03T21:35:21.8371159Z at /home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:9981:21
2022-06-03T21:35:21.8371577Z at processTicksAndRejections (internal/process/task_queues.js:97:5)
2022-06-03T21:35:21.8372556Z at async createBranch (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:11767:26)
2022-06-03T21:35:21.8373203Z at async Object.branch (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:11795:9)
2022-06-03T21:35:21.8373841Z at async retry.retries (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:12469:48)
2022-06-03T21:35:21.8374517Z at async Object.createPullRequest (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:12469:24)
2022-06-03T21:35:21.8375167Z at async /home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:60463:30
2022-06-03T21:35:21.8375793Z at async GitHub.openPR (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:61570:20)
2022-06-03T21:35:21.8376407Z at async Go.openPR (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:63386:20)
2022-06-03T21:35:21.8377091Z at async Go._run (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:63238:32) {
2022-06-03T21:35:21.8377430Z status: 403,
2022-06-03T21:35:21.8377630Z response: {
2022-06-03T21:35:21.8377999Z url: 'https://api.github.com/repos/g2a-com/klio/git/refs',
2022-06-03T21:35:21.8378278Z status: 403,
2022-06-03T21:35:21.8378480Z headers: {
2022-06-03T21:35:21.8378774Z 'access-control-allow-origin': '',
2022-06-03T21:35:21.8379088Z ✔ Retry attempt #3...
2022-06-03T21:35:21.8380352Z 'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset',
2022-06-03T21:35:21.8381231Z connection: 'close',
2022-06-03T21:35:21.8381604Z 'content-encoding': 'gzip',
2022-06-03T21:35:21.8382058Z 'content-security-policy': "default-src 'none'",
2022-06-03T21:35:21.8382546Z 'content-type': 'application/json; charset=utf-8',
2022-06-03T21:35:21.8383018Z date: 'Fri, 03 Jun 2022 21:35:21 GMT',
2022-06-03T21:35:21.8383548Z 'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin',
2022-06-03T21:35:21.8384026Z server: 'GitHub.com',
2022-06-03T21:35:21.8384526Z 'strict-transport-security': 'max-age=31536000; includeSubdomains; preload',
2022-06-03T21:35:21.8385170Z 'transfer-encoding': 'chunked',
2022-06-03T21:35:21.8385616Z vary: 'Accept-Encoding, Accept, X-Requested-With',
2022-06-03T21:35:21.8386075Z 'x-content-type-options': 'nosniff',
2022-06-03T21:35:21.8386474Z 'x-frame-options': 'deny',
2022-06-03T21:35:21.8386913Z 'x-github-media-type': 'github.v3; format=json',
2022-06-03T21:35:21.8387385Z 'x-github-request-id': '07C2:6D13:93BC60:11773A1:629A7E99',
2022-06-03T21:35:21.8387802Z 'x-ratelimit-limit': '1000',
2022-06-03T21:35:21.8388197Z 'x-ratelimit-remaining': '982',
2022-06-03T21:35:21.8388588Z 'x-ratelimit-reset': '1654295702',
2022-06-03T21:35:21.8389003Z 'x-ratelimit-resource': 'core',
2022-06-03T21:35:21.8389392Z 'x-ratelimit-used': '18',
2022-06-03T21:35:21.8389764Z 'x-xss-protection': '0'
2022-06-03T21:35:21.8390041Z },
2022-06-03T21:35:21.8390243Z data: {
2022-06-03T21:35:21.8390577Z message: 'Resource not accessible by integration',
2022-06-03T21:35:21.8391138Z documentation_url: 'https://docs.github.com/rest/reference/git#create-a-reference'
2022-06-03T21:35:21.8391509Z }
2022-06-03T21:35:21.8391929Z },
2022-06-03T21:35:21.8392136Z request: {
2022-06-03T21:35:21.8392449Z method: 'POST',
2022-06-03T21:35:21.8392897Z url: 'https://api.github.com/repos/g2a-com/klio/git/refs',
2022-06-03T21:35:21.8393249Z headers: {
2022-06-03T21:35:21.8393647Z accept: 'application/vnd.github.v3+json',
2022-06-03T21:35:21.8394329Z 'user-agent': 'octokit-rest.js/18.12.0 octokit-core.js/3.5.1 Node.js/12.22.7 (linux; x64)',
2022-06-03T21:35:21.8394817Z authorization: 'token [REDACTED]',
2022-06-03T21:35:21.8395275Z 'content-type': 'application/json; charset=utf-8'
2022-06-03T21:35:21.8395597Z },
2022-06-03T21:35:21.8396582Z body: '{"ref":"refs/heads/release-v1.0.1","sha":"c7c642369d87ca81f6af5b920c71161cbcc54ab8"}',
2022-06-03T21:35:21.8397027Z request: { hook: [Function: bound bound register] }
2022-06-03T21:35:21.8397356Z }
2022-06-03T21:35:21.8397531Z }
2022-06-03T21:35:46.1591378Z ✔ Successfully found branch HEAD sha "c7c642369d87ca81f6af5b920c71161cbcc54ab8".
2022-06-03T21:35:46.4098179Z ✖ Error when creating branch
2022-06-03T21:35:46.4109582Z ✖ RequestError [HttpError]: Error creating Pull Request: Resource not accessible by integration
2022-06-03T21:35:46.4110060Z ✔ Retry attempt #4...
2022-06-03T21:35:46.4111379Z at /home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:9981:21
2022-06-03T21:35:46.4112304Z at processTicksAndRejections (internal/process/task_queues.js:97:5)
2022-06-03T21:35:46.4113015Z at async createBranch (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:11767:26)
2022-06-03T21:35:46.4113744Z at async Object.branch (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:11795:9)
2022-06-03T21:35:46.4114498Z at async retry.retries (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:12469:48)
2022-06-03T21:35:46.4115297Z at async Object.createPullRequest (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:12469:24)
2022-06-03T21:35:46.4116039Z at async /home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:60463:30
2022-06-03T21:35:46.4116732Z at async GitHub.openPR (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:61570:20)
2022-06-03T21:35:46.4117478Z at async Go.openPR (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:63386:20)
2022-06-03T21:35:46.4118181Z at async Go._run (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:63238:32) {
2022-06-03T21:35:46.4118571Z status: 403,
2022-06-03T21:35:46.4118787Z response: {
2022-06-03T21:35:46.4119270Z url: 'https://api.github.com/repos/g2a-com/klio/git/refs',
2022-06-03T21:35:46.4119961Z status: 403,
2022-06-03T21:35:46.4120180Z headers: {
2022-06-03T21:35:46.4120564Z 'access-control-allow-origin': '',
2022-06-03T21:35:46.4121813Z 'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset',
2022-06-03T21:35:46.4122732Z connection: 'close',
2022-06-03T21:35:46.4123222Z 'content-encoding': 'gzip',
2022-06-03T21:35:46.4123661Z 'content-security-policy': "default-src 'none'",
2022-06-03T21:35:46.4124134Z 'content-type': 'application/json; charset=utf-8',
2022-06-03T21:35:46.4124530Z date: 'Fri, 03 Jun 2022 21:35:46 GMT',
2022-06-03T21:35:46.4125071Z 'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin',
2022-06-03T21:35:46.4125531Z server: 'GitHub.com',
2022-06-03T21:35:46.4126007Z 'strict-transport-security': 'max-age=31536000; includeSubdomains; preload',
2022-06-03T21:35:46.4126636Z 'transfer-encoding': 'chunked',
2022-06-03T21:35:46.4127073Z vary: 'Accept-Encoding, Accept, X-Requested-With',
2022-06-03T21:35:46.4127509Z 'x-content-type-options': 'nosniff',
2022-06-03T21:35:46.4127867Z 'x-frame-options': 'deny',
2022-06-03T21:35:46.4128280Z 'x-github-media-type': 'github.v3; format=json',
2022-06-03T21:35:46.4128916Z 'x-github-request-id': '07C2:6D14:68CDE9:1365A6A:629A7EB2',
2022-06-03T21:35:46.4129296Z 'x-ratelimit-limit': '1000',
2022-06-03T21:35:46.4129674Z 'x-ratelimit-remaining': '979',
2022-06-03T21:35:46.4130067Z 'x-ratelimit-reset': '1654295702',
2022-06-03T21:35:46.4130438Z 'x-ratelimit-resource': 'core',
2022-06-03T21:35:46.4130799Z 'x-ratelimit-used': '21',
2022-06-03T21:35:46.4131134Z 'x-xss-protection': '0'
2022-06-03T21:35:46.4131364Z },
2022-06-03T21:35:46.4131578Z data: {
2022-06-03T21:35:46.4131961Z message: 'Resource not accessible by integration',
2022-06-03T21:35:46.4132497Z documentation_url: 'https://docs.github.com/rest/reference/git#create-a-reference'
2022-06-03T21:35:46.4132847Z }
2022-06-03T21:35:46.4133054Z },
2022-06-03T21:35:46.4133254Z request: {
2022-06-03T21:35:46.4133585Z method: 'POST',
2022-06-03T21:35:46.4134016Z url: 'https://api.github.com/repos/g2a-com/klio/git/refs',
2022-06-03T21:35:46.4134337Z headers: {
2022-06-03T21:35:46.4134686Z accept: 'application/vnd.github.v3+json',
2022-06-03T21:35:46.4135229Z 'user-agent': 'octokit-rest.js/18.12.0 octokit-core.js/3.5.1 Node.js/12.22.7 (linux; x64)',
2022-06-03T21:35:46.4135690Z authorization: 'token [REDACTED]',
2022-06-03T21:35:46.4136114Z 'content-type': 'application/json; charset=utf-8'
2022-06-03T21:35:46.4136394Z },
2022-06-03T21:35:46.4136876Z body: '{"ref":"refs/heads/release-v1.0.1","sha":"c7c642369d87ca81f6af5b920c71161cbcc54ab8"}',
2022-06-03T21:35:46.4137270Z request: { hook: [Function: bound bound register] }
2022-06-03T21:35:46.4137537Z }
2022-06-03T21:35:46.4137735Z }
2022-06-03T21:36:55.3224531Z ✔ Successfully found branch HEAD sha "c7c642369d87ca81f6af5b920c71161cbcc54ab8".
2022-06-03T21:36:55.7141702Z ✖ Error when creating branch
2022-06-03T21:36:55.7155329Z ✖ RequestError [HttpError]: Error creating Pull Request: Resource not accessible by integration
2022-06-03T21:36:55.7156110Z at /home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:9981:21
2022-06-03T21:36:55.7156643Z at processTicksAndRejections (internal/process/task_queues.js:97:5)
2022-06-03T21:36:55.7157322Z at async createBranch (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:11767:26)
2022-06-03T21:36:55.7158086Z at async Object.branch (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:11795:9)
2022-06-03T21:36:55.7159205Z at async retry.retries (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:12469:48)
2022-06-03T21:36:55.7159981Z at async Object.createPullRequest (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:12469:24)
2022-06-03T21:36:55.7160715Z at async /home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:60463:30
2022-06-03T21:36:55.7161412Z at async GitHub.openPR (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:61570:20)
2022-06-03T21:36:55.7162132Z at async Go.openPR (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:63386:20)
2022-06-03T21:36:55.7162837Z at async Go._run (/home/runner/work/_actions/GoogleCloudPlatform/release-please-action/v2/dist/index.js:63238:32) {
2022-06-03T21:36:55.7163226Z status: 403,
2022-06-03T21:36:55.7163451Z response: {
2022-06-03T21:36:55.7163880Z url: 'https://api.github.com/repos/g2a-com/klio/git/refs',
2022-06-03T21:36:55.7164190Z status: 403,
2022-06-03T21:36:55.7164400Z headers: {
2022-06-03T21:36:55.7164761Z 'access-control-allow-origin': '*',
2022-06-03T21:36:55.7165996Z 'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset',
2022-06-03T21:36:55.7167037Z connection: 'close',
2022-06-03T21:36:55.7167384Z 'content-encoding': 'gzip',
2022-06-03T21:36:55.7167815Z 'content-security-policy': "default-src 'none'",
2022-06-03T21:36:55.7168270Z 'content-type': 'application/json; charset=utf-8',
2022-06-03T21:36:55.7168659Z date: 'Fri, 03 Jun 2022 21:36:55 GMT',
2022-06-03T21:36:55.7168983Z ✔ Retry attempt #5...
2022-06-03T21:36:55.7169537Z 'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin',
2022-06-03T21:36:55.7169994Z server: 'GitHub.com',
2022-06-03T21:36:55.7170463Z 'strict-transport-security': 'max-age=31536000; includeSubdomains; preload',
2022-06-03T21:36:55.7170916Z 'transfer-encoding': 'chunked',
2022-06-03T21:36:55.7171339Z vary: 'Accept-Encoding, Accept, X-Requested-With',
2022-06-03T21:36:55.7171746Z 'x-content-type-options': 'nosniff',
2022-06-03T21:36:55.7172112Z 'x-frame-options': 'deny',
2022-06-03T21:36:55.7172516Z 'x-github-media-type': 'github.v3; format=json',
2022-06-03T21:36:55.7172970Z 'x-github-request-id': '07C2:4973:1822F47:359C6BD:629A7EF7',
2022-06-03T21:36:55.7173352Z 'x-ratelimit-limit': '1000',
2022-06-03T21:36:55.7173718Z 'x-ratelimit-remaining': '976',
2022-06-03T21:36:55.7174097Z 'x-ratelimit-reset': '1654295702',
2022-06-03T21:36:55.7174439Z 'x-ratelimit-resource': 'core',
2022-06-03T21:36:55.7174791Z 'x-ratelimit-used': '24',
2022-06-03T21:36:55.7175130Z 'x-xss-protection': '0'
2022-06-03T21:36:55.7175361Z },
2022-06-03T21:36:55.7175565Z data: {
2022-06-03T21:36:55.7175942Z message: 'Resource not accessible by integration',
2022-06-03T21:36:55.7176487Z documentation_url: 'https://docs.github.com/rest/reference/git#create-a-reference'
2022-06-03T21:36:55.7176832Z }
2022-06-03T21:36:55.7177025Z },
2022-06-03T21:36:55.7177214Z request: {
2022-06-03T21:36:55.7177495Z method: 'POST',
2022-06-03T21:36:55.7177901Z url: 'https://api.github.com/repos/g2a-com/klio/git/refs',
2022-06-03T21:36:55.7178191Z headers: {
2022-06-03T21:36:55.7178563Z accept: 'application/vnd.github.v3+json',
2022-06-03T21:36:55.7179102Z 'user-agent': 'octokit-rest.js/18.12.0 octokit-core.js/3.5.1 Node.js/12.22.7 (linux; x64)',
2022-06-03T21:36:55.7179531Z authorization: 'token [REDACTED]',
2022-06-03T21:36:55.7179941Z 'content-type': 'application/json; charset=utf-8'
2022-06-03T21:36:55.7180328Z },
2022-06-03T21:36:55.7180794Z body: '{"ref":"refs/heads/release-v1.0.1","sha":"c7c642369d87ca81f6af5b920c71161cbcc54ab8"}',
2022-06-03T21:36:55.7181196Z request: { hook: [Function: bound bound register] }
2022-06-03T21:36:55.7181468Z }
2022-06-03T21:36:55.7181927Z }
2022-06-03T21:40:11.3757245Z ✔ Successfully found branch HEAD sha "c7c642369d87ca81f6af5b920c71161cbcc54ab8".
2022-06-03T21:40:11.6689032Z ✖ Error when creating branch
2022-06-03T21:40:11.6740075Z ##[error]release-please failed: Error creating Pull Request: Resource not accessible by integration
Currently kilo uses g2a.yaml
file to store information about project's dependencies. Needlessly to say, this name has to change. There are two solutions for this issue:
cli.yaml
, or cli-dependencies.yaml
;klio.yaml
, but allow customising it (#1), so custom versions of the CLI could use different names.Personally I prefer first option, since former one breaks compatibility between branded variants of the CLI.
When klio runs a command it checks for its updates in the background. Since this operation can slow down command execution, we should cache its result for some time (let's say 24 hours).
Version v2 of Klio required "apiVersion" field in all its config files. Since this field was neither used nor well specified, I've removed it while implementing multiple registries support. That isn't changing the fact that having apiVersion field could be very useful, but it has to be thought through, not only copy-pasted from k8s.
Currently, I see three use cases for having such a field:
Let's discuss each point separately.
This use case applies mainly to a "manifest.yaml" file. Klio provides various helpers to make creating commands easier. If some command uses, for example, JSON output to print logs, it will not work correctly with a version which doesn't support this feature.
We could use apiVersion to specify which version of Klio's API is required to run a command correctly. It would require using some variation of semantic versioning.
Examples in other projects:
Managing unknown properties could be tricky when it comes to ensuring forward-compatibility. Forbidding them breaks compatibility with future versions, but allowing them could also be harmful since it enables to using some 3rd-party extensions to the file format. This unknown fields could potentially be incompatible with some future additions to file structure.
ApiVersion field can be used to circumvent this issue. When a particular version is known to Klio, it can deny using file if it has unknown properties. If a version is higher than currently supported one, Klio can simply ignore them, assuming that there is some newer version of Klio which supports them. For example, let's assume that Klio supports following apiVersions: 1.0, 1.1, 1.2:
This use case doesn't affect Klio itself, since when Klio discovers paths, it is using a file's name, not its content. But it can help 3rd party tools (like CI pipelines) to check if the project is using Klio. For this to work, a version has to be prefixed, in a similar manner to k8s or skaffold apiVersion fields.
Examples in other projects:
We need to establish not only why also how versions should work.
The field doesn't have to be named apiVersion, neither we have to use a single field to describe version.
Field name | Good for | Notes |
---|---|---|
version | API compatibility File format |
It's confusing, since there are also command versions, which are not described by this field. |
apiVersion | API compatibility | This name is used by k8s and a few other projects. |
configVersion | File format |
I'm going to update this table if some new ideas came out.
Generally, versions should follow semantic versioning, but we can use a different number of segments:
Additionally, a version can be prefixed with some kind of "namespace" (like "skaffold/v2").
Looking at our use cases, it would be best to use versions with two semver segments (e.g. "1.2"). If we want to address the 3rd use case (files discovery), versions have to be prefixed (e.g. "klio/1.2").
If we are going to use prefixes, it's worth to mention that they cannot be subject to branding, since it would break compatibility with public registries and commands.
Since Klio API is going to change more often than files formats, "klio.yaml" and "registry.yaml" should be versioned separately from "manifest.yaml".
We definitely need to include apiVersion in "manifest.yaml". I'm not sure about other files. Adding version to them increases the complexity and size of a boilerplate, but there aren't significant gains.
Please let me know what do you think about it.
Problem:
All dependency checksums located in klio.yaml are static in project context but binaries differ depending on user platform.
It causes this error:
klio/internal/dependency/manager.go
Line 150 in 5eadf52
Expect:
g2a get
without any checksum issues.klio get
on such a klio.yaml
:defaultRegistry: https://example/registry.yaml
dependencies:
build:
version: 1.6.0
deploy:
version: 0.12.0
scripts:
version: 0.5.0
Reformats it into:
defaultRegistry: ""
dependencies:
build:
registry: https://example/registry.yaml
version: 1.6.0
deploy:
registry: https://example/registry.yaml
version: 0.12.0
scripts:
registry: https://example/registry.yaml
version: 0.5.0
klio get command
without --from
flag ends up with an error:Failed to install command@*: Get "": unsupported protocol scheme ""
Attempting to fix these issues like this seems to fix them however after it, running klio get build
on such a klio.yaml
:
defaultRegistry: https://example/registry.yaml
dependencies:
build:
registry: https://example-nightly/registry.yaml
version: 1.7.2
deploy:
version: 0.12.0
scripts:
version: 0.5.0
it gets reformatted to
defaultRegistry: https://example/registry.yaml
dependencies:
build:
version: 1.7.2
deploy:
version: 0.12.0
scripts:
version: 0.5.0
and build gets downloaded from the default registry instead of the specified one
Currently when user tries to install command locally but klio.yaml cannot be found, klio displays following message:
$ klio get deploy
[FATA] Packages can be installed locally only under project directory, use "--global" option
Which is not entirely helpful, because it doesn't inform how to make a "project directory". It would be nice to have some helper for creating klio.yaml file. Ideally it would be a separate command similar to npm init
or go mod init
, but since we shouldn't introduce to many builtin commands, I think simply adding --init-project
option to klio get
is good enough. Adding such option would result in creating klio.yaml file in the current directory (if it doesn't already exist).
Currently get command validates its parameters rather loosely. We should add at least following checks:
/^[a-z0-9_-]+$/
?`)Line 27 in d5d7afc
Create CI/CD setup for klio core, which will
klio
nightly and release builds using github actionCurrently, we can install only commands, but since some commands also need to be extendable, we need to provide some plugins mechanism.
For a start, let's look at how commands work. Each command contains an executable and some metadata in the manifest.yaml file. Klio can interpret this metadata to list commands in help message and run executable when a command is used. Commands have names, but since they are not unique across multiple registries, the user can change them during installation.
Plugins are different in two key aspects:
Besides these two differences, plugins should work similarly to commands. They should be installed with "get" command and included as dependencies in a klio.yaml file.
Commands need some way for listing compatible plugins. We cannot rely on using commands names for it, because:
That's why we need a separate identifier to discover plugins for commands - a namespace. To limit potential name conflicts, namespaces have a form of the domain name.
To make using plugins simpler, a namespace should always be specified as a prefix of a plugin name (not as a separate field). For example plugin named "helm" in a namespace "deploy.ci.klio.sh" should have a full name: "deploy.ci.klio.sh/helm". A plugin can be renamed during installation as long as the namespace part remains unchanged.
Format of registry.yaml, klio.yaml and dependencies.json should not change. The only difference is a name (which in case of the plugins includes namespace).
Manifest.yaml should have a separate kind (Plugin), and shouldn't include any properties except kind
and apiVersion
. Optionally, we could let to include some metadata specific for a plugin, but in my opinion, it would be better to store such metadata in a separate file.
Plugins should be installed similarly to commands; the only difference is a namespace in the name:
klio get plugin.namespace.org/plugin-name
Plugins can be aliased, but klio should print and error when the user tries to change a namespace:
klio get plugin.namespace.org/plugin-name --as plugin.namespace.org/plugin-name # OK
klio get plugin.namespace.org/plugin-name --as different.namespace.org/plugin-name # Error
We need to provide some way for listing plugins. I propose to implement a single "sdk" command, which would group all tools dedicated to being used by the commands:
klio sdk list-plugins --namespace deploy.ci.klio.sh
Option -v
is currently working only when specified directly after g2a
command. Since usually -v
parameter is added when users try to run command again in order to debug why it failed, it's really convieniet to add it on the very end of the line. The problem is, when -v
is specified after name of subcommand, we cannot reliably parse it and remove it from parameters passed down to sub-command. To illustrate the issue, take a look for these examples:
g2a cmd -v
– is -v
verbosity parameter or some other parameter used by cmd
command?g2a cmd -vv
– is -vvv
a -v
parameter specified 2 times, or -v
parameter with v
value?g2a cmd -xv
– is -xv
two parameters, or single -x
parameter with v
value?g2a cmd --param -v
– is -v
a parameter or a value of --param
parameter?It's impossible to mitigate all these issues without knowing exact structure of the sub-command's parameters, but we can try to reduce their impact by applying following rules:
-v
is specified after command name, pass it with the rest of parameters to this command (do not intercept it).-vv
and --verbose
, paramenters like -xv
have to be ignored.--log-level
) shouldn't be changed (they should be parsed only if specified before command name).Since it will cause errors on commands wich doesn't accept unknown parameters, this change must apply only to commands using API newer than "g2a-cli/v1beta1".
Problem:
After building and running klio from develop branch it returns with exit code 1 and no logs whatsoever.
Adding klio.yaml
into the project folder allows klio to start and install commands locally however it fails when trying to install commands globally, again with no logs.
How To Reproduce:
go build cmd/klio/klio.go
./klio
- you will see no error logs, the exit code is 1
, adding any flags like --help
does not change anythingklio.yaml
into the project folder (even an empty yaml is fine for reproducing purposes)./klio getCommand hello --from https://raw.githubusercontent.com/g2a-com/klio-example-command/main/registry.yaml -g
again fails with no logs and exit code 1
Currently it is necessary to use an 3rd party tool together with klio due to internalize logger:
import (
"github.com/g2a-com/klio/pkg/cli"
log "github.com/kataras/golog"
)
func main() {
cmd := cli.CLI{
CommandName: "my-command",
Version: "0.0.1",
DefaultRegistry: "https://some.registry.com/registry.yaml",
}
log.Warn("I'm warning you!")
Instead, it would be much better to align log formatting with klio:
import (
"github.com/g2a-com/klio/pkg/cli"
"github.com/g2a-com/klio/pkg/log"
)
func main() {
cmd := cli.CLI{
CommandName: "my-command",
Version: "0.0.1",
DefaultRegistry: "https://some.registry.com/registry.yaml",
}
log.Warn("I'm warning you!")
To do that, part of the internal package log
must be extracted to external package.
User should have an opportunity to remove a global command from Klio. This is especially important for aliased commands, which may be used for testing (eg. nightly versions). User should be able to do something like:
klio remove command-alias -g
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.