Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: implement --verbose flag on ion template inspect cmd #21

Merged
merged 41 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
348dc92
feat: add ion template inspect cmd
diversable Feb 15, 2023
d142870
bump patch release
diversable Feb 15, 2023
be88ce3
fix: ion template inspect; add more tests
diversable Feb 15, 2023
24ec3df
update tests
diversable Feb 15, 2023
b4f161c
fix: inspect template implementation
diversable Feb 15, 2023
7ecda5a
reverse bump version
diversable Feb 15, 2023
f6956df
Merge branch 'Roger-luo:main' into main
diversable Feb 15, 2023
64280da
test: update template tests
diversable Feb 16, 2023
a8802fb
Merge branch 'Roger-luo:main' into main
diversable Feb 16, 2023
cf02c96
Fix test: template
diversable Feb 16, 2023
31f29f2
Merge branch 'Roger-luo:main' into main
diversable Feb 17, 2023
8c83346
feat: add --verbose flag to `ion template inspect`
diversable Feb 18, 2023
dbedb17
fix: refactor
diversable Feb 18, 2023
2f23481
Merge branch 'Roger-luo:main' into main
diversable Feb 18, 2023
a44b8a4
fix: update tmpl inspect -v --all combination
diversable Feb 18, 2023
840f6b0
Merge branch 'main' into template
diversable Feb 18, 2023
70f7ca1
fix: tests
diversable Feb 18, 2023
4b8d890
Fix: tests
diversable Feb 18, 2023
3a18aa7
Merge branch 'template' of https://github.com/diversable/Ion into tem…
diversable Feb 18, 2023
b2771fc
fix: clippy
diversable Feb 18, 2023
5ba05ca
fix: fmt
diversable Feb 18, 2023
e43a945
Update grcov.yml
diversable Feb 18, 2023
75ad65e
update readme: add link to template repo
diversable Feb 18, 2023
73ce742
Update grcov.yml
diversable Feb 18, 2023
5a913ce
Update grcov.yml
diversable Feb 18, 2023
ec6474f
update
diversable Feb 20, 2023
995583b
Merge branch 'main'
diversable Feb 20, 2023
0f1ca84
Merge branch 'main' into template
diversable Feb 20, 2023
636e44e
fix: tests
diversable Feb 20, 2023
f4e6be2
fmt
diversable Feb 20, 2023
83e4181
Merge branch 'main' into template
diversable Feb 20, 2023
4226e38
ion requested updates
diversable Feb 20, 2023
d82409d
template macro minor update..
diversable Feb 20, 2023
10ed0bb
Merge branch 'Roger-luo:main' into template
diversable Feb 20, 2023
64ec29a
Merge branch 'Roger-luo:main' into template
diversable Feb 21, 2023
bad6c7d
request: update to debug printing
diversable Feb 22, 2023
4494d14
rm comment
diversable Feb 22, 2023
bbd6a1f
remove dependence on impl Display
diversable Feb 22, 2023
653c0f6
remove impl Display stubs
diversable Feb 22, 2023
17a8b98
finish removing display
diversable Feb 22, 2023
1bedf44
cleanup
diversable Feb 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions .github/workflows/grcov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
on: [push, pull_request]
diversable marked this conversation as resolved.
Show resolved Hide resolved

name: Code coverage with grcov

jobs:
grcov:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
- macOS-latest

steps:
- uses: actions/checkout@v2

- name: Install toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
profile: minimal

- name: Execute tests
uses: actions-rs/cargo@v1
with:
command: test
args: --all
env:
CARGO_INCREMENTAL: 0
RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests"
# Problematic RUSTFLAGS: -Cpanic=abort

# Note that `actions-rs/grcov` Action can install `grcov` too,
# but can't use faster installation methods yet.
# As a temporary experiment `actions-rs/install` Action plugged in here.

# Consider **NOT** to copy that into your workflow,
# but use `actions-rs/grcov` only
# - name: Pre-installing grcov
# uses: actions-rs/[email protected]
# with:
# crate: grcov
# use-tool-cache: true

- name: Gather coverage data
id: coverage
uses: actions-rs/[email protected]
with:
coveralls-token: ${{ secrets.COVERALLS_TOKEN }}

