Skip to content
This repository has been archived by the owner on Aug 3, 2023. It is now read-only.

Commit

Permalink
Merge pull request #632 from cloudflare/alewis/build-site
Browse files Browse the repository at this point in the history
Add support for generating and initializing site projects
  • Loading branch information
ashleymichal authored Sep 19, 2019
2 parents b9c3a50 + 359b2e8 commit 5385c86
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 152 deletions.
31 changes: 29 additions & 2 deletions src/commands/build/wranglerjs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod output;

use crate::commands::build::watch::wait_for_changes;
use crate::commands::build::watch::COOLDOWN_PERIOD;
use crate::commands::generate::run_generate;

use crate::commands::publish::package::Package;
use crate::install;
Expand Down Expand Up @@ -128,7 +129,12 @@ fn setup_build(target: &Target) -> Result<(Command, PathBuf, Bundle), failure::E
}

let build_dir = target.build_dir()?;
run_npm_install(&build_dir.to_path_buf()).expect("could not run `npm install`");

if target.site.is_some() {
scaffold_site_worker(&target)?;
}

run_npm_install(&build_dir).expect("could not run `npm install`");

let node = which::which("node").unwrap();
let mut command = Command::new(node);
Expand Down Expand Up @@ -166,7 +172,7 @@ fn setup_build(target: &Target) -> Result<(Command, PathBuf, Bundle), failure::E
if !bundle.has_webpack_config(&webpack_config_path) {
let package = Package::new(&build_dir)?;
let package_main = build_dir
.join(package.main()?)
.join(package.main(&build_dir)?)
.to_str()
.unwrap()
.to_string();
Expand All @@ -182,6 +188,27 @@ fn setup_build(target: &Target) -> Result<(Command, PathBuf, Bundle), failure::E
Ok((command, temp_file, bundle))
}

pub fn scaffold_site_worker(target: &Target) -> Result<(), failure::Error> {
let build_dir = target.build_dir()?;
// TODO: this is a placeholder template. Replace with The Real Thing on launch.
let template = "https://github.com/ashleymichal/glowing-palm-tree";

if !Path::new(&build_dir).exists() {
// TODO: use site.entry_point instead of build_dir explicitly.
run_generate(
build_dir.file_name().unwrap().to_str().unwrap(),
template,
&target.target_type,
)?;

// This step is to prevent having a git repo within a git repo after
// generating the scaffold into an existing project.
fs::remove_dir_all(&build_dir.join(".git"))?;
}

Ok(())
}

// Run {npm install} in the specified directory. Skips the install if a
// {node_modules} is found in the directory.
fn run_npm_install(dir: &PathBuf) -> Result<(), failure::Error> {
Expand Down
15 changes: 13 additions & 2 deletions src/commands/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,29 @@ pub fn generate(
name: &str,
template: &str,
target_type: Option<TargetType>,
site: bool,
) -> Result<(), failure::Error> {
let target_type = target_type.unwrap_or_else(|| get_target_type(template));
run_generate(name, template, &target_type)?;
let config_path = PathBuf::from("./").join(&name);
Manifest::generate(name.to_string(), target_type, config_path, site)?;
Ok(())
}

pub fn run_generate(
name: &str,
template: &str,
target_type: &TargetType,
) -> Result<(), failure::Error> {
let tool_name = "cargo-generate";
let binary_path = install::install(tool_name, "ashleygwilliams")?.binary(tool_name)?;

let args = ["generate", "--git", template, "--name", name, "--force"];

let target_type = target_type.unwrap_or_else(|| get_target_type(template));
let command = command(name, binary_path, &args, &target_type);
let command_name = format!("{:?}", command);

commands::run(command, &command_name)?;
Manifest::generate(name.to_string(), target_type, false)?;
Ok(())
}

Expand Down
19 changes: 16 additions & 3 deletions src/commands/init.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
use crate::commands;
use crate::settings::target::{Manifest, TargetType};
use crate::terminal::message;
use std::path::Path;
use std::path::{Path, PathBuf};

pub fn init(name: Option<&str>, target_type: Option<TargetType>) -> Result<(), failure::Error> {
pub fn init(
name: Option<&str>,
target_type: Option<TargetType>,
site: bool,
) -> Result<(), failure::Error> {
if Path::new("./wrangler.toml").exists() {
failure::bail!("A wrangler.toml file already exists! Please remove it before running this command again.");
}
let dirname = get_current_dirname()?;
let name = name.unwrap_or_else(|| &dirname);
let target_type = target_type.unwrap_or_default();
Manifest::generate(name.to_string(), target_type, true)?;
let config_path = PathBuf::from("./");
let manifest = Manifest::generate(name.to_string(), target_type, config_path, site)?;
message::success("Succesfully created a `wrangler.toml`");

if site {
let env = None;
let release = false;
let target = manifest.get_target(env, release)?;
commands::build::wranglerjs::scaffold_site_worker(&target)?;
}
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion src/commands/kv/bucket/upload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub fn upload_files(
}

// Add the popped key-value pair to the running batch of key-value pair uploads
key_count = key_count + 1;
key_count += 1;
key_pair_bytes = key_pair_bytes + pair.key.len() + pair.value.len();
key_value_batch.push(pair);
}
Expand Down
11 changes: 2 additions & 9 deletions src/commands/kv/namespace/site.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,10 @@ pub fn site(target: &Target, user: &GlobalUser) -> Result<WorkersKvNamespace, fa
});

