Skip to content
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
107 changes: 93 additions & 14 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ homepage = "https://oseda.net"
repository = "https://github.com/oseda-dev/oseda-cli"
readme = "README.md"
name = "oseda-cli"
version = "2.4.6"
version = "2.6.0"
edition = "2021"

[[bin]]
Expand All @@ -20,6 +20,7 @@ chrono = { version = "0.4.41", features = ["serde"] }
clap = { version = "4.5.38", features = ["derive"] }
clap-markdown = "0.1.5"
ctrlc = "3.4.7"
dirs = "6.0.0"
inquire = "0.7.5"
open = "5.3.3"
reqwest = { version = "0.12.20", features = ["blocking"] }
Expand Down
1 change: 0 additions & 1 deletion src/cmd/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ pub fn deploy(opts: DeployOptions) -> Result<(), Box<dyn Error>> {
if open::that(pull_request_url.clone()).is_err() {
return Err(format!("Please visit {pull_request_url} in a browser and submit a pull-request by hand").into());
};

}
None => {
println!("Error: could not get github username");
Expand Down
17 changes: 14 additions & 3 deletions src/cmd/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ use std::{

use clap::Args;

use crate::{cmd::run, net::kill_port};
use crate::{
cmd::run,
net::kill_port,
puppeteer::{is_puppeteer_chrome_installed, prompt_install_puppeteer_chrome},
};

/// Options struct for the export subcommand
#[derive(Args, Debug, Clone)]
Expand All @@ -24,6 +28,7 @@ pub struct ExportOptions {

/// Export the current Oseda project to a PDF file via `decktape`
pub fn export(opts: ExportOptions) -> Result<(), Box<dyn Error>> {
println!("Cleaning any existing oseda processing...");
if kill_port(opts.port).is_err() {
eprintln!("Warning, could not kill value on desired port")
}
Expand All @@ -33,6 +38,12 @@ pub fn export(opts: ExportOptions) -> Result<(), Box<dyn Error>> {
.current_dir(".")
.output()?;

// prompt for puppeteer and confirm installation
if !is_puppeteer_chrome_installed() {
prompt_install_puppeteer_chrome()?;
}
println!("Puppeteer Chrome is installed, continuing...");

if !output.status.success() {
eprintln!(
"Decktape installation failure: {}",
Expand All @@ -54,8 +65,8 @@ pub fn export(opts: ExportOptions) -> Result<(), Box<dyn Error>> {
let addr = format!("http://localhost:{}", opts.port);

// run decktape, assuming the server has spun up by now
let export_output = Command::new("decktape")
.args(["automatic", &addr, &opts.output])
let export_output = Command::new("npm")
.args(["exec", "decktape", "reveal", &addr, &opts.output])
.output()?;

// send shutdown flag, should signal to run_with_shutdown to kill the process
Expand Down
1 change: 0 additions & 1 deletion src/cmd/init.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

use std::{
error::Error,
fs::{self},
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod color;
pub mod config;
pub mod github;
pub mod net;
pub mod puppeteer;
pub mod tags;
pub mod template;

Expand Down
68 changes: 68 additions & 0 deletions src/puppeteer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// utils for puppeteer and chrome

use std::{error::Error, process::Command};

use inquire::Confirm;
/// Checks whether headless Chrome has been installed on the users system via npx puppeteer
///
/// # Returns
///
/// - `bool` - Whether or not it has been installed
pub fn is_puppeteer_chrome_installed() -> bool {
//puppeteer will install into cache directory
// this is differnt on different systems
// afaik, not even specific to just OS -> so I pulled in `dirs`
let mut path = match dirs::cache_dir() {
Some(p) => p,
None => return false,
};

// {cache}/puppeteer/chrome
path.push("puppeteer");
path.push("chrome");

if path.is_dir() {
if let Ok(entries) = std::fs::read_dir(&path) {
// if any folder present, should be installed
return entries
.filter_map(Result::ok)
.any(|entry| entry.path().is_dir());
}
}

false
}

/// Prompts the user for an installation of headless Chrome via. Puppeteer, installing it if they elect to proceed
///
/// # Returns
///
/// - `Result<(), Box<dyn Error>>`
/// - Ok(()) if installation proceeds as normal
/// - Err() if installation is aborted by user
pub fn prompt_install_puppeteer_chrome() -> Result<(), Box<dyn Error>> {
println!("`oseda export` uses DeckTape to export your presentation");
println!("DeckTape needs chromium installed (puppeteer prefered");
println!("Puppeteer Chrome is not currently detected.");
let ans = Confirm::new("Would you like to install it and proceed?")
.with_default(false)
.prompt();

// let else my beloved
// gaurd clause
let Ok(true) = ans else {
return Err("DeckTape is required to proceed".into());
};

println!("Installing Puppeteer Chrome... (This may take several minutes, you will only need to install this once");

let chrome_install_output = Command::new("npx")
.args(["puppeteer", "browsers", "install", "chrome"])
.output()?;

if !chrome_install_output.status.success() {
return Err("Error: could not install puppeteer chrome".into());
}

Ok(())
}
Loading
Loading