From 970b695b7511c01bbd0f71db2cca0da2298b08f9 Mon Sep 17 00:00:00 2001 From: sw-yx Date: Sat, 6 Apr 2019 02:19:47 -0400 Subject: [PATCH 1/4] add initial log to help perceived responsiveness --- src/commands/dev/exec.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/commands/dev/exec.js b/src/commands/dev/exec.js index b1bf1d2..dfc0bb8 100644 --- a/src/commands/dev/exec.js +++ b/src/commands/dev/exec.js @@ -8,6 +8,9 @@ class ExecCommand extends Command { async run() { const { site, api } = this.netlify; if (site.id) { + console.log( + `${NETLIFYDEV} Checking your site's environment variables...` + ); const accessToken = await this.authenticate(); const { addEnvVariables } = require("../../utils/dev"); await addEnvVariables(api, site, accessToken); From a7a3942dc77d891ee8d17ec08c5223592eacfae0 Mon Sep 17 00:00:00 2001 From: sw-yx Date: Sat, 6 Apr 2019 02:53:19 -0400 Subject: [PATCH 2/4] add netlify dev chalk brand and reuse accessToken for speed --- src/commands/dev/exec.js | 2 +- src/commands/dev/index.js | 6 ++--- src/commands/functions/build.js | 14 +++++++---- src/commands/functions/create.js | 40 ++++++++++++++++++-------------- src/commands/functions/serve.js | 4 +++- src/commands/functions/update.js | 4 +++- src/live-tunnel.js | 6 +++-- src/utils/dev.js | 4 ++-- 8 files changed, 47 insertions(+), 33 deletions(-) diff --git a/src/commands/dev/exec.js b/src/commands/dev/exec.js index dfc0bb8..3053a32 100644 --- a/src/commands/dev/exec.js +++ b/src/commands/dev/exec.js @@ -11,7 +11,7 @@ class ExecCommand extends Command { console.log( `${NETLIFYDEV} Checking your site's environment variables...` ); - const accessToken = await this.authenticate(); + const accessToken = api.accessToken; const { addEnvVariables } = require("../../utils/dev"); await addEnvVariables(api, site, accessToken); } else { diff --git a/src/commands/dev/index.js b/src/commands/dev/index.js index 55de465..25e14a1 100644 --- a/src/commands/dev/index.js +++ b/src/commands/dev/index.js @@ -170,6 +170,7 @@ function startDevServer(settings, log, error) { class DevCommand extends Command { async run() { + this.log(`${NETLIFYDEV} Starting Netlify Dev...`); const { flags, args } = this.parse(DevCommand); const { api, site, config } = this.netlify; const functionsDir = @@ -180,7 +181,6 @@ class DevCommand extends Command { let accessToken = api.accessToken; if (site.id && !flags.offline) { - accessToken = await this.authenticate(); const { addEnvVariables } = require("../../utils/dev"); addonUrls = await addEnvVariables(api, site, accessToken); } @@ -189,7 +189,7 @@ class DevCommand extends Command { let settings = serverSettings(config.dev); if (!(settings && settings.command)) { this.log( - "[Netlify Dev] No dev server detected, using simple static server" + `${NETLIFYDEV} No dev server detected, using simple static server` ); const dist = (config.dev && config.dev.publish) || @@ -240,7 +240,7 @@ class DevCommand extends Command { live: flags.live || false }); - const banner = chalk.bold(`Netlify Dev Server now ready on ${url}`); + const banner = chalk.bold(`${NETLIFYDEV} Server now ready on ${url}`); this.log( boxen(banner, { padding: 1, diff --git a/src/commands/functions/build.js b/src/commands/functions/build.js index d613ac5..04e8c3a 100644 --- a/src/commands/functions/build.js +++ b/src/commands/functions/build.js @@ -2,6 +2,8 @@ const fs = require("fs"); const { flags } = require("@oclif/command"); const Command = require("@netlify/cli-utils"); const { zipFunctions } = require("@netlify/zip-it-and-ship-it"); +const chalk = require("chalk"); +const NETLIFYDEV = `[${chalk.cyan("Netlify Dev")}]`; class FunctionsBuildCommand extends Command { async run() { @@ -12,27 +14,29 @@ class FunctionsBuildCommand extends Command { const dst = flags.functions || config.build.functions; if (src === dst) { - this.log("Source and destination for function build can't be the same"); + this.log( + `${NETLIFYDEV} Source and destination for function build can't be the same` + ); process.exit(1); } if (!src || !dst) { if (!src) this.log( - "You must specify a source folder with a --src flag or a functionsSource field in your config" + `${NETLIFYDEV} Error: You must specify a source folder with a --src flag or a functionsSource field in your config` ); if (!dst) this.log( - "You must specify a destination functions folder with a --functions flag or a functions field in your config" + `${NETLIFYDEV} Error: You must specify a destination functions folder with a --functions flag or a functions field in your config` ); process.exit(1); } fs.mkdirSync(dst, { recursive: true }); - this.log("Building functions"); + this.log(`${NETLIFYDEV} Building functions`); zipFunctions(src, dst, { skipGo: true }); - this.log("Functions built to ", dst); + this.log(`${NETLIFYDEV} Functions built to `, dst); } } diff --git a/src/commands/functions/create.js b/src/commands/functions/create.js index e7846e7..d67397d 100644 --- a/src/commands/functions/create.js +++ b/src/commands/functions/create.js @@ -12,6 +12,8 @@ const cp = require("child_process"); const { createAddon } = require("netlify/src/addons"); const ora = require("ora"); const { track } = require("@netlify/cli-utils/src/utils/telemetry"); +const chalk = require("chalk"); +const NETLIFYDEV = `[${chalk.cyan("Netlify Dev")}]`; const templatesDir = path.resolve(__dirname, "../../functions-templates"); @@ -161,7 +163,6 @@ async function pickTemplate() { const filteredTemplateNames = filteredTemplates.map(x => input ? x.string : x ); - // console.log({ filteredTemplateNames }) return registry .filter(t => filteredTemplateNames.includes(t.name + t.description)) .map(t => { @@ -203,15 +204,17 @@ function ensureFunctionDirExists(flags, config) { const functionsDir = flags.functions || (config.build && config.build.functions); if (!functionsDir) { - this.log("No functions folder specified in netlify.toml or as an argument"); + this.log( + `${NETLIFYDEV} No functions folder specified in netlify.toml or as an argument` + ); process.exit(1); } if (!fs.existsSync(functionsDir)) { this.log( - `functions folder ${functionsDir} specified in netlify.toml but folder not found, creating it...` + `${NETLIFYDEV} functions folder ${functionsDir} specified in netlify.toml but folder not found, creating it...` ); fs.mkdirSync(functionsDir); - this.log(`functions folder ${functionsDir} created`); + this.log(`${NETLIFYDEV} functions folder ${functionsDir} created`); } return functionsDir; } @@ -227,7 +230,7 @@ async function downloadFromURL(flags, args, functionsDir) { fs.lstatSync(fnFolder + ".js").isFile() ) { this.log( - `A single file version of the function ${name} already exists at ${fnFolder}.js` + `${NETLIFYDEV} Warning: A single file version of the function ${name} already exists at ${fnFolder}.js. Terminating without further action.` ); process.exit(1); } @@ -254,9 +257,11 @@ async function downloadFromURL(flags, args, functionsDir) { }) ); - this.log(`installing dependencies for ${nameToUse}...`); + this.log(`${NETLIFYDEV} Installing dependencies for ${nameToUse}...`); cp.exec("npm i", { cwd: path.join(functionsDir, nameToUse) }, () => { - this.log(`installing dependencies for ${nameToUse} complete `); + this.log( + `${NETLIFYDEV} Installing dependencies for ${nameToUse} complete ` + ); }); // read, execute, and delete function template file if exists @@ -296,16 +301,13 @@ async function scaffoldFromTemplate(flags, args, functionsDir) { try { await downloadFromURL.call(this, flags, args, functionsDir); } catch (err) { - console.error("Error downloading from URL: " + flags.url); + console.error(`${NETLIFYDEV} Error downloading from URL: ` + flags.url); console.error(err); process.exit(1); } } else if (chosentemplate === "report") { console.log( - "opening in browser: https://github.com/netlify/netlify-dev-plugin/issues/new" - ); - require("../../utils/openBrowser.js")( - "https://github.com/netlify/netlify-dev-plugin/issues/new" + `${NETLIFYDEV} Open in browser: https://github.com/netlify/netlify-dev-plugin/issues/new` ); } else { const { @@ -323,7 +325,7 @@ async function scaffoldFromTemplate(flags, args, functionsDir) { } const name = await getNameFromArgs(args, flags, templateName); - this.log(`Creating function ${name}`); + this.log(`${NETLIFYDEV} Creating function ${name}`); const functionPath = ensureFunctionPathIsOk.call( this, functionsDir, @@ -338,7 +340,7 @@ async function scaffoldFromTemplate(flags, args, functionsDir) { copy(pathToTemplate, functionPath, vars, async (err, createdFiles) => { if (err) throw err; createdFiles.forEach(filePath => { - this.log(`Created ${filePath}`); + this.log(`${NETLIFYDEV} Created ${filePath}`); require("fs").chmodSync(path.resolve(filePath), 0o777); if (filePath.includes("package.json")) hasPackageJSON = true; }); @@ -377,12 +379,12 @@ async function installAddons(addons = [], fnPath) { ); return false; } - console.log("checking Netlify APIs..."); + console.log(`${NETLIFYDEV} checking Netlify APIs...`); return api.getSite({ siteId }).then(async siteData => { - const accessToken = await this.authenticate(); + const accessToken = api.accessToken; const arr = addons.map(({ addonName, addonDidInstall }) => { - console.log("installing addon: " + addonName); + console.log(`${NETLIFYDEV} installing addon: ` + addonName); // will prompt for configs if not supplied - we do not yet allow for addon configs supplied by `netlify functions:create` command and may never do so return createSiteAddon( accessToken, @@ -423,7 +425,9 @@ async function installAddons(addons = [], fnPath) { function ensureFunctionPathIsOk(functionsDir, flags, name) { const functionPath = path.join(functionsDir, name); if (fs.existsSync(functionPath)) { - this.log(`Function ${functionPath} already exists, cancelling...`); + this.log( + `${NETLIFYDEV} Function ${functionPath} already exists, cancelling...` + ); process.exit(1); } return functionPath; diff --git a/src/commands/functions/serve.js b/src/commands/functions/serve.js index 55f4e88..8c82ee2 100644 --- a/src/commands/functions/serve.js +++ b/src/commands/functions/serve.js @@ -1,8 +1,10 @@ const { Command, flags } = require("@oclif/command"); +const chalk = require("chalk"); +const NETLIFYDEV = `[${chalk.cyan("Netlify Dev")}]`; class FunctionsServeCommand extends Command { async run() { - this.log(`serve a function`); + this.log(`${NETLIFYDEV} NOT IMPLEMENTED YET: serve a function`); } } diff --git a/src/commands/functions/update.js b/src/commands/functions/update.js index 0ef4202..ce91812 100644 --- a/src/commands/functions/update.js +++ b/src/commands/functions/update.js @@ -1,8 +1,10 @@ const { Command, flags } = require("@oclif/command"); +const chalk = require("chalk"); +const NETLIFYDEV = `[${chalk.cyan("Netlify Dev")}]`; class FunctionsUpdateCommand extends Command { async run() { - this.log(`update a function`); + this.log(`${NETLIFYDEV} NOT IMPLEMENTED YET: update a function`); } } diff --git a/src/live-tunnel.js b/src/live-tunnel.js index 2a780e3..cdd5f26 100644 --- a/src/live-tunnel.js +++ b/src/live-tunnel.js @@ -4,6 +4,8 @@ const os = require("os"); const path = require("path"); const execa = require("execa"); const { fetchLatest, updateAvailable } = require("gh-release-fetch"); +const chalk = require("chalk"); +const NETLIFYDEV = `[${chalk.cyan("Netlify Dev")}]`; async function createTunnel(siteId, netlifyApiToken, log) { await installTunnelClient(log); @@ -14,7 +16,7 @@ async function createTunnel(siteId, netlifyApiToken, log) { ); process.exit(1); } - log("Creating Live Tunnel for " + siteId); + log(`${NETLIFYDEV} Creating Live Tunnel for ` + siteId); const url = `https://api.netlify.com/api/v1/live_sessions?site_id=${siteId}`; const response = await fetch(url, { @@ -71,7 +73,7 @@ async function installTunnelClient(log) { return; } - log("Installing Live Tunnel Client"); + log(`${NETLIFYDEV} Installing Live Tunnel Client`); const win = isWindows(); const platform = win ? "windows" : process.platform; diff --git a/src/utils/dev.js b/src/utils/dev.js index 830f4f0..b2fe437 100644 --- a/src/utils/dev.js +++ b/src/utils/dev.js @@ -9,9 +9,9 @@ const NETLIFYDEV = `[${chalk.cyan("Netlify Dev")}]`; * * ``` * // usage example - * const { site } = this.netlify + * const { site, api } = this.netlify * if (site.id) { - * const accessToken = await this.authenticate() + * const accessToken = api.accessToken * const addonUrls = await addEnvVariables(site, accessToken) * // addonUrls is only for startProxy in netlify dev:index * } From c45c694feaee02188a46a44ceaa5a369e2174a06 Mon Sep 17 00:00:00 2001 From: sw-yx Date: Sat, 6 Apr 2019 03:27:17 -0400 Subject: [PATCH 3/4] add notes on readme --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ca66182..2c299f3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Netlify CLI plugin for local dev experience. ## What is Netlify Dev? -Netlify Dev brings the power of Netlify's Edge Logic layer, serverless functions and [add-on ecosystem](#using-add-ons) to your local laptop. It runs Netlify's production routing engine in a local dev server to make all redirects, proxy rules, function routes or add-on routes available locally and injects the correct environment variables from your site environment, installed add-ons or your netlify.toml file into your build and function environment. +Netlify Dev brings the power of Netlify's Edge Logic layer, [serverless functions](#netlify-functions) and [add-on ecosystem](#using-add-ons) to your local laptop. It runs Netlify's production routing engine in a local dev server to make all redirects, proxy rules, function routes or add-on routes available locally and injects the correct environment variables from your site environment, installed add-ons or your netlify.toml file into your build and function environment. It automatically detects common tools like Gatsby, Hugo, React Static, Eleventy, and more, to give a zero config setup for your local dev server and can help scaffolding new functions as you work on them. @@ -14,6 +14,17 @@ It automatically detects common tools like Gatsby, Hugo, React Static, Eleventy, - `netlify dev:exec ` runs a shell command within the netlify dev environment - `netlify functions:create` bootstrap a new function +As these commands are expected to be frequently used, it may be helpful to define aliases in your terminal (Mac: [bash](https://jonsuh.com/blog/bash-command-line-shortcuts/), [zsh](https://askubuntu.com/questions/758496/how-to-make-a-permanent-alias-in-oh-my-zsh), Windows: [doskey](https://stackoverflow.com/questions/20530996/aliases-in-windows-command-prompt), [registry](https://stackoverflow.com/questions/20530996/aliases-in-windows-command-prompt)) to your personal preference. For example: + +``` +## ~/.zshrc +alias ndeploy="netlify deploy --prod" +alias nd="netlify dev" +alias ndl="netlify dev --live" +alias nfc="netlify functions:create" +alias ndx="netlify dev:exec " +``` + ## Using the beta Currently the Netlify dev plugin is in private beta. You'll need to follow these steps to enable it: From 7b23aef4afe543d2349c1ab721b3b27b11d10cdb Mon Sep 17 00:00:00 2001 From: sw-yx Date: Sat, 6 Apr 2019 13:20:42 -0400 Subject: [PATCH 4/4] slight tweak to readme --- README.md | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2c299f3..4167be3 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,19 @@ Netlify CLI plugin for local dev experience. ## What is Netlify Dev? -Netlify Dev brings the power of Netlify's Edge Logic layer, [serverless functions](#netlify-functions) and [add-on ecosystem](#using-add-ons) to your local laptop. It runs Netlify's production routing engine in a local dev server to make all redirects, proxy rules, function routes or add-on routes available locally and injects the correct environment variables from your site environment, installed add-ons or your netlify.toml file into your build and function environment. +Netlify Dev brings the power of Netlify's Edge Logic layer, [serverless functions](#netlify-functions) and [add-on ecosystem](#using-add-ons) to your local machine. It runs Netlify's production routing engine in a local dev server to make all redirects, proxy rules, function routes or add-on routes available locally and injects the correct environment variables from your site environment, installed add-ons or your netlify.toml file into your build and function environment. It automatically detects common tools like Gatsby, Hugo, React Static, Eleventy, and more, to give a zero config setup for your local dev server and can help scaffolding new functions as you work on them. +## Prerequisites + +There are just two: + +- You should be [logged in on Netlify CLI](https://www.netlify.com/docs/cli/#authentication) +- Your project should be linked to a `siteID` on Netlify (using [netlify init](https://www.netlify.com/docs/cli/#continuous-deployment) or [netlify link](https://www.netlify.com/docs/cli/#linking-and-unlinking-sites)). You can confirm this has been done if you have a `.netlify` folder with a `state.json` file containing your `siteID`. + +This is how we pull down your build environment variables and manage your addons on your local machine. + ## Usage - `netlify dev` start a local dev server for the build tool you're using @@ -16,7 +25,7 @@ It automatically detects common tools like Gatsby, Hugo, React Static, Eleventy, As these commands are expected to be frequently used, it may be helpful to define aliases in your terminal (Mac: [bash](https://jonsuh.com/blog/bash-command-line-shortcuts/), [zsh](https://askubuntu.com/questions/758496/how-to-make-a-permanent-alias-in-oh-my-zsh), Windows: [doskey](https://stackoverflow.com/questions/20530996/aliases-in-windows-command-prompt), [registry](https://stackoverflow.com/questions/20530996/aliases-in-windows-command-prompt)) to your personal preference. For example: -``` +```bash ## ~/.zshrc alias ndeploy="netlify deploy --prod" alias nd="netlify dev" @@ -31,13 +40,13 @@ Currently the Netlify dev plugin is in private beta. You'll need to follow these Make sure Netlify CLI is installed and up to date: -``` +```bash npm install -g netlify-cli ``` Then clone and activate the plugin: -``` +```bash git clone git@github.com:netlify/netlify-dev-plugin.git cd netlify-dev-plugin npm install @@ -172,7 +181,7 @@ Add-ons are a way for Netlify users to extend the functionality of their Jamstac To try out an add-on with Netlify dev, run the `netlify addons:create` command: -``` +```bash netlify addons:create fauna ``` @@ -186,8 +195,10 @@ After you have installed an add-on, it will be visible with the `netlify addons: To share your ongoing dev session with a coworker, just run Netlify Dev with a `--live` flag: -``` +```bash netlify dev --live ``` You will get a URL that looks like `https://clever-cray-2aa156-6639f3.netlify.live/`. This can be accessed by anyone as long as you keep your session open. + +> Note: there are currently known issues with ending the live session alongside your webdevserver. We are working on fixing it. In the mean time you can run `ps aux | grep live-tunnel` and kill these sessions manually.