Skip to content

Commit

Permalink
feat: removed PERSEUS_STANDALONE
Browse files Browse the repository at this point in the history
Deployed binaries can now operate without that environment variable by
using inbuilt feature flags.

Closes #87.
  • Loading branch information
arctic-hen7 committed Dec 12, 2021
1 parent 1c0122a commit d178f5a
Show file tree
Hide file tree
Showing 14 changed files with 41 additions and 19 deletions.
2 changes: 1 addition & 1 deletion docs/0.3.x/en-US/deploying/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ If you use `perseus deploy -e`, the contents of `pkg/` can be served by any file

### Fully-Fledged Server

If you just use `perseus deploy`, the `pkg/` directory will contain a binary called `server` for you to run, which will serve your app on its own. However, it's important to note that this binary is structured to support either the development configuration of running inside `.perseus/` or the production configuration of running inside `pkg/`, and you have to provide the `PERSEUS_STANDALONE` environment variable to tell it to do the latter. This binary can then be run on any server with a writable filesystem. For more details on this, see the next subsection.
If you just use `perseus deploy`, the `pkg/` directory will contain a binary called `server` for you to run, which will serve your app on its own, without the need for any of the development infrastructure (e.g. the `.perseus/` directory). Running this used to require setting the `PERSEUS_STANDALONE` environment variable, though after [this](https://github.com/arctic-hen7/perseus/issues/87) that's no longer required.
2 changes: 1 addition & 1 deletion docs/0.3.x/en-US/deploying/serverful.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

If your app uses rendering strategies that need a server, you won't be able to export your app to purely static files, and so you'll need to host the Perseus server itself.

You can prepare your production server by running `perseus deploy`, which will create a new directory called `pkg/`, which will contain the standalone binary and everything needed to run it. You should then upload this file to your server and set the `PERSEUS_STANDALONE` environment variable to `true` so that Perseus expects a standalone binary configuration. Note that this process will vary depending on your hosting provider.
You can prepare your production server by running `perseus deploy`, which will create a new directory called `pkg/`, which will contain the standalone binary and everything needed to run it.

## Hosting Providers

Expand Down
2 changes: 1 addition & 1 deletion docs/next/en-US/deploying/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ If you use `perseus deploy -e`, the contents of `pkg/` can be served by any file

### Fully-Fledged Server

If you just use `perseus deploy`, the `pkg/` directory will contain a binary called `server` for you to run, which will serve your app on its own. However, it's important to note that this binary is structured to support either the development configuration of running inside `.perseus/` or the production configuration of running inside `pkg/`, and you have to provide the `PERSEUS_STANDALONE` environment variable to tell it to do the latter. This binary can then be run on any server with a writable filesystem. For more details on this, see the next subsection.
If you just use `perseus deploy`, the `pkg/` directory will contain a binary called `server` for you to run, which will serve your app on its own, without the need for any of the development infrastructure (e.g. the `.perseus/` directory). Running this used to require setting the `PERSEUS_STANDALONE` environment variable, though after [this](https://github.com/arctic-hen7/perseus/issues/87) that's no longer required.
2 changes: 1 addition & 1 deletion docs/next/en-US/deploying/serverful.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

If your app uses rendering strategies that need a server, you won't be able to export your app to purely static files, and so you'll need to host the Perseus server itself.

You can prepare your production server by running `perseus deploy`, which will create a new directory called `pkg/`, which will contain the standalone binary and everything needed to run it. You should then upload this file to your server and set the `PERSEUS_STANDALONE` environment variable to `true` so that Perseus expects a standalone binary configuration. Note that this process will vary depending on your hosting provider.
You can prepare your production server by running `perseus deploy`, which will create a new directory called `pkg/`, which will contain the standalone binary and everything needed to run it.

## Hosting Providers

Expand Down
4 changes: 4 additions & 0 deletions examples/basic/.perseus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ console_error_panic_hook = "0.1.6"
# This section is needed for Wasm Pack (which we use instead of Trunk for flexibility)
[lib]
crate-type = ["cdylib", "rlib"]

[features]
# This changes a few things to support running as a standalone server binary (this is set by `perseus deploy`, do NOT invoke this manually!)
standalone = []
4 changes: 3 additions & 1 deletion examples/basic/.perseus/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ warp = { package = "warp-fix-171", version = "0.3", optional = true }
tokio = { version = "1", optional = true, features = [ "macros", "rt-multi-thread" ] } # We don't need this for Actix Web

# This binary can use any of the server integrations
# Note: because of the way the CLI works, each feature must be an integration
[features]
integration-actix-web = [ "perseus-actix-web", "actix-web" ]
integration-warp = [ "perseus-warp", "warp", "tokio" ]

default = [ "integration-warp" ]

# This makes the binary work on its own, and is enabled by `perseus deploy` (do NOT invoke this manually!)
standalone = [ "perseus/standalone", "perseus-engine/standalone" ]
3 changes: 1 addition & 2 deletions examples/basic/.perseus/server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use std::fs;
// This server executable can be run in two modes:
// dev: inside `.perseus/server/src/main.rs`, works with that file structure
// prod: as a standalone executable with a `dist/` directory as a sibling
// The prod mode can be enabled by setting the `PERSEUS_STANDALONE` environment variable

// Integration: Actix Web
#[cfg(feature = "integration-actix-web")]
Expand Down Expand Up @@ -53,7 +52,7 @@ fn get_standalone_and_act() -> bool {
// So we don't have to define a different `FsConfigManager` just for the server, we shift the execution context to the same level as everything else
// The server has to be a separate crate because otherwise the dependencies don't work with Wasm bundling
// If we're not running as a standalone binary, assume we're running in dev mode under `.perseus/`
if env::var("PERSEUS_STANDALONE").is_err() {
if !cfg!(feature = "standalone") {
env::set_current_dir("../").unwrap();
false
} else {
Expand Down
4 changes: 2 additions & 2 deletions examples/basic/.perseus/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ pub fn get_static_aliases<G: GenericNode>(plugins: &Plugins<G>) -> HashMap<Strin
} else if path.starts_with("./") {
// `./` -> `../` (moving to execution from `.perseus/`)
// But if we're operating standalone, it stays the same
if ::std::env::var("PERSEUS_STANDALONE").is_ok() {
if cfg!(feature = "standalone") {
path.to_string()
} else {
format!(".{}", path)
}
} else {
// Anything else gets a `../` prepended
// But if we're operating standalone, it stays the same
if ::std::env::var("PERSEUS_STANDALONE").is_ok() {
if cfg!(feature = "standalone") {
path.to_string()
} else {
format!("../{}", path)
Expand Down
3 changes: 2 additions & 1 deletion packages/perseus-cli/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ fn deploy_full(dir: PathBuf, output: String) -> Result<i32, Error> {
no_run: true,
no_build: false,
release: true,
standalone: true,
},
)?;
if serve_exit_code != 0 {
Expand Down Expand Up @@ -112,7 +113,7 @@ fn deploy_full(dir: PathBuf, output: String) -> Result<i32, Error> {
}

println!();
println!("Deployment complete 🚀! Your app is now available for serving in the standalone folder '{}'! You can run it by executing the `server` binary in that folder with the `PERSEUS_STANDALONE` environment variable set to `true`.", &output_path.to_str().map(|s| s.to_string()).unwrap());
println!("Deployment complete 🚀! Your app is now available for serving in the standalone folder '{}'! You can run it by executing the `server` binary in that folder.", &output_path.to_str().map(|s| s.to_string()).unwrap());

Ok(0)
} else {
Expand Down
3 changes: 3 additions & 0 deletions packages/perseus-cli/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ pub struct ServeOpts {
/// Build and serve for production
#[clap(long)]
pub release: bool,
/// Make the final binary standalone (this is used in `perseus deploy` only, don't manually invoke it unless you have a good reason!)
#[clap(long)]
pub standalone: bool,
}
/// Removes `.perseus/` entirely for updates or to fix corruptions
#[derive(Parser)]
Expand Down
11 changes: 9 additions & 2 deletions packages/perseus-cli/src/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ fn build_server(
did_build: bool,
exec: Arc<Mutex<String>>,
is_release: bool,
is_standalone: bool,
) -> Result<
ThreadHandle<impl FnOnce() -> Result<i32, ExecutionError>, Result<i32, ExecutionError>>,
ExecutionError,
Expand Down Expand Up @@ -65,9 +66,14 @@ fn build_server(
let (stdout, _stderr) = handle_exit_code!(run_stage(
vec![&format!(
// This sets Cargo to tell us everything, including the executable path to the server
"{} build --message-format json {}",
"{} build --message-format json {} {}",
env::var("PERSEUS_CARGO_PATH").unwrap_or_else(|_| "cargo".to_string()),
if is_release { "--release" } else { "" }
if is_release { "--release" } else { "" },
if is_standalone {
"--features standalone"
} else {
""
}
)],
&sb_target,
&sb_spinner,
Expand Down Expand Up @@ -191,6 +197,7 @@ pub fn serve(dir: PathBuf, opts: ServeOpts) -> Result<(i32, Option<String>), Exe
did_build,
Arc::clone(&exec),
opts.release,
opts.standalone,
)?;
// Only build if the user hasn't set `--no-build`, handling non-zero exit codes
if did_build {
Expand Down
2 changes: 2 additions & 0 deletions packages/perseus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ tinker-plugins = []
# This feature enables server-side-only features, which should be used on both the server and in the builder
# This prevents leakage of server-side code
server-side = []
# This feature changes a few defaults so that Perseus works seemlessly when deployed with the `.perseus/` structure (this is activated automatically by `perseus deploy`, and should not be invoked manually!)
standalone = []
2 changes: 2 additions & 0 deletions packages/perseus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ pub mod internal {
pub use crate::client_translations_manager::*;
pub use crate::locale_detector::*;
pub use crate::locales::*;
#[doc(hidden)]
pub use crate::macros::DFLT_TRANSLATIONS_DIR;
pub use crate::translations_manager::*;
pub use crate::translator::*;
}
Expand Down
16 changes: 9 additions & 7 deletions packages/perseus/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ macro_rules! define_app_root {
pub static APP_ROOT: &str = $root_id;
};
}
#[cfg(feature = "standalone")]
#[doc(hidden)]
/// The default translations directory when we're running as a standalone binary.
pub static DFLT_TRANSLATIONS_DIR: &str = "./translations";
#[cfg(not(feature = "standalone"))]
#[doc(hidden)]
/// The default translations directory when we're running with the `.perseus/` support structure.
pub static DFLT_TRANSLATIONS_DIR: &str = "../translations";
/// An internal macro used for defining a function to get the user's preferred translations manager (which requires multiple branches).
/// This is not plugin-extensible, but a control action can reset it later.
#[doc(hidden)]
Expand All @@ -65,14 +73,8 @@ macro_rules! define_get_translations_manager {
.cloned()
.cloned()
.collect();
// If we're running on a server, we should be using a flattened directory structure
let translations_dir = if ::std::env::var("PERSEUS_STANDALONE").is_ok() {
"./translations"
} else {
"../translations"
};
$crate::internal::i18n::FsTranslationsManager::new(
translations_dir.to_string(),
$crate::internal::i18n::DFLT_TRANSLATIONS_DIR.to_string(),
all_locales,
$crate::internal::i18n::TRANSLATOR_FILE_EXT.to_string(),
$crate::internal::get_path_prefix_server(),
Expand Down

0 comments on commit d178f5a

Please sign in to comment.