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

#9 | + STDIN support for print command | #patch #10

Merged
merged 4 commits into from
Nov 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
111 changes: 105 additions & 6 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,118 @@ jobs:
features: --features "backend+ui" --no-default-features
steps:
- uses: actions/checkout@v1
- name: Install tools
- name: install tools
run: sudo apt-get install build-essential libncurses5-dev libncursesw5-dev
- name: Check formatting
- name: check formatting
run: cargo fmt --all -- --check
- name: Check README.md synchronization
- name: check README.md synchronization
run: |
cargo install --force cargo-sync-readme
cargo sync-readme -c
- name: Scan code
- name: scan code
run: |
rustup component add clippy
cargo clippy --all-targets ${{ matrix.features }} -- -D warnings
- name: Execute tests
- name: execute unit tests
run: cargo test ${{ matrix.features }}
- name: Build program
- name: build program
run: cargo build ${{ matrix.features }}
<<<<<<< HEAD
=======

tag:
if: github.ref == 'refs/heads/master'
needs: check
name: tag and release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: tag
id: tag
uses: anothrNick/github-tag-action@1.19.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WITH_V: false
RELEASE_BRANCHES: master
DEFAULT_BUMP: patch
- name: create release
id: create_release
uses: actions/create-release@latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.tag.outputs.new_tag}}
release_name: ${{ steps.tag.outputs.new_tag }}
body: |
Release ${{ steps.tag.outputs.new_tag }}.
draft: false
prerelease: false
- run: printf ${{ steps.create_release.outputs.upload_url }} > ${{ env.RELEASE_FILE }}
- name: upload release data
uses: actions/upload-artifact@v1.0.0
with:
name: RELEASE
path: ${{ env.RELEASE_FILE }}

publish-cratesio:
needs: tag
name: crates.io
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: get version
id: get_version
run: echo ::set-output name=VERSION::$(git tag --points-at HEAD --sort -version:refname | head -1)
- name: install tools
run: sudo apt-get install build-essential libncurses5-dev libncursesw5-dev
- name: publish
id: publish
run: |
VERSION=${{ steps.get_version.outputs.VERSION }} make update-version &&
cargo login ${{ secrets.CRATES_IO_TOKEN }} &&
cargo publish --allow-dirty

publish:
needs: tag
name: publish for ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: macos-latest
target: x86_64-apple-darwin
install: printf ok
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
install: sudo apt-get install build-essential libncurses5-dev libncursesw5-dev
steps:
- uses: actions/checkout@v1
- name: get version
id: get_version
run: echo ::set-output name=VERSION::$(git tag --points-at HEAD --sort -version:refname | head -1)
- name: download release id
uses: actions/download-artifact@v1.0.0
with:
name: RELEASE
- name: get release data
id: get_release_data
run: echo ::set-output name=upload_url::$(cat RELEASE/${{ env.RELEASE_FILE }})
- name: install tools
run: |
${{ matrix.install }} &&
rustup target install ${{ matrix.target }}
- name: build-${{ matrix.target }}
run: |
VERSION=${{ steps.get_version.outputs.VERSION }} make update-version &&
cargo build --release --target ${{ matrix.target }}
- name: zip
run: cd ./target/${{ matrix.target }}/release && tar -zcvf ${{ matrix.target }}.tar.gz complate
- name: upload asset
uses: svenstaro/upload-release-action@v1-release
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ./target/${{ matrix.target }}/release/${{ matrix.target }}.tar.gz
asset_name: ${{ matrix.target }}.tar.gz
tag: ${{ steps.get_version.outputs.VERSION }}
overwrite: true
>>>>>>> 88d6d53 (#9 small changes to pipeline)
3 changes: 2 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
}
},
"args": [
"--shell-trust", "prompt"
"print",
"--shell-trust", "prompt",
],
"cwd": "${workspaceFolder}"
},
Expand Down
39 changes: 12 additions & 27 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ async-trait = "0.1.24"
clap = "2.33.0"
handlebars = "3.0.1"

dialoguer = { version = "0.5.0", optional = true }
dialoguer = { version = "0.7.1", optional = true }
cursive = { version = "0.11.2", optional = true }
fui = { version = "1.0", optional = true }

Expand Down
3 changes: 2 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ Either one of the `backend+` flags (or both) MUST be enabled for `complate` to w

|Name|Short|Long|Description|Remark|Status|
|-- |-- |-- |-- |-- |--|
|Config via file path|-c|--config|The path to the configuration file that shall be used. This path can be relative or absolute. The default path is `./.complate/config.yml`.|Can not be used in conjunction with the `pipe` argument.|stable|
|Config via STDIN pipe|-||The indicator that the config get's passed to the program via STDIN pipe.|Can not be used in conjunction with the `config` argument. Only works with UI backend right now (see: mitsuhiko/dialoguer#93).|experimental|
|Config via file path|-c|--config|The path to the configuration file that shall be used. This path can be relative or absolute. The default path is `./complate/config.yml`.|Can not be used in conjunction with the `pipe` argument.|stable|
|Shell trust||--shell-trust|Enables the shell value provider for replacing template placeholders. Due to the potential security risk with this option, it is disabled by default. Possible values for this option are `none` (default), `prompt` and `ultimate`||stable|
|Backend|-b|--backend|Defines the backend for the user interaction.||`CLI` is stable. `UI` is experimental (feature = "backend+ui").

Expand Down
10 changes: 10 additions & 0 deletions docs/adrs/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Summary

Architecture

- [ADR 1: Usage of ADRs](./adrs/1.md)
- [ADR 2: Usage of key words](./adrs/2.md)
- [ADR 3: Versioning](./adrs/3.md)
- [ADR 4: Experimental flag](./adrs/4.md)
- [ADR 5: Usage of feature flags](./adrs/5.md)
- [ADR 6: Print command supporting STDIN pipe](./adrs/6.md)
3 changes: 2 additions & 1 deletion docs/wiki/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
- [ADR 3: Versioning](./adrs/3.md)
- [ADR 4: Experimental flag](./adrs/4.md)
- [ADR 5: Usage of feature flags](./adrs/5.md)
- [ADR 6: Usage of shell scripts instead of Makefiles](./adrs/6.md)
- [ADR 6: Print command supporting STDIN pipe](./adrs/6.md)
- [ADR 7: Usage of shell scripts instead of Makefiles](./adrs/7.md)
8 changes: 5 additions & 3 deletions docs/wiki/src/adrs/6.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# ADR 6: Usage of shell scripts instead of Makefiles
# ADR 6: Print command supporting STDIN pipe

## Summary

Originally, this project had a Makefile in order to do the build steps and such. Since Makefile still is kind of an alien syntax and has some disadvantages against standard plain shell scripts (bash scripts), I decided to replace the Makefile with a shell script (`./do.sh`).\
This script now contains the important commands like generating coverage reports and initializing the repository.
The print command MUST support piping the configuration into it via STDIN as alternative to the file based approach.\
The indicator for the pipe being used SHALL be the "-" character as argument to the pipe function.\
The configuration file ("-c", "--config") argument MUST NOT be compatible with the pipe argument. Either none, or exactly one of them MAY be explicitly specified at the same time.\
Since the config file argument has a default value, the pipe command overrides that so that the program behaves as if there was no configuration file specified at all.

## Authors

Expand Down
11 changes: 11 additions & 0 deletions docs/wiki/src/adrs/7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ADR 7: Usage of shell scripts instead of Makefiles

## Summary

Originally, this project had a Makefile in order to do the build steps and such. Since Makefile still is kind of an alien syntax and has some disadvantages against standard plain shell scripts (bash scripts), I decided to replace the Makefile with a shell script (`./do.sh`).\
This script now contains the important commands like generating coverage reports and initializing the repository.

## Authors

* Heiko Alexander Weber\
[haw@voidpointergroup.com](mailto:haw@voidpointergroup.com)
54 changes: 42 additions & 12 deletions src/args/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::io::Result;
use std::io::{stdin, Read, Result};

pub struct CallArgs {
pub privileges: Privilege,
Expand All @@ -10,15 +10,18 @@ impl CallArgs {
pub async fn validate(&self) -> Result<()> {
match self.privileges {
Privilege::Normal => match &self.command {
Command::Print(args) => match args.backend {
#[cfg(feature = "backend+cli")]
Backend::CLI => Ok(()),
#[cfg(feature = "backend+ui")]
Backend::UI => Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not use backend+ui without experimental features being activated",
)),
},
Command::Print(args) => {
match args.backend {
#[cfg(feature = "backend+ui")]
Backend::UI => return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not use backend+ui without experimental features being activated",
)),
#[cfg(feature = "backend+cli")]
Backend::CLI => {}
};
Ok(())
}
_ => Ok(()),
},
Privilege::Experimental => Ok(()),
Expand Down Expand Up @@ -80,6 +83,12 @@ impl ClapArgumentLoader {
.takes_value(false))
.subcommand(clap::App::new("init"))
.subcommand(clap::App::new("print")
.arg(clap::Arg::with_name("-")
.short("-")
.help("Pipe indicates to read the config from STDIN")
.multiple(false)
.required(false)
.takes_value(false))
.arg(clap::Arg::with_name("config")
.short("c")
.long("config")
Expand Down Expand Up @@ -125,8 +134,29 @@ impl ClapArgumentLoader {

match command.subcommand_matches("print") {
Some(x) => {
let config_file = x.value_of("config").unwrap().to_owned();
let config = std::fs::read_to_string(config_file)?;
let config = if x.is_present("-") {
match privileges {
Privilege::Normal => {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not use pipe argument without experimental features being activated",
));
}
Privilege::Experimental => {}
}
let mut buffer = String::new();
let stdin = stdin();
stdin.lock().read_to_string(&mut buffer)?;
buffer
} else if x.is_present("config") {
let config_file = x.value_of("config").unwrap().to_owned();
std::fs::read_to_string(config_file)?
} else {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"configuration not specified",
));
};

let shell_trust = match x.value_of("shell-trust") {
Some(x) => match x {
Expand Down
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ async fn async_main() -> Result<()> {
Ok(())
}
crate::args::Command::Print(x) => {
std::io::stdout().write_all(crate::render::select_and_render(x).await?.as_bytes())?;
let res = crate::render::select_and_render(x).await?;
std::io::stdout().write_all(res.as_bytes())?;
Ok(())
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ mod cli {
}

async fn check(&self, prompt: &str, options: &[String]) -> Result<String> {
let indices = dialoguer::Checkboxes::new()
let indices = dialoguer::MultiSelect::new()
.with_prompt(prompt)
.items(options)
.interact()
Expand Down