match response {
Ok(success) => {
return Ok(success.result);
}
Ok(success) => Ok(success.result),
Err(e) => match e {
ApiFailure::Error(_status, api_errors) => {
if api_errors
.errors
.iter()
.find(|&e| e.code == 10014)
.is_some()
{
if api_errors.errors.iter().any(|e| e.code == 10014) {
log::info!("Namespace {} already exists.", title);
let response = client.request(&ListNamespaces {
account_identifier: &target.account_id,
Expand Down
15 changes: 7 additions & 8 deletions src/commands/publish/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use route::Route;

use upload_form::build_script_upload_form;

use log::info;
use std::path::Path;

use crate::commands;
Expand All @@ -29,7 +28,7 @@ pub fn publish(
push_worker: bool,
push_bucket: bool,
) -> Result<(), failure::Error> {
info!("workers_dev = {}", target.workers_dev);
log::info!("workers_dev = {}", target.workers_dev);

validate_target(target)?;

Expand Down Expand Up @@ -80,14 +79,14 @@ fn publish_script(user: &GlobalUser, target: &Target) -> Result<(), failure::Err
let pattern = if !target.workers_dev {
let route = Route::new(&target)?;
Route::publish(&user, &target, &route)?;
info!("publishing to route");
log::info!("publishing to route");
route.pattern
} else {
info!("publishing to subdomain");
log::info!("publishing to subdomain");
publish_to_subdomain(target, user)?
};

info!("{}", &pattern);
log::info!("{}", &pattern);
message::success(&format!(
"Successfully published your script to {}",
&pattern
Expand All @@ -100,7 +99,7 @@ fn upload_buckets(target: &Target, user: &GlobalUser) -> Result<(), failure::Err
for namespace in &target.kv_namespaces() {
if let Some(bucket) = &namespace.bucket {
let path = Path::new(&bucket);
kv::bucket::upload(target, user.to_owned(), &namespace.id, path, false)?;
kv::bucket::sync(target, user.to_owned(), &namespace.id, path, false)?;
}
}

Expand All @@ -112,7 +111,7 @@ fn build_subdomain_request() -> String {
}

fn publish_to_subdomain(target: &Target, user: &GlobalUser) -> Result<String, failure::Error> {
info!("checking that subdomain is registered");
log::info!("checking that subdomain is registered");
let subdomain = Subdomain::get(&target.account_id, user)?;

let sd_worker_addr = format!(
Expand All @@ -122,7 +121,7 @@ fn publish_to_subdomain(target: &Target, user: &GlobalUser) -> Result<String, fa

let client = http::auth_client(user);

info!("Making public on subdomain...");
log::info!("Making public on subdomain...");
let mut res = client
.post(&sd_worker_addr)
.header("Content-type", "application/json")
Expand Down
6 changes: 3 additions & 3 deletions src/commands/publish/package.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::fs;
use std::path::{Path, PathBuf};
use std::path::PathBuf;

use serde::{self, Deserialize};

Expand All @@ -9,12 +9,12 @@ pub struct Package {
main: String,
}
impl Package {
pub fn main(&self) -> Result<String, failure::Error> {
pub fn main(&self, build_dir: &PathBuf) -> Result<String, failure::Error> {
if self.main == "" {
failure::bail!(
"The `main` key in your `package.json` file is required; please specified the entrypoint of your Worker.",
)
} else if !Path::new(&self.main).exists() {
} else if !build_dir.join(&self.main).exists() {
failure::bail!(
"The entrypoint of your Worker ({}) could not be found.",
self.main
Expand Down
2 changes: 1 addition & 1 deletion src/commands/publish/upload_form/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn build_script_upload_form(target: &Target) -> Result<Form, failure::Error>
let build_dir = target.build_dir()?;
let package = Package::new(&build_dir)?;

let script_path = package.main()?;
let script_path = package.main(&build_dir)?;

let assets = ProjectAssets::new(script_path, Vec::new(), kv_namespaces)?;

Expand Down
71 changes: 54 additions & 17 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ fn run() -> Result<(), failure::Error> {
.about("List all namespaces on your Cloudflare account")
)
)
.subcommand(SubCommand::with_name("kv:key")
.subcommand(
SubCommand::with_name("kv:key")
.about(&*format!(
"{} Individually manage Workers KV key-value pairs",
emoji::KEY
Expand Down Expand Up @@ -319,6 +320,13 @@ fn run() -> Result<(), failure::Error> {
.long("type")
.takes_value(true)
.help("the type of project you want generated"),
)
.arg(
Arg::with_name("site")
.short("s")
.long("site")
.takes_value(false)
.help("initializes a Workers Sites project. Overrides `type` and `template`"),
),
)
.subcommand(
Expand All @@ -338,6 +346,13 @@ fn run() -> Result<(), failure::Error> {
.long("type")
.takes_value(true)
.help("the type of project you want generated"),
)
.arg(
Arg::with_name("site")
.short("s")
.long("site")
.takes_value(false)
.help("initializes a Workers Sites project. Overrides `type` and `template`"),
),
)
.subcommand(
Expand Down Expand Up @@ -455,32 +470,54 @@ fn run() -> Result<(), failure::Error> {
commands::global_config(email, api_key)?;
} else if let Some(matches) = matches.subcommand_matches("generate") {
let name = matches.value_of("name").unwrap_or("worker");
let target_type = match matches.value_of("type") {
Some(s) => Some(TargetType::from_str(&s.to_lowercase())?),
None => None,
};
let site = matches.is_present("site");

let default_template = "https://github.com/cloudflare/worker-template";
let template = matches.value_of("template").unwrap_or(match target_type {
Some(ref pt) => match pt {
TargetType::Rust => "https://github.com/cloudflare/rustwasm-worker-template",
let (target_type, template) = if site {
// Workers Sites projects are always Webpack for now
let target_type = Some(TargetType::Webpack);
// template = "https://github.com/cloudflare/worker-sites-template";
// TODO: this is a placeholder template. Replace with The Real Thing (^) on launch.
let template = "https://github.com/ashleymichal/scaling-succotash";

(target_type, template)
} else {
let target_type = match matches.value_of("type") {
Some(s) => Some(TargetType::from_str(&s.to_lowercase())?),
None => None,
};

let default_template = "https://github.com/cloudflare/worker-template";
let template = matches.value_of("template").unwrap_or(match target_type {
Some(ref pt) => match pt {
TargetType::Rust => "https://github.com/cloudflare/rustwasm-worker-template",
_ => default_template,
},
_ => default_template,
},
_ => default_template,
});
});

(target_type, template)
};

info!(
"Generate command called with template {}, and name {}",
template, name
);
commands::generate(name, template, target_type)?;

commands::generate(name, template, target_type, site)?;
} else if let Some(matches) = matches.subcommand_matches("init") {
let name = matches.value_of("name");
let target_type = match matches.value_of("type") {
Some(s) => Some(settings::target::TargetType::from_str(&s.to_lowercase())?),
None => None,
let site = matches.is_present("site");
let target_type = if site {
// Workers Sites projects are always Webpack for now
Some(TargetType::Webpack)
} else {
match matches.value_of("type") {
Some(s) => Some(settings::target::TargetType::from_str(&s.to_lowercase())?),
None => None,
}
};
commands::init(name, target_type)?;

commands::init(name, target_type, site)?;
} else if let Some(matches) = matches.subcommand_matches("build") {
info!("Getting project settings");
let manifest = settings::target::Manifest::new(config_path)?;
Expand Down
Loading

0 comments on commit 5385c86

Please sign in to comment.