- name: Coveralls upload
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel: true
path-to-lcov: ${{ steps.coverage.outputs.report }}

grcov_finalize:
runs-on: ubuntu-latest
needs: grcov
steps:
- name: Coveralls finalization
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel-finished: true
281 changes: 280 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,291 @@ Download tarball in the release page and extract it to your `$HOME/.julia` direc

### build from source
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it'd be nice if this can be in a separate PR, I probably will put up the website soon, so we can decide whether to have this in a different PR


Using [`just`](https://github.com/casey/just):
Using [`just`](https://github.com/casey/just) and [Rust's cargo/rustc compiler](https://rustup.rs/):

```bash
just install
```

### Overview
Everything in Ion is optimized for terminal UX, including its name - ion is the easiest-to-type name that I find not used by other popular CLI tools.

This is still at quite an early stage, but I have been using it for a month myself, so I'd like to share this tool with the community. There will be more detailed documentation and a website set up in the future.

TL;DR let me introduce what commands ion provides currently, you can find more detailed information in the help message by running ion help.

#### Installation - Details

Currently only MacOS and Linux are supported; the MacOS and Linux binaries are packed as a tarball in the release CDN. There is only one binary in the release, so just download it and put it wherever you like. Also, if anyone would like to contribute their knowledge about how to release Windows binaries, that would be appreciated!

Or you can install by building it from a source if you have a rust compiler setup locally, after cloning the repo, you can just run just install and it will install the binary to the .local/bin/ folder.

If you want to have shell auto-completion, after downloading ion, run ion completions <shell> to generate the shell completion script, e.g for oh-my-zsh you can copy and paste the following

> cd .oh-my-zsh/completions

> ion completions zsh |> _ion

In the future, if this is adopted by more people, maybe we can have juliaup ship this or have an ionup for a friendlier installation process.

#### The forwarded Pkg commands

Ion forwards Julia's Pkg commands in the terminal, e.g

> ion add

Add dependencies to current environment


Usage:
```
ion add [OPTIONS] [PACKAGE]...

Arguments:
[PACKAGE]... The package to add

Options:
-g, --global Add the package to the global environment
-h, --help Print help
```
and all Pkg commands will run as equivalent to having `julia --project -e "using Pkg; ...` by default, and there is a `-g --global` option to manage global shared environment.

#### Releasing a new version with Ion

This has been one of the most frequently used features personally in my previous Julia version, and in this new rust version, I have rewritten the whole thing in a much cleaner and modular fashion.

Have you tired of wanting to bump a patch version, but forgetting it's already bumped in main and only noticing it's a wrong patch version after the General registry complains to you after 3min? Have you been tired of opening your editor, changing the version in Project.toml manually then opening a browser to summon JuliaRegistrator but having the bot name typed wrong?

With ion release you only need one line to do all these within seconds! e.g

> ion release patch

will automatically bump a patch version based on your current version in main and your registered version. If it's not a continuous version number, ion will warn you and ask if you want to continue; if your current version number is already valid, ion will ask if you want to release that instead - and Ion will also summon JuliaRegistrator directly without asking you to open the browser.

#### Releases
Custom release pipeline with summon and bump:

We now also provide bump and summon commands to allow you to do more customization, e.g managing large mono-repo that contains many other packages or maybe you want to pack up some artifact before summon JuliaRegistrator. You can combine these two commands with [`just`](https://github.com/casey/just) (recommended) or `make`, like what I do here.


#### Run a standalone script with dependencies

This is a feature that is supported in many other languages: Single-file scripts that download their dependencies. The lack of this feature has been a gripe from users in the Julia community; Ion solves this pain point with its new script system.

You can write the following in your Julia script
```Julia
# !/usr/bin/env ion run
#=ion
Example = "0.5"
=#

using Pkg
Pkg.status()

println("hello world")
```
and ion will parse the #=ion ... block to automatically setup an environment, running this will print

> ion run script.jl
>
> Status `~/.local/bin/env/env-3506815430/Project.toml`
>
> [7876af07] Example v0.5.3
>
> hello world

You probably want to ask why this is not a Project.toml or Manifest.toml embedded inside the script like Pluto notebook. Like many other similar implementations, we want this part editable and readable since it will directly appear in your script. Thus if you can install a package with a specific version in Julia REPL by only providing the version number and name, you should be typing the same information in your script too!

We also have an alternative mode letting you specify UUID, git revision, URL, path, etc, e.g

```julia
# !/usr/bin/env ion run
#=ion
Example = {version="0.5", url="https://github.com/Roger-luo/Example.jl"}
=#

using Pkg
Pkg.status()

println("hello world")
```
On the other hand, there might be cases where we want a script to be never changed, which is something I'm thinking to have a release mode script environment specification that is similar to Pluto notebook that has a complete Manifest.toml and Project.toml inside the script.

#### A Local Environment by Default
As for normal scripts, many Julia users want `julia --project` to be the default, which is something I advocate too, and I have been using alias jp="julia --project" in my terminal for years. Though this has been a safety concern for julia compiler binary, it is not a concern for a developer tool that only runs locally. So for a script without the #=ion dependencies, ion run is equivalent to the following (and it forwards Julia compiler flags like --threads etc. if you specify it)
```
command equivalent to
ion run julia --project
ion run script.jl julia --project script.jl
```
#### Clone Julia packages

Have you gotten annoyed that cloning a Julia package using git ends up in a folder with xxxx.jl by default?

Have you been opening a browser, searching the package, copying the package git URL, then cloning the package somewhere?

Have you tried to let dev command use your own directory instead of .julia/dev ?

Have you cloned a Julia package, ready to contribute to it, but realize you need to fork it and change remote origin to remote upstream and add your own fork?

Now ion clone handles all above with just one line! if you try `ion clone Example` it will look for the registered URL and try to clone it, and because you don't seem to have access to this repo, we will ask if you want to fork it and if you say yes, we will do it for you. No opening browser is needed!

#### Create a new package with pre-defined templates

Have you ever typed the same project configuration again and again interactively with PkgTemplates?

Have you ever typed the wrong option in the interactive mode with PkgTemplates and had to start over entirely?

The `ion new` command is here to help: we create an entirely new templating system based on PkgTemplates but with serialization in TOML.

The following is a project template for a small project:

```TOML
name="project"
description = "A project description"

[readme]
[project_file]
[src_dir]
[tests]
```

and the following is a project template for research packages:

```TOML
name="research"
description = "A research package description"

[project_file]
[readme]
[src_dir]
[documenter]
[license]
[tests]
[repo]
[codecov]
[citation]
[github.ci]
arch = ["x86", "x86_64"]
os = ["ubuntu-latest", "macos-latest", "windows-latest"]

[github.tagbot]
[github.compat_helper]
```

Most importantly you can save your own custom configuration and share it with people! Maybe your company's internal packages need a custom README template and LICENSE? Create your own template.toml with corresponding components and share it with your colleagues instead of asking them to do it interactively! Check examples in our [template registry here](https://github.com/Roger-luo/ion-templates)!

#### What's next?

I'm hoping to have self-update support like juliaup in the future, but I haven't had the time to work it out, for other features. I'm also thinking about JuliaFormatter and JET integration similar to cargo fmt and cargo clippy, but I haven't decided on how integration is supported yet.

Last, please feel free to open issues on bug reports, feature requests, or contributing PRs!

### Command Quick Reference:

NB: sub-commands are indicated with bullet points and options are indicated with bullet points plus short or long flags (ie. -f or --flag).
Arguments are listed in square brackets, such as [URL]. A positional arg which is capable of handling multiple arguments is listed with ellipses following the name (eg. [EXAMPLE...]).

Optional arguments are listed with a `?` before the name; generally speaking, if required arguments are not provided, Ion will ask for them.


| Commands | Description |
| ---------------------------- | ------------------------------------------------------------ |
| new [PATH] | Create a new package |
| clone [URL] [PATH] | Clone a package from URL or registry |
| release [VERSION] [PATH] | release a new version of a package |
| bump [VERSION] [PATH] | bump the version of a package |
| summon [PATH] | summon JuliaRegistrator to register the package |
| run [PATH] | Run a script, or start a REPL if no script is given |
| script update/rm/repl [PATH] | script tools |
| add [PACKAGE...] | Add dependencies to current environment |
| remove [PACKAGE...] | Remove dependencies in the current environment [aliases: rm] |
| develop [PACKAGE] | Develop packages in the current environment [aliases: dev] |
| free [PACKAGE] | Free pinned packages in the current environment |
| gc | garbage collect packages not used for a significant time |
| precompile [PACKAGE...] | Precompile all packages in the current environment |
| status | Show the status of the current environment [aliases: st] |
| update [PACKAGE...] | Update the current environment [aliases: up] |
| why [PACKAGE] | show why a package is installed |
| template list/update/inspect | template management |
| completions [SHELL] | generate shell completion scripts |
| auth login/logout | manage Github authentication |

---

#### Command List
ion
- auth
- login
- logout
- clone [?options] [URL] [PATH]
- --registry [REGISTRY]
- release [?options] [VERSION] [PATH]
- --branch | -b [?BRANCH]
- --registry [?REGISTRY]
- --no-prompt
- --no-commit
- --no-report
- --skip-note
- summon [?options] [PATH]
- --branch | -b
- --no-prompt
- --skip-note
- bump [?options] [VERSION] [PATH]
- --branch | -b [BRANCH]
- --no-prompt
- --no-commit
- --no-report
- --registry [REGISTRY]
- new [?options] [PATH]
- --list
- --force | -f
- --no-interactive
- --template | -t [TEMPLATE]
- run [?options] [PATH]
- --sysimage | -J [PATH]
- --threads | -t [?NUMBER_OF_THREADS]
- --procs | -p [?NUMBER_OF_PROCESSES]
- --color [?OPT]
- --verbose | -v
- script
- update [?options] [PATH]
- --verbose | -v
- rm [PATH]
- repl [PATH]
- add [?options] [PACKAGE...]
- --global | -g
- develop | dev [?options] [PACKAGE]
- --global | -g
- --all
- --version | -v
- free [?options] [PACKAGE]
- --global | -g
- gc [?options]
- --global | -g
- precompile [?options] [PACKAGE...]
- --strict
- --global | -g
- remove | rm [?options] [PACKAGE...]
- --global | -g
- status | st [?options]
- --outdated
- --no-diff
- --manifest
- --global | -g
- update | up [?options] [PACKAGE...]
- --global | -g
- why [?options] [PACKAGE]
- --global | -g
- completions [SHELL]
- template
- list
- update
- inspect [?TEMPLATE_NAME]
- --all
- --verbose | -v


## License

MIT License
17 changes: 11 additions & 6 deletions src/bin/ion/commands/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ pub fn cli() -> Command {
Command::new("inspect")
.about("inspect the contents of a template")
.arg(arg!([TEMPLATE] "Selects which template to print out"))
.arg(arg!(--"all" "Inspect all installed templates")),
.arg(arg!(--"all" "Inspect all installed templates"))
.arg(arg!(verbose: -v --verbose "Inspect details of the template output")),
)
.arg_required_else_help(true)
}
Expand All @@ -43,17 +44,21 @@ pub fn exec(config: &mut Config, matches: &ArgMatches) -> CliResult {
RemoteTemplate::new(config).download()?;
}
Some(("inspect", matches)) => {
let all_flag = matches.get_flag("all");
let verbose_flag = matches.get_flag("verbose");

download_templates(config)?;
// Iff a template name is provided, inspect template; otherwise, check for --all flag; if no --all, ask user to select template from list

// Iff a template name is provided, inspect template; otherwise, check for --all flag; if no --all, ask user to select template from list
match matches.get_one::<String>("TEMPLATE") {
Some(template) => inspect_template(config, template.to_owned())?,
Some(template) => {
inspect_template(config, template.to_owned(), verbose_flag)?;
}
None => {
let all_flag = matches.get_flag("all");
if all_flag {
inspect_all_templates(config)?;
inspect_all_templates(config, verbose_flag)?;
} else {
ask_inspect_template(config)?;
ask_inspect_template(config, verbose_flag)?;
}
}
};
Expand Down
Loading