Skip to content

Commit

Permalink
Impl gitignore updates, GitHub actions updates, version configs
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanFlurry committed Aug 22, 2022
1 parent 8fae592 commit 475de8c
Show file tree
Hide file tree
Showing 8 changed files with 352 additions and 9 deletions.
31 changes: 31 additions & 0 deletions Cargo.lock

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

100 changes: 92 additions & 8 deletions cli/src/commands/init.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
use anyhow::{bail, Context, Result};
use anyhow::{bail, ensure, Context, Result};
use clap::Parser;
use console::Term;
use std::path::Path;
use tokio::{fs, io::AsyncWriteExt};

use crate::util::{secrets, term};
use crate::util::{git, secrets, term};

const GITHUB_WORKFLOW_RIVET_PUBLISH_YAML: &'static str =
include_str!("../../tpl/workflows/rivet-publish.yaml");
const RIVET_VERSION_TOML: &'static str = include_str!("../../tpl/rivet.version.toml");

#[derive(Parser)]
pub struct Opts {}

impl Opts {
pub async fn execute(&self, term: &Term, override_api_url: Option<String>) -> Result<()> {
// Check if token already exists
let ctx = if let Some(cloud_token) = secrets::read_cloud_token().await? {
if let Some(cloud_token) = secrets::read_cloud_token().await? {
let ctx = cli_core::ctx::init(override_api_url.clone(), cloud_token).await?;

let game_res = ctx
Expand All @@ -23,20 +29,98 @@ impl Opts {
let game = game_res.game().context("game_res.game")?;
let display_name = game.display_name().context("game.display_name")?;

term::status::success("Found Existing Token", display_name);
term::status::success("Found existing token", display_name);
} else {
read_cloud_token(term, override_api_url.clone()).await?;
};

// Update .gitignore
if !git::check_ignore(Path::new(".rivet/")).await? {
if term::input::bool(term, "Add .rivet/ to .gitignore?").await? {
let mut file = fs::OpenOptions::new()
.write(true)
.append(true)
.open(".gitignore")
.await?;
file.write_all(b"\n### Rivet ###\n.rivet/\n").await?;

ctx
ensure!(
git::check_ignore(Path::new(".rivet/")).await?,
"updated gitignore does not ignore Rivet files"
);

term::status::success("Finished", "Git will now ignore the .rivet/ folder.");
}
} else {
read_cloud_token(term, override_api_url.clone()).await?
term::status::success(
".gitignore already configured",
"The .rivet/ folder is already ignored by Git.",
);
}

// Create .github/workflows/rivet-push.yaml
let workflows_path = std::env::current_dir()?.join(".github").join("workflows");
let actions_path = workflows_path.join("rivet-publish.yaml");
let actions_needs_update = match fs::read_to_string(&actions_path).await {
Ok(old_actions_file) => old_actions_file != GITHUB_WORKFLOW_RIVET_PUBLISH_YAML,
Err(err) if err.kind() == std::io::ErrorKind::NotFound => true,
Err(err) => {
return Err(err.into());
}
};
if actions_needs_update {
if term::input::bool(
term,
"Setup GitHub Actions at .github/workflows/rivet-push.yaml?",
)
.await?
{
fs::create_dir_all(&workflows_path).await?;
fs::write(actions_path, GITHUB_WORKFLOW_RIVET_PUBLISH_YAML).await?;

term::status::success(
"Finished",
"Your game will automatically deploy to Rivet next time you push to GitHub.",
);
}
} else {
term::status::success(
"GitHub Actions already configured",
"Your game already deploys to Rivet when you push to GitHub.",
);
}

// Create rivet.version.toml
let config_path = std::env::current_dir()?.join("rivet.version.toml");
let config_needs_creation = match fs::read_to_string(&config_path).await {
Ok(_) => false,
Err(err) if err.kind() == std::io::ErrorKind::NotFound => true,
Err(err) => {
return Err(err.into());
}
};
if config_needs_creation {
if term::input::bool(term, "Create default config at rivet.version.toml?").await? {
fs::write(config_path, RIVET_VERSION_TOML).await?;

term::status::success(
"Finished",
"Rivet Matchmaker and Rivet CDN will be enabled next time you deploy.",
);
}
} else {
term::status::success(
"Version already configured",
"Your game is already configured with rivet.version.toml.",
);
}

Ok(())
}
}

async fn read_cloud_token(term: &Term, override_api_url: Option<String>) -> Result<cli_core::Ctx> {
term.write_line("Cloud token: ")?;
let token = tokio::task::block_in_place(|| term.read_secure_line())?;
let token = term::input::secure(term, "Rivet cloud token?").await?;

// Create new context
let new_ctx = cli_core::ctx::init(
Expand Down
12 changes: 12 additions & 0 deletions cli/src/util/git.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use anyhow::Result;
use std::path::Path;
use tokio::process::Command;

pub async fn check_ignore(path: &Path) -> Result<bool> {
let output = Command::new("git")
.arg("check-ignore")
.arg(path)
.output()
.await?;
Ok(output.status.success())
}
1 change: 1 addition & 0 deletions cli/src/util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod fmt;
pub mod game;
pub mod git;
pub mod paths;
pub mod secrets;
pub mod struct_fmt;
Expand Down
49 changes: 48 additions & 1 deletion cli/src/util/term.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ where
println!("{}", table);
}

pub fn link<'a>(msg: impl ToString) -> StyledObject<String> {
pub fn link(msg: impl ToString) -> StyledObject<String> {
style(msg.to_string()).italic().underlined()
}

pub fn code(msg: impl ToString) -> StyledObject<String> {
style(msg.to_string()).italic()
}

pub mod status {
use console::style;
use std::fmt::Display;
Expand All @@ -40,3 +44,46 @@ pub mod status {
eprintln!(" {} {}", style(msg).bold().red(), data);
}
}

pub mod input {
use anyhow::Result;
use console::{style, Term};
use std::fmt::Display;

pub async fn input(term: &Term, msg: impl Display) -> Result<String> {
eprint!("{} ", style(msg).bold().blue());
term.flush()?;
let input = tokio::task::block_in_place(|| term.read_line())?;
Ok(input)
}

pub async fn secure(term: &Term, msg: impl Display) -> Result<String> {
eprint!("{} ", style(msg).bold().blue());
term.flush()?;
let input = tokio::task::block_in_place(|| term.read_secure_line())?;
Ok(input)
}

pub async fn bool(term: &Term, msg: impl Display + Clone) -> Result<bool> {
loop {
eprint!(
"{} {} ",
style(msg.clone()).bold().blue(),
style("(y/n)").italic()
);
term.flush()?;
let input = tokio::task::block_in_place(|| term.read_char())?;
eprintln!();

match input {
'y' | 'Y' => return Ok(true),
'n' | 'N' => return Ok(false),
_ => {
super::status::error("Invalid Bool", "Must be y or n");
eprintln!();
continue;
}
}
}
}
}
16 changes: 16 additions & 0 deletions cli/tpl/rivet.version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[cdn]

[matchmaker]
[matchmaker.game_modes.default]
tier = "basic-1d1"
max_players = 16

[matchmaker.game_modes.default.docker]
args = []
env = {}

[matchmaker.game_modes.default.docker.ports]
https = { proto = "https", target = 80 }

[kv]

Loading

0 comments on commit 475de8c

Please sign in to comment.