Skip to content

Commit 8ecdd3f

Browse files
committed
feat: Add initial windows support
1 parent c7401f8 commit 8ecdd3f

File tree

7 files changed

+140
-64
lines changed

7 files changed

+140
-64
lines changed

.editorconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ root = true
33
[*]
44
insert_final_newline = true
55
trim_trailing_whitespace = true
6+
indent_size = 4
67

78
[*.{yml,yaml}]
89
indent_size = 2

.github/workflows/release.yml

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ jobs:
2727
- os: macos
2828
image: macos-latest
2929
target: x86_64-apple-darwin
30+
- os: windows
31+
image: windows-latest
32+
target: x86_64-pc-windows-msvc
3033

3134
steps:
3235
- uses: actions/checkout@v2
@@ -42,17 +45,28 @@ jobs:
4245
if: ${{ matrix.os == 'linux' }}
4346
run: cross build --release --target=${{ matrix.target }} --verbose
4447

45-
- name: Build macos
46-
if: ${{ matrix.os == 'macos' }}
48+
- name: Build != linux
49+
if: ${{ matrix.os != 'linux' }}
4750
run: cargo build --release --target=${{ matrix.target }} --verbose
4851

4952
- name: Prepare
53+
shell: bash
5054
run: |
51-
final_binary=${{ env.BINARY_NAME }}-${{ matrix.target }}
52-
mv target/${{ matrix.target }}/release/${{ env.BINARY_NAME }} $final_binary
55+
compress() {
56+
if [[ "${{ matrix.os }}" = "windows" ]]; then
57+
7z a $(echo $1 | sed 's/\.exe$//').zip $1
58+
else
59+
gzip -f9 $1
60+
fi
61+
}
62+
if [[ "${{ matrix.os }}" = "windows" ]]; then
63+
suffix=.exe
64+
fi
65+
final_binary=${{ env.BINARY_NAME }}-${{ matrix.target }}${suffix}
66+
mv target/${{ matrix.target }}/release/${{ env.BINARY_NAME }}${suffix} $final_binary
5367
ls
5468
file $final_binary
55-
gzip -f9 $final_binary
69+
compress $final_binary
5670
5771
- name: Archive binary artifacts
5872
uses: actions/upload-artifact@v2
@@ -61,6 +75,7 @@ jobs:
6175
if-no-files-found: warn
6276
path: |
6377
*.gz
78+
*.zip
6479
6580
create_release:
6681
name: Create Release
@@ -90,8 +105,20 @@ jobs:
90105
matrix:
91106
include:
92107
- target: x86_64-unknown-linux-musl
108+
content_type: application/gzip
109+
extension: gz
93110
- target: aarch64-unknown-linux-musl
111+
content_type: application/gzip
112+
extension: gz
94113
- target: x86_64-apple-darwin
114+
content_type: application/gzip
115+
extension: gz
116+
- target: x86_64-apple-darwin
117+
content_type: application/gzip
118+
extension: gz
119+
- target: x86_64-pc-windows-msvc
120+
content_type: application/zip
121+
extension: zip
95122
steps:
96123
- name: Download all workflow run artifacts
97124
uses: actions/download-artifact@v2
@@ -103,6 +130,6 @@ jobs:
103130
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
104131
with:
105132
upload_url: ${{ needs.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
106-
asset_path: ./binaries/${{ env.BINARY_NAME }}-${{ matrix.target }}.gz
107-
asset_name: ${{ env.BINARY_NAME }}-${{ matrix.target }}.gz
108-
asset_content_type: application/gzip
133+
asset_path: ./binaries/${{ env.BINARY_NAME }}-${{ matrix.target }}.${{ matrix.extension }}
134+
asset_name: ${{ env.BINARY_NAME }}-${{ matrix.target }}.${{ matrix.extension }}
135+
asset_content_type: ${{ matrix.content_type }}

.github/workflows/tests.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ jobs:
2020
image: ubuntu-latest
2121
- os: macos
2222
image: macos-latest
23+
- os: windows
24+
image: windows-latest
2325

2426
steps:
2527
- uses: actions/checkout@v2
@@ -39,6 +41,19 @@ jobs:
3941
set -ex
4042
brew install gpg sops kustomize
4143
44+
# Chocolatey times out, so scoop it is
45+
- name: Install windows
46+
if: ${{ matrix.os == 'windows' }}
47+
run: |
48+
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
49+
scoop install gnupg sops kustomize
50+
echo "~/scoop/shims" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
51+
- name: Check for kustomize
52+
if: ${{ matrix.os == 'windows' }}
53+
run: |
54+
echo $env:PATH
55+
get-command kustomize
56+
4257
- name: Build
4358
run: cargo build --verbose
4459
- name: Run tests

src/installer.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#[cfg(target_family = "unix")]
2+
use std::os::unix::fs::symlink;
3+
#[cfg(target_family = "windows")]
4+
use std::os::windows::fs::symlink_file as symlink;
5+
6+
use std::path::MAIN_SEPARATOR;
7+
use std::{
8+
env::{args, var},
9+
fs::{canonicalize, create_dir_all},
10+
path::PathBuf,
11+
};
12+
13+
use color_eyre::eyre::{eyre, WrapErr};
14+
use dirs::home_dir;
15+
16+
use crate::types::Kind;
17+
use crate::{API_VERSION, XDG_CONFIG_HOME};
18+
19+
pub fn install() -> color_eyre::Result<()> {
20+
let home = home_dir().ok_or_else(|| eyre!("Failed to determine home director"))?;
21+
let install_directory = get_install_directory(home);
22+
23+
let source = PathBuf::from(args().next().unwrap());
24+
let source =
25+
canonicalize(&source).wrap_err("failed to find the absolute path of the current binary")?;
26+
27+
let kinds = [
28+
Kind::ConfigMapGenerator,
29+
Kind::SecretGenerator,
30+
Kind::SimpleDecrypt,
31+
];
32+
33+
let binary_suffix = if cfg!(windows) { ".exe" } else { "" };
34+
35+
for kind in &kinds {
36+
let kind = format!("{:?}", kind);
37+
let destination_folder = install_directory.join(&kind.to_lowercase());
38+
create_dir_all(&destination_folder).wrap_err_with(|| {
39+
format!(
40+
"failed to create directory {}",
41+
&destination_folder.to_string_lossy()
42+
)
43+
})?;
44+
45+
let destination = destination_folder.join(format!("{}{}", &kind, &binary_suffix));
46+
println!(
47+
"Linking kustomize-sops-rs to {}",
48+
&destination.to_string_lossy()
49+
);
50+
if destination.exists() {
51+
std::fs::remove_file(&destination).wrap_err("failed to delete old file")?;
52+
}
53+
symlink(&source, destination).wrap_err("failed to create link")?;
54+
}
55+
Ok(())
56+
}
57+
58+
fn get_install_directory(home: PathBuf) -> PathBuf {
59+
let api_directory = API_VERSION.replace("/", &MAIN_SEPARATOR.to_string());
60+
var(XDG_CONFIG_HOME)
61+
.wrap_err("failed to get the install directory")
62+
.map(|config| PathBuf::from(config))
63+
.unwrap_or_else(|_| home.join(".config"))
64+
.join("kustomize")
65+
.join("plugin")
66+
.join(api_directory)
67+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod cli;
22
pub mod decryption;
3+
pub mod installer;
34
pub mod maps;
45
pub mod types;
56

src/main.rs

Lines changed: 8 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
use std::{
2-
env::{args, var},
3-
fs::{canonicalize, create_dir_all, File},
2+
fs::File,
43
io::{stdout, Write},
5-
os::unix::fs::symlink,
6-
path::PathBuf,
74
process::exit,
85
};
96

107
use clap::Clap;
11-
use color_eyre::{
12-
eyre::{eyre, Context},
13-
Result,
14-
};
15-
use dirs::home_dir;
8+
use color_eyre::Result;
9+
use serde_yaml::{from_reader, to_string};
10+
1611
use kustomize_sops::{
17-
cli::Arguments, cli::SubCommand, decryption::decrypt_file, maps::generate_data_field,
18-
maps::generate_output_map, types::Input, types::Kind, API_VERSION, CONFIG_MAP_OUTPUT,
19-
SECRET_OUTPUT, XDG_CONFIG_HOME,
12+
cli::Arguments, cli::SubCommand, decryption::decrypt_file, installer,
13+
maps::generate_data_field, maps::generate_output_map, types::Input, types::Kind,
14+
CONFIG_MAP_OUTPUT, SECRET_OUTPUT,
2015
};
21-
use serde_yaml::{from_reader, to_string};
2216

2317
fn main() -> Result<()> {
2418
color_eyre::install()?;
@@ -33,7 +27,7 @@ fn main() -> Result<()> {
3327
};
3428
}
3529
match arguments.subcommand {
36-
Some(SubCommand::Install) => return install(),
30+
Some(SubCommand::Install) => return installer::install(),
3731
None => {
3832
eprintln!("The yaml file is required if no command is set");
3933
exit(1);
@@ -61,45 +55,3 @@ fn process_simple_decrypt(input: &Input) -> Result<()> {
6155

6256
Ok(())
6357
}
64-
65-
fn install() -> Result<()> {
66-
let home = home_dir().ok_or_else(|| eyre!("Failed to determine home director"))?;
67-
let install_directory = var(XDG_CONFIG_HOME)
68-
.wrap_err("failed to get the install directory")
69-
.map(|config| PathBuf::from(config))
70-
.unwrap_or_else(|_| home.join(".config"))
71-
.join("kustomize")
72-
.join("plugin")
73-
.join(API_VERSION);
74-
75-
let source = PathBuf::from(args().next().unwrap());
76-
let source =
77-
canonicalize(&source).wrap_err("failed to find the absolute path of the current binary")?;
78-
79-
let kinds = [
80-
Kind::ConfigMapGenerator,
81-
Kind::SecretGenerator,
82-
Kind::SimpleDecrypt,
83-
];
84-
85-
for kind in &kinds {
86-
let kind = format!("{:?}", kind);
87-
let destination_folder = install_directory.join(&kind.to_lowercase());
88-
create_dir_all(&destination_folder).wrap_err_with(|| {
89-
format!(
90-
"failed to create directory {}",
91-
&destination_folder.to_string_lossy()
92-
)
93-
})?;
94-
let destination = destination_folder.join(&kind);
95-
println!(
96-
"Linking kustomize-sops-rs to {}",
97-
&destination.to_string_lossy()
98-
);
99-
if !destination.exists() {
100-
// XXX: To implement on windows this needs to change
101-
symlink(&source, destination).wrap_err("failed to create link")?;
102-
}
103-
}
104-
Ok(())
105-
}

tests/integration.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@ fn setup_tests() {
1616
}
1717

1818
fn configure_gpg() -> Result<()> {
19+
let output = Command::new("gpg")
20+
.arg("--list-keys")
21+
.stderr(Stdio::piped())
22+
.stdout(Stdio::piped())
23+
.output()
24+
.wrap_err("failed to run gpg")?;
25+
26+
check_output_status(&output)?;
27+
if String::from_utf8_lossy(&output.stdout).contains("EBC846D0169D43A96ABA1C31AD471BDF8E8A0484")
28+
{
29+
return Ok(());
30+
}
1931
let output = Command::new("gpg")
2032
.args(&["--import", "tests/kustomization/private.key"])
2133
.stderr(Stdio::piped())
@@ -59,6 +71,7 @@ fn run_with_kustomize() {
5971
.stdout(Stdio::piped())
6072
.stderr(Stdio::piped())
6173
.output()
74+
.wrap_err("failed to execute kustomize")
6275
.unwrap();
6376

6477
let stdout = String::from_utf8_lossy(&output.stdout);

0 commit comments

Comments
 (0)