Skip to content

Commit

Permalink
Move installer package to nextjs/packages (#3044)
Browse files Browse the repository at this point in the history
(patch)
  • Loading branch information
beerose authored Dec 10, 2021
1 parent d05f00c commit 5f1c6a4
Show file tree
Hide file tree
Showing 92 changed files with 2,716 additions and 1,019 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,33 @@ jobs:
env:
CI: true

testNextPackages:
name: Next - Test Packages
defaults:
run:
working-directory: nextjs
needs: build-linux
runs-on: ubuntu-latest
env:
BLITZ_TELEMETRY_DISABLED: 1
steps:
- uses: actions/cache@v2
id: restore-build
with:
path: ./*
key: ${{ runner.os }}-${{ github.sha }}
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: "14"
- name: Setup kernel to increase watchers
if: runner.os == 'Linux'
run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
- name: Test Next Packages
run: yarn testonly:packages
env:
CI: true

testBlitzExamples:
timeout-minutes: 30
name: Blitz - Test Example Apps (ubuntu-latest)
Expand Down Expand Up @@ -378,6 +405,7 @@ jobs:
testIntegrationBlitzWin,
testUnit,
testBlitzPackages,
testNextPackages,
testBlitzExamples,
testBlitzExamplesWin,
]
Expand Down
2 changes: 2 additions & 0 deletions nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"dev": "lerna run dev --stream --parallel",
"dev2": "while true; do yarn --check-files && yarn dev; done",
"testonly": "jest --runInBand",
"testonly:packages": "ultra -r --filter \"packages/*\" --concurrency 15 test",
"testheadless": "cross-env HEADLESS=true yarn testonly",
"testsafari": "cross-env BROWSER_NAME=safari yarn testonly",
"testfirefox": "cross-env BROWSER_NAME=firefox yarn testonly",
Expand Down Expand Up @@ -145,6 +146,7 @@
"taskr": "1.1.0",
"tree-kill": "1.2.2",
"typescript": "4.5.2",
"ultra-runner": "3.10.5",
"wait-port": "0.2.2",
"web-streams-polyfill": "2.1.1",
"webpack-bundle-analyzer": "4.3.0",
Expand Down
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions nextjs/packages/installer/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
preset: '../../../jest-unit.config.js',
}
File renamed without changes.
File renamed without changes.
12 changes: 12 additions & 0 deletions nextjs/packages/installer/src/components/enter-to-continue.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Text } from 'ink'
import * as React from 'react'
import { Newline } from './newline'

export const EnterToContinue: React.FC<{ message?: string }> = ({
message = 'Press ENTER to continue',
}) => (
<>
<Newline />
<Text bold>{message}</Text>
</>
)
6 changes: 6 additions & 0 deletions nextjs/packages/installer/src/components/newline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Box } from 'ink'
import * as React from 'react'

export const Newline: React.FC<{ count?: number }> = ({ count = 1 }) => {
return <Box paddingBottom={count} />
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import {spawn} from "cross-spawn"
import * as fs from "fs-extra"
import {Box, Text} from "ink"
import Spinner from "ink-spinner"
import * as path from "path"
import * as React from "react"
import {Newline} from "../components/newline"
import {RecipeCLIArgs} from "../types"
import {useEnterToContinue} from "../utils/use-enter-to-continue"
import {useUserInput} from "../utils/use-user-input"
import {Executor, executorArgument, ExecutorConfig, getExecutorArgument} from "./executor"
import { spawn } from 'cross-spawn'
import * as fs from 'fs-extra'
import { Box, Text } from 'ink'
import Spinner from 'ink-spinner'
import * as path from 'path'
import * as React from 'react'
import { Newline } from '../components/newline'
import { RecipeCLIArgs } from '../types'
import { useEnterToContinue } from '../utils/use-enter-to-continue'
import { useUserInput } from '../utils/use-user-input'
import {
Executor,
executorArgument,
ExecutorConfig,
getExecutorArgument,
} from './executor'

interface NpmPackage {
name: string
Expand All @@ -22,24 +27,26 @@ export interface Config extends ExecutorConfig {
packages: executorArgument<NpmPackage[]>
}

export function isAddDependencyExecutor(executor: ExecutorConfig): executor is Config {
export function isAddDependencyExecutor(
executor: ExecutorConfig
): executor is Config {
return (executor as Config).packages !== undefined
}

export const type = "add-dependency"
export const type = 'add-dependency'

function Package({pkg, loading}: {pkg: NpmPackage; loading: boolean}) {
function Package({ pkg, loading }: { pkg: NpmPackage; loading: boolean }) {
return (
<Text>
{` `}
{loading ? <Spinner /> : "📦"}
{loading ? <Spinner /> : '📦'}
{` ${pkg.name}@${pkg.version}`}
</Text>
)
}

const DependencyList = ({
lede = "Hang tight! Installing dependencies...",
lede = 'Hang tight! Installing dependencies...',
depsLoading = false,
devDepsLoading = false,
packages,
Expand All @@ -60,7 +67,9 @@ const DependencyList = ({
<Package key={pkg.name} pkg={pkg} loading={depsLoading} />
))}
<Newline />
{devPackages.length ? <Text>Dev Dependencies to be installed:</Text> : null}
{devPackages.length ? (
<Text>Dev Dependencies to be installed:</Text>
) : null}
{devPackages.map((pkg) => (
<Package key={pkg.name} pkg={pkg} loading={devDepsLoading} />
))}
Expand All @@ -72,51 +81,57 @@ const DependencyList = ({
* Exported for unit testing purposes
*/
export function getPackageManager() {
if (fs.existsSync(path.resolve("yarn.lock"))) {
return "yarn"
if (fs.existsSync(path.resolve('yarn.lock'))) {
return 'yarn'
}
return "npm"
return 'npm'
}

/**
* Exported for unit testing purposes
*/
export async function installPackages(packages: NpmPackage[], isDev = false) {
const packageManager = getPackageManager()
const isNPM = packageManager === "npm"
const pkgInstallArg = isNPM ? "install" : "add"
const isNPM = packageManager === 'npm'
const pkgInstallArg = isNPM ? 'install' : 'add'
const args: string[] = [pkgInstallArg]

if (isDev) {
args.push(isNPM ? "--save-dev" : "-D")
args.push(isNPM ? '--save-dev' : '-D')
}
packages.forEach((pkg) => {
pkg.version ? args.push(`${pkg.name}@${pkg.version}`) : args.push(pkg.name)
})
await new Promise((resolve) => {
const cp = spawn(packageManager, args, {
stdio: ["inherit", "pipe", "pipe"],
stdio: ['inherit', 'pipe', 'pipe'],
})
cp.on("exit", resolve)
cp.on('exit', resolve)
})
}

export const Commit: Executor["Commit"] = ({cliArgs, cliFlags, step, onChangeCommitted}) => {
export const Commit: Executor['Commit'] = ({
cliArgs,
cliFlags,
step,
onChangeCommitted,
}) => {
const userInput = useUserInput(cliFlags)
const [depsInstalled, setDepsInstalled] = React.useState(false)
const [devDepsInstalled, setDevDepsInstalled] = React.useState(false)

const handleChangeCommitted = React.useCallback(() => {
const packages = (step as Config).packages
const dependencies = packages.length === 1 ? "dependency" : "dependencies"
const dependencies = packages.length === 1 ? 'dependency' : 'dependencies'
onChangeCommitted(`Installed ${packages.length} ${dependencies}`)
}, [onChangeCommitted, step])

React.useEffect(() => {
async function installDeps() {
const packagesToInstall = getExecutorArgument((step as Config).packages, cliArgs).filter(
(p) => !p.isDevDep,
)
const packagesToInstall = getExecutorArgument(
(step as Config).packages,
cliArgs
).filter((p) => !p.isDevDep)
await installPackages(packagesToInstall)
setDepsInstalled(true)
}
Expand All @@ -127,9 +142,10 @@ export const Commit: Executor["Commit"] = ({cliArgs, cliFlags, step, onChangeCom
React.useEffect(() => {
if (!depsInstalled) return
async function installDevDeps() {
const packagesToInstall = getExecutorArgument((step as Config).packages, cliArgs).filter(
(p) => p.isDevDep,
)
const packagesToInstall = getExecutorArgument(
(step as Config).packages,
cliArgs
).filter((p) => p.isDevDep)
await installPackages(packagesToInstall, true)
setDevDepsInstalled(true)
}
Expand Down Expand Up @@ -186,7 +202,12 @@ const CommitWithInput = ({
)
}

const CommitWithoutInput = ({depsInstalled, devDepsInstalled, step, cliArgs}: CommitChildProps) => (
const CommitWithoutInput = ({
depsInstalled,
devDepsInstalled,
step,
cliArgs,
}: CommitChildProps) => (
<DependencyList
depsLoading={!depsInstalled}
devDepsLoading={!devDepsInstalled}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Box, Text} from "ink"
import * as React from "react"
import {Newline} from "../components/newline"
import {RecipeCLIArgs, RecipeCLIFlags} from "../types"
import { Box, Text } from 'ink'
import * as React from 'react'
import { Newline } from '../components/newline'
import { RecipeCLIArgs, RecipeCLIFlags } from '../types'

export interface ExecutorConfig {
successIcon?: string
Expand Down Expand Up @@ -32,16 +32,16 @@ export interface Executor {
type dynamicExecutorArgument<T> = (cliArgs: RecipeCLIArgs) => T

function isDynamicExecutorArgument<T>(
input: executorArgument<T>,
input: executorArgument<T>
): input is dynamicExecutorArgument<T> {
return typeof (input as dynamicExecutorArgument<T>) === "function"
return typeof (input as dynamicExecutorArgument<T>) === 'function'
}

export type executorArgument<T> = T | dynamicExecutorArgument<T>

export function Frontmatter({executor}: {executor: ExecutorConfig}) {
export function Frontmatter({ executor }: { executor: ExecutorConfig }) {
const lineLength = executor.stepName.length + 6
const verticalBorder = `+${new Array(lineLength).fill("–").join("")}+`
const verticalBorder = `+${new Array(lineLength).fill('–').join('')}+`
return (
<Box flexDirection="column" paddingBottom={1}>
<Newline />
Expand All @@ -63,7 +63,10 @@ export function Frontmatter({executor}: {executor: ExecutorConfig}) {
)
}

export function getExecutorArgument<T>(input: executorArgument<T>, cliArgs: RecipeCLIArgs): T {
export function getExecutorArgument<T>(
input: executorArgument<T>,
cliArgs: RecipeCLIArgs
): T {
if (isDynamicExecutorArgument(input)) {
return input(cliArgs)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {prompt as enquirer} from "enquirer"
import globby from "globby"
import { prompt as enquirer } from 'enquirer'
import globby from 'globby'

enum SearchType {
file,
Expand All @@ -13,8 +13,8 @@ interface FilePromptOptions {
context: any
}

function getMatchingFiles(filter: string = ""): Promise<string[]> {
return globby(filter, {expandDirectories: true})
function getMatchingFiles(filter: string = ''): Promise<string[]> {
return globby(filter, { expandDirectories: true })
}

export async function filePrompt(options: FilePromptOptions): Promise<string> {
Expand All @@ -24,10 +24,10 @@ export async function filePrompt(options: FilePromptOptions): Promise<string> {
if (choices.length === 1) {
return choices[0]
}
const results: {file: string} = await enquirer({
type: "autocomplete",
name: "file",
message: "Select the target file",
const results: { file: string } = await enquirer({
type: 'autocomplete',
name: 'file',
message: 'Select the target file',
// @ts-ignore
limit: 10,
choices,
Expand Down
Loading

0 comments on commit 5f1c6a4

Please sign in to comment.