Skip to content

Commit 9da7d3f

Browse files
committed
Add some CLI tests and workflow
This commit adds - release action to release tarball for downloading - run CI on pull request Signed-off-by: bin liu <liubin0329@gmail.com>
1 parent d05e755 commit 9da7d3f

7 files changed

Lines changed: 302 additions & 14 deletions

File tree

.github/workflows/ci.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: CI
2+
on:
3+
pull_request:
4+
types:
5+
- opened
6+
- edited
7+
- reopened
8+
- synchronize
9+
10+
env:
11+
CARGO_TERM_COLOR: always
12+
RUST_TARGET: x86_64-unknown-linux-musl
13+
14+
jobs:
15+
build:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v2
19+
- name: Build and test
20+
uses: gmiam/rust-musl-action@master
21+
with:
22+
args: make all

.github/workflows/release.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
name: release
2+
3+
on:
4+
push:
5+
tags:
6+
- v[0-9]+.[0-9]+.[0-9]+*
7+
workflow_dispatch:
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
RUST_TARGET: x86_64-unknown-linux-musl
12+
REGISTRY: ghcr.io
13+
IMAGE_NAME: ${{ github.repository }}
14+
15+
jobs:
16+
build-linux:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v2
20+
- name: Build toml cli
21+
# uses: juankaram/rust-musl-action@master
22+
uses: gmiam/rust-musl-action@master
23+
with:
24+
args: cargo build --target $RUST_TARGET --release
25+
- name: store-artifacts
26+
uses: actions/upload-artifact@v2
27+
with:
28+
if-no-files-found: error
29+
name: toml-artifacts-linux
30+
path: |
31+
target/${{ env.RUST_TARGET }}/release/toml
32+
33+
prepare-tarball-linux:
34+
runs-on: ubuntu-latest
35+
needs: [build-linux]
36+
steps:
37+
- name: download artifacts
38+
uses: actions/download-artifact@v2
39+
with:
40+
name: toml-artifacts-linux
41+
path: toml-cli
42+
- name: prepare release tarball
43+
run: |
44+
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
45+
tarball="toml-cli-$tag-linux-amd64.tgz"
46+
chmod +x toml-cli/*
47+
tar cf - toml-cli | gzip > ${tarball}
48+
echo "tarball=${tarball}" >> $GITHUB_ENV
49+
50+
shasum="$tarball.sha256sum"
51+
sha256sum $tarball > $shasum
52+
echo "tarball_shasum=${shasum}" >> $GITHUB_ENV
53+
- name: store-artifacts
54+
uses: actions/upload-artifact@v2
55+
with:
56+
name: release-tarball
57+
path: |
58+
${{ env.tarball }}
59+
${{ env.tarball_shasum }}
60+
61+
create-release:
62+
runs-on: ubuntu-latest
63+
needs: [prepare-tarball-linux]
64+
steps:
65+
- name: download artifacts
66+
uses: actions/download-artifact@v2
67+
with:
68+
name: release-tarball
69+
path: tarballs
70+
- name: prepare release env
71+
run: |
72+
echo "tarballs<<EOF" >> $GITHUB_ENV
73+
for I in $(ls tarballs);do echo "tarballs/${I}" >> $GITHUB_ENV; done
74+
echo "EOF" >> $GITHUB_ENV
75+
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
76+
echo "tag=${tag}" >> $GITHUB_ENV
77+
cat $GITHUB_ENV
78+
- name: push release
79+
if: github.event_name == 'push'
80+
uses: softprops/action-gh-release@v1
81+
with:
82+
name: "Toml cli ${{ env.tag }}"
83+
body: |
84+
"Toml cli release ${{ env.tag }}"
85+
generate_release_notes: true
86+
files: |
87+
${{ env.tarballs }}
88+
89+
publish-image:
90+
runs-on: ubuntu-latest
91+
needs: [build-linux]
92+
steps:
93+
- name: Checkout repository
94+
uses: actions/checkout@v2
95+
- name: Log in to the container registry
96+
uses: docker/login-action@v2
97+
with:
98+
registry: ${{ env.REGISTRY }}
99+
username: ${{ github.actor }}
100+
password: ${{ secrets.GITHUB_TOKEN }}
101+
- name: download artifacts
102+
uses: actions/download-artifact@v2
103+
with:
104+
name: toml-artifacts-linux
105+
path: misc
106+
- name: Extract metadata (tags, labels) for Docker
107+
id: meta
108+
uses: docker/metadata-action@v4
109+
with:
110+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
111+
- name: build and push toml cli image
112+
uses: docker/build-push-action@v3
113+
with:
114+
context: misc
115+
file: misc/Dockerfile
116+
push: true
117+
tags: ${{ steps.meta.outputs.tags }}
118+
labels: ${{ steps.meta.outputs.labels }}

Cargo.lock

Lines changed: 51 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ serde = "1.0"
2424
serde_json = "1.0"
2525
structopt = "0.3"
2626
toml_edit = "0.15"
27+
28+
[dev-dependencies]
29+
tempfile = "3.3.0"

Makefile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
default: build
2+
3+
CARGO ?= $(shell which cargo)
4+
RUST_TARGET ?= x86_64-unknown-linux-musl
5+
INSTALL_DIR_PREFIX ?= "/usr/local/bin"
6+
7+
.format:
8+
${CARGO} fmt -- --check
9+
10+
build: .format
11+
${CARGO} build --target ${RUST_TARGET} --release
12+
# Cargo will skip checking if it is already checked
13+
${CARGO} clippy --bins --tests -- -Dwarnings
14+
15+
install: .format build
16+
mkdir -m 755 -p $(INSTALL_DIR_PREFIX)
17+
install -m 755 target/${RUST_TARGET}/release/toml $(INSTALL_DIR_PREFIX)/toml
18+
19+
clean:
20+
${CARGO} clean
21+
22+
ut:
23+
RUST_BACKTRACE=1 ${CARGO} test --workspace -- --skip integration --nocapture
24+
25+
integration:
26+
# run tests under `test` directory
27+
RUST_BACKTRACE=1 ${CARGO} test --workspace -- integration --nocapture
28+
29+
test: ut integration
30+
31+
all: build install test

misc/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM alpine:3.17
2+
3+
ADD toml /bin/toml
4+
RUN chmod +x /bin/toml

test/test.rs

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,82 @@
1-
use std::env;
2-
use std::ffi::OsString;
3-
use std::path::PathBuf;
1+
use std::fs;
42
use std::process;
53
use std::str;
64

5+
const TOML_CMD: &str = "toml";
6+
77
#[test]
8-
fn help_if_no_args() {
8+
fn integration_test_help_if_no_args() {
99
// Probably want to factor out much of this when adding more tests.
10-
let proc = process::Command::new(get_exec_path()).output().unwrap();
11-
assert!(!proc.status.success());
12-
let stderr = str::from_utf8(proc.stderr.as_slice()).unwrap();
10+
let cmd = process::Command::new(TOML_CMD).output().unwrap();
11+
assert!(!cmd.status.success());
12+
let stderr = str::from_utf8(cmd.stderr.as_slice()).unwrap();
1313
assert!(stderr.contains("-h, --help"));
1414
}
1515

16-
fn get_exec_path() -> PathBuf {
17-
// TODO is there no cleaner way to get this from Cargo?
18-
// Also should it really be "debug"?
19-
let target_dir: PathBuf = env::var_os("CARGO_TARGET_DIR")
20-
.unwrap_or_else(|| OsString::from("target"))
21-
.into();
22-
target_dir.join("debug").join("toml")
16+
#[test]
17+
fn integration_test_cmd_get() {
18+
let body = r#"[a]
19+
b = "c"
20+
[x]
21+
y = "z""#;
22+
let toml_dir = tempfile::tempdir().expect("failed to create tempdir");
23+
let toml_file = toml_dir.path().join("test.toml");
24+
fs::write(&toml_file, body).expect("failed to write tempfile");
25+
let toml_file = toml_file.as_os_str().to_str().unwrap();
26+
27+
let cmd = process::Command::new(TOML_CMD)
28+
.args(["get", toml_file, "x.y"])
29+
.output()
30+
.unwrap();
31+
assert!(cmd.status.success());
32+
let stdout = str::from_utf8(cmd.stdout.as_slice()).unwrap();
33+
assert_eq!("\"z\"\n", stdout);
34+
35+
// x.z does not exists
36+
let cmd = process::Command::new(TOML_CMD)
37+
.args(["get", toml_file, "x.z"])
38+
.output()
39+
.unwrap();
40+
assert!(!cmd.status.success());
41+
}
42+
43+
#[test]
44+
fn integration_test_cmd_set() {
45+
// fn set(path: PathBuf, query: &str, value_str: &str, opts: SetOpts) -> Result<(), Error> {
46+
let body = r#"[a]
47+
b = "c"
48+
[x]
49+
y = "z""#;
50+
let toml_dir = tempfile::tempdir().expect("failed to create tempdir");
51+
let toml_file = toml_dir.path().join("test.toml");
52+
fs::write(&toml_file, body).expect("failed to write tempfile");
53+
let toml_file = toml_file.as_os_str().to_str().unwrap();
54+
55+
// x.y exists
56+
let cmd = process::Command::new(TOML_CMD)
57+
.args(["set", toml_file, "x.y", "new"])
58+
.output()
59+
.unwrap();
60+
assert!(cmd.status.success());
61+
let stdout = str::from_utf8(cmd.stdout.as_slice()).unwrap();
62+
let excepted = r#"[a]
63+
b = "c"
64+
[x]
65+
y = "new"
66+
"#;
67+
assert_eq!(excepted, stdout);
68+
69+
let cmd = process::Command::new(TOML_CMD)
70+
.args(["set", toml_file, "x.z", "123"])
71+
.output()
72+
.unwrap();
73+
assert!(cmd.status.success());
74+
let stdout = str::from_utf8(cmd.stdout.as_slice()).unwrap();
75+
let excepted = r#"[a]
76+
b = "c"
77+
[x]
78+
y = "z"
79+
z = "123"
80+
"#;
81+
assert_eq!(excepted, stdout);
2382
}

0 commit comments

Comments
 (0)