-
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
47 changed files
with
2,173 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// @ts-check | ||
|
||
const { getTsconfigPath } = require("@strangelovelabs/style-guide/eslint/helpers"); | ||
|
||
/** @type {import("eslint").Linter.Config} */ | ||
const eslintConfig = { | ||
extends: [ | ||
require.resolve("@strangelovelabs/style-guide/eslint/browser-node"), | ||
require.resolve("@strangelovelabs/style-guide/eslint/typescript"), | ||
], | ||
ignorePatterns: [".next", "node_modules", "out"], | ||
parserOptions: { | ||
project: getTsconfigPath(), | ||
}, | ||
root: true, | ||
}; | ||
|
||
module.exports = eslintConfig; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/dist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import retry from "async-retry"; | ||
import chalk from "chalk"; | ||
import path from "path"; | ||
|
||
import type { PackageManager } from "./helpers/get-pkg-manager"; | ||
import { tryGitInit } from "./helpers/git"; | ||
import { install } from "./helpers/install"; | ||
import { isFolderEmpty } from "./helpers/is-folder-empty"; | ||
import { getOnline } from "./helpers/is-online"; | ||
import { isWriteable } from "./helpers/is-writeable"; | ||
import { makeDir } from "./helpers/make-dir"; | ||
import type { RepoInfo } from "./helpers/repo"; | ||
import { downloadAndExtractRepo } from "./helpers/repo"; | ||
|
||
export class DownloadError extends Error {} | ||
|
||
export async function createApp({ | ||
appPath, | ||
packageManager, | ||
}: { | ||
appPath: string; | ||
packageManager: PackageManager; | ||
}): Promise<void> { | ||
const repo: RepoInfo = { | ||
username: "strangelove-ventures", | ||
branch: "dev", | ||
name: "graz", | ||
filePath: "templates/default", | ||
}; | ||
|
||
const root = path.resolve(appPath); | ||
|
||
if (!(await isWriteable(path.dirname(root)))) { | ||
console.error("The application path is not writable, please check folder permissions and try again."); | ||
console.error("It is likely you do not have write permissions for this folder."); | ||
process.exit(1); | ||
} | ||
|
||
const appName = path.basename(root); | ||
|
||
await makeDir(root); | ||
if (!isFolderEmpty(root, appName)) { | ||
process.exit(1); | ||
} | ||
|
||
const useYarn = packageManager === "yarn"; | ||
const isOnline = !useYarn || (await getOnline()); | ||
const originalDirectory = process.cwd(); | ||
|
||
console.log(`Creating a cosmos frontend in ${chalk.green(root)}.`); | ||
console.log(); | ||
|
||
process.chdir(root); | ||
|
||
try { | ||
console.log(`Downloading files from repo. This might take a moment.`); | ||
console.log(); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call | ||
await retry(() => downloadAndExtractRepo(root, repo), { | ||
retries: 3, | ||
}); | ||
} catch (reason) { | ||
// eslint-disable-next-line no-inner-declarations | ||
function isErrorLike(err: unknown): err is { message: string } { | ||
return typeof err === "object" && err !== null && typeof (err as { message?: unknown }).message === "string"; | ||
} | ||
|
||
throw new DownloadError(isErrorLike(reason) ? reason.message : `${reason}`); | ||
} | ||
console.log("Installing packages. This might take a couple of minutes."); | ||
console.log(); | ||
await install(root, null, { packageManager, isOnline }); | ||
|
||
if (tryGitInit(root)) { | ||
console.log("Initialized a git repository."); | ||
console.log(); | ||
} | ||
|
||
let cdpath: string; | ||
if (path.join(originalDirectory, appName) === appPath) { | ||
cdpath = appName; | ||
} else { | ||
cdpath = appPath; | ||
} | ||
|
||
console.log(`${chalk.green("Success!")} Created ${appName} at ${appPath}`); | ||
|
||
console.log("Inside that directory, you can run several commands:"); | ||
console.log(); | ||
console.log(chalk.cyan(` ${packageManager} ${useYarn ? "" : "run "}dev`)); | ||
console.log(" Starts the development server."); | ||
console.log(); | ||
console.log(chalk.cyan(` ${packageManager} ${useYarn ? "" : "run "}build`)); | ||
console.log(" Builds the app for production."); | ||
console.log(); | ||
console.log(chalk.cyan(` ${packageManager} start`)); | ||
console.log(" Runs the built app in production mode."); | ||
console.log(); | ||
console.log("We suggest that you begin by typing:"); | ||
console.log(); | ||
console.log(chalk.cyan(" cd"), cdpath); | ||
console.log(` ${chalk.cyan(`${packageManager} ${useYarn ? "" : "run "}dev`)}`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { execSync } from "child_process"; | ||
|
||
export type PackageManager = "npm" | "pnpm" | "yarn"; | ||
|
||
export function getPkgManager(): PackageManager { | ||
try { | ||
const userAgent = process.env.npm_config_user_agent; | ||
if (userAgent) { | ||
if (userAgent.startsWith("yarn")) { | ||
return "yarn"; | ||
} else if (userAgent.startsWith("pnpm")) { | ||
return "pnpm"; | ||
} | ||
} | ||
try { | ||
execSync("yarn --version", { stdio: "ignore" }); | ||
return "yarn"; | ||
} catch { | ||
execSync("pnpm --version", { stdio: "ignore" }); | ||
return "pnpm"; | ||
} | ||
} catch { | ||
return "npm"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { execSync } from "child_process"; | ||
import path from "path"; | ||
import rimraf from "rimraf"; | ||
|
||
function isInGitRepository(): boolean { | ||
try { | ||
execSync("git rev-parse --is-inside-work-tree", { stdio: "ignore" }); | ||
return true; | ||
} catch (_) { | ||
return false; | ||
} | ||
} | ||
function isInMercurialRepository(): boolean { | ||
try { | ||
execSync("hg --cwd . root", { stdio: "ignore" }); | ||
return true; | ||
} catch (_) { | ||
return false; | ||
} | ||
} | ||
|
||
export function tryGitInit(root: string): boolean { | ||
let didInit = false; | ||
try { | ||
execSync("git --version", { stdio: "ignore" }); | ||
if (isInGitRepository() || isInMercurialRepository()) { | ||
return false; | ||
} | ||
|
||
execSync("git init", { stdio: "ignore" }); | ||
didInit = true; | ||
|
||
execSync("git checkout -b main", { stdio: "ignore" }); | ||
|
||
execSync("git add -A", { stdio: "ignore" }); | ||
|
||
// execSync('git commit -m "Initial commit from create-graz-app"', { | ||
// stdio: "ignore", | ||
// }); | ||
return true; | ||
} catch (e) { | ||
if (didInit) { | ||
try { | ||
rimraf.sync(path.join(root, ".git")); | ||
} catch (_) { | ||
return false; | ||
} | ||
} | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import chalk from "chalk"; | ||
import spawn from "cross-spawn"; | ||
|
||
import type { PackageManager } from "./get-pkg-manager"; | ||
|
||
interface InstallArgs { | ||
/** | ||
* Indicate whether to install packages using npm, pnpm or Yarn. | ||
*/ | ||
packageManager: PackageManager; | ||
/** | ||
* Indicate whether there is an active Internet connection. | ||
*/ | ||
isOnline: boolean; | ||
/** | ||
* Indicate whether the given dependencies are devDependencies. | ||
*/ | ||
devDependencies?: boolean; | ||
} | ||
|
||
/** | ||
* Spawn a package manager installation with either Yarn or NPM. | ||
* | ||
* @returns A Promise that resolves once the installation is finished. | ||
*/ | ||
export function install( | ||
root: string, | ||
dependencies: string[] | null, | ||
{ packageManager, isOnline, devDependencies }: InstallArgs, | ||
): Promise<void> { | ||
/** | ||
* (p)npm-specific command-line flags. | ||
*/ | ||
const npmFlags: string[] = []; | ||
/** | ||
* Yarn-specific command-line flags. | ||
*/ | ||
const yarnFlags: string[] = []; | ||
/** | ||
* Return a Promise that resolves once the installation is finished. | ||
*/ | ||
return new Promise((resolve, reject) => { | ||
let args: string[]; | ||
const command = packageManager; | ||
const useYarn = packageManager === "yarn"; | ||
|
||
if (dependencies?.length) { | ||
/** | ||
* If there are dependencies, run a variation of `{packageManager} add`. | ||
*/ | ||
if (useYarn) { | ||
/** | ||
* Call `yarn add --exact (--offline)? (-D)? ...`. | ||
*/ | ||
args = ["add", "--exact"]; | ||
if (!isOnline) args.push("--offline"); | ||
args.push("--cwd", root); | ||
if (devDependencies) args.push("--dev"); | ||
args.push(...dependencies); | ||
} else { | ||
/** | ||
* Call `(p)npm install [--save|--save-dev] ...`. | ||
*/ | ||
args = ["install", "--save-exact"]; | ||
args.push(devDependencies ? "--save-dev" : "--save"); | ||
args.push(...dependencies); | ||
} | ||
} else { | ||
/** | ||
* If there are no dependencies, run a variation of `{packageManager} install`. | ||
*/ | ||
args = ["install"]; | ||
if (!isOnline) { | ||
console.log(chalk.yellow("You appear to be offline.")); | ||
if (useYarn) { | ||
console.log(chalk.yellow("Falling back to the local Yarn cache.")); | ||
console.log(); | ||
args.push("--offline"); | ||
} else { | ||
console.log(); | ||
} | ||
} | ||
} | ||
/** | ||
* Add any package manager-specific flags. | ||
*/ | ||
if (useYarn) { | ||
args.push(...yarnFlags); | ||
} else { | ||
args.push(...npmFlags); | ||
} | ||
/** | ||
* Spawn the installation process. | ||
*/ | ||
const child = spawn(command, args, { | ||
stdio: "inherit", | ||
env: { | ||
...process.env, | ||
ADBLOCK: "1", | ||
// we set NODE_ENV to development as pnpm skips dev | ||
// dependencies when production | ||
NODE_ENV: "development", | ||
DISABLE_OPENCOLLECTIVE: "1", | ||
}, | ||
}); | ||
child.on("close", (code) => { | ||
if (code !== 0) { | ||
// eslint-disable-next-line prefer-promise-reject-errors | ||
reject({ command: `${command} ${args.join(" ")}` }); | ||
return; | ||
} | ||
resolve(); | ||
}); | ||
}); | ||
} |
Oops, something went wrong.