feat: Scan for lock files and set right commands

This commit is contained in:
Andras Bacsai 2022-02-20 14:40:15 +01:00
parent 1cfaef911c
commit aa5e2edbc5
4 changed files with 189 additions and 58 deletions

View File

@ -1,16 +1,146 @@
const defaultBuildAndDeploy = { function defaultBuildAndDeploy(packageManager) {
installCommand: 'yarn install', return {
buildCommand: 'yarn build', installCommand:
startCommand: 'yarn start' packageManager === 'npm' ? `${packageManager} run install` : `${packageManager} install`,
buildCommand:
packageManager === 'npm' ? `${packageManager} run build` : `${packageManager} build`,
startCommand:
packageManager === 'npm' ? `${packageManager} run start` : `${packageManager} start`
}; };
export const buildPacks = [ }
{ export function findBuildPack(pack, packageManager = 'npm') {
name: 'node', const metaData = buildPacks.find((b) => b.name === pack);
if (pack === 'node') {
return {
...metaData,
installCommand: null, installCommand: null,
buildCommand: null, buildCommand: null,
startCommand: null, startCommand: null,
publishDirectory: null, publishDirectory: null,
port: null, port: null
};
}
if (pack === 'static') {
return {
...metaData,
installCommand: null,
buildCommand: null,
startCommand: null,
publishDirectory: null,
port: 80
};
}
if (pack === 'docker') {
return {
...metaData,
installCommand: null,
buildCommand: null,
startCommand: null,
publishDirectory: null,
port: null
};
}
if (pack === 'svelte') {
return {
...metaData,
...defaultBuildAndDeploy(packageManager),
publishDirectory: 'public',
port: 80
};
}
if (pack === 'nestjs') {
return {
...metaData,
...defaultBuildAndDeploy(packageManager),
startCommand:
packageManager === 'npm' ? 'npm run start:prod' : `${packageManager} run start:prod`,
publishDirectory: null,
port: 3000
};
}
if (pack === 'react') {
return {
...metaData,
...defaultBuildAndDeploy(packageManager),
publishDirectory: 'build',
port: 80
};
}
if (pack === 'nextjs') {
return {
...metaData,
...defaultBuildAndDeploy(packageManager),
publishDirectory: null,
port: 3000
};
}
if (pack === 'gatsby') {
return {
...metaData,
...defaultBuildAndDeploy(packageManager),
publishDirectory: 'public',
port: 80
};
}
if (pack === 'vuejs') {
return {
...metaData,
...defaultBuildAndDeploy(packageManager),
publishDirectory: 'dist',
port: 80
};
}
if (pack === 'nuxtjs') {
return {
...metaData,
...defaultBuildAndDeploy(packageManager),
publishDirectory: null,
port: 3000
};
}
if (pack === 'preact') {
return {
...metaData,
...defaultBuildAndDeploy(packageManager),
publishDirectory: 'build',
port: 80
};
}
if (pack === 'php') {
return {
...metaData,
installCommand: null,
buildCommand: null,
startCommand: null,
publishDirectory: null,
port: 80
};
}
if (pack === 'rust') {
return {
...metaData,
installCommand: null,
buildCommand: null,
startCommand: null,
publishDirectory: null,
port: 3000
};
}
return {
name: 'node',
fancyName: 'Node.js',
hoverColor: 'hover:bg-green-700',
color: 'bg-green-700',
installCommand: null,
buildCommand: null,
startCommand: null,
publishDirectory: null,
port: null
};
}
export const buildPacks = [
{
name: 'node',
fancyName: 'Node.js', fancyName: 'Node.js',
hoverColor: 'hover:bg-green-700', hoverColor: 'hover:bg-green-700',
color: 'bg-green-700' color: 'bg-green-700'
@ -18,103 +148,72 @@ export const buildPacks = [
{ {
name: 'static', name: 'static',
publishDirectory: 'dist',
port: 80,
fancyName: 'Static', fancyName: 'Static',
hoverColor: 'hover:bg-orange-700', hoverColor: 'hover:bg-orange-700',
color: 'bg-orange-700' color: 'bg-orange-700'
}, },
{ {
name: 'docker', name: 'docker',
installCommand: null,
buildCommand: null,
startCommand: null,
publishDirectory: null,
port: null,
fancyName: 'Docker', fancyName: 'Docker',
hoverColor: 'hover:bg-sky-700', hoverColor: 'hover:bg-sky-700',
color: 'bg-sky-700' color: 'bg-sky-700'
}, },
{ {
name: 'svelte', name: 'svelte',
...defaultBuildAndDeploy,
publishDirectory: 'public',
port: 80,
fancyName: 'Svelte', fancyName: 'Svelte',
hoverColor: 'hover:bg-orange-700', hoverColor: 'hover:bg-orange-700',
color: 'bg-orange-700' color: 'bg-orange-700'
}, },
{ {
name: 'nestjs', name: 'nestjs',
...defaultBuildAndDeploy,
startCommand: 'yarn start:prod',
port: 3000,
fancyName: 'NestJS', fancyName: 'NestJS',
hoverColor: 'hover:bg-red-700', hoverColor: 'hover:bg-red-700',
color: 'bg-red-700' color: 'bg-red-700'
}, },
{ {
name: 'react', name: 'react',
...defaultBuildAndDeploy,
publishDirectory: 'build',
port: 80,
fancyName: 'React', fancyName: 'React',
hoverColor: 'hover:bg-blue-700', hoverColor: 'hover:bg-blue-700',
color: 'bg-blue-700' color: 'bg-blue-700'
}, },
{ {
name: 'nextjs', name: 'nextjs',
...defaultBuildAndDeploy,
port: 3000,
fancyName: 'NextJS', fancyName: 'NextJS',
hoverColor: 'hover:bg-blue-700', hoverColor: 'hover:bg-blue-700',
color: 'bg-blue-700' color: 'bg-blue-700'
}, },
{ {
name: 'gatsby', name: 'gatsby',
...defaultBuildAndDeploy,
publishDirectory: 'public',
port: 80,
fancyName: 'Gatsby', fancyName: 'Gatsby',
hoverColor: 'hover:bg-blue-700', hoverColor: 'hover:bg-blue-700',
color: 'bg-blue-700' color: 'bg-blue-700'
}, },
{ {
name: 'vuejs', name: 'vuejs',
...defaultBuildAndDeploy,
publishDirectory: 'dist',
port: 80,
fancyName: 'VueJS', fancyName: 'VueJS',
hoverColor: 'hover:bg-green-700', hoverColor: 'hover:bg-green-700',
color: 'bg-green-700' color: 'bg-green-700'
}, },
{ {
name: 'nuxtjs', name: 'nuxtjs',
...defaultBuildAndDeploy,
port: 3000,
fancyName: 'NuxtJS', fancyName: 'NuxtJS',
hoverColor: 'hover:bg-green-700', hoverColor: 'hover:bg-green-700',
color: 'bg-green-700' color: 'bg-green-700'
}, },
{ {
name: 'preact', name: 'preact',
...defaultBuildAndDeploy,
publishDirectory: 'build',
port: 80,
fancyName: 'Preact', fancyName: 'Preact',
hoverColor: 'hover:bg-blue-700', hoverColor: 'hover:bg-blue-700',
color: 'bg-blue-700' color: 'bg-blue-700'
}, },
{ {
name: 'php', name: 'php',
port: 80,
fancyName: 'PHP', fancyName: 'PHP',
hoverColor: 'hover:bg-indigo-700', hoverColor: 'hover:bg-indigo-700',
color: 'bg-indigo-700' color: 'bg-indigo-700'
}, },
{ {
name: 'rust', name: 'rust',
port: 3000,
fancyName: 'Rust', fancyName: 'Rust',
hoverColor: 'hover:bg-pink-700', hoverColor: 'hover:bg-pink-700',
color: 'bg-pink-700' color: 'bg-pink-700'

View File

@ -3,6 +3,7 @@
import { page } from '$app/stores'; import { page } from '$app/stores';
import { post } from '$lib/api'; import { post } from '$lib/api';
import { findBuildPack } from '$lib/components/templates';
import { errorNotification } from '$lib/form'; import { errorNotification } from '$lib/form';
const { id } = $page.params; const { id } = $page.params;
@ -11,10 +12,13 @@
export let buildPack; export let buildPack;
export let foundConfig; export let foundConfig;
export let scanning; export let scanning;
export let packageManager;
async function handleSubmit(name) { async function handleSubmit(name) {
try { try {
const tempBuildPack = JSON.parse(JSON.stringify(buildPack)); const tempBuildPack = JSON.parse(
JSON.stringify(findBuildPack(buildPack.name, packageManager))
);
delete tempBuildPack.name; delete tempBuildPack.name;
delete tempBuildPack.fancyName; delete tempBuildPack.fancyName;
delete tempBuildPack.color; delete tempBuildPack.color;

View File

@ -29,14 +29,16 @@
<script lang="ts"> <script lang="ts">
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { buildPacks, scanningTemplates } from '$lib/components/templates'; import { buildPacks, findBuildPack, scanningTemplates } from '$lib/components/templates';
import BuildPack from './_BuildPack.svelte'; import BuildPack from './_BuildPack.svelte';
import { page, session } from '$app/stores'; import { page, session } from '$app/stores';
import { get } from '$lib/api'; import { get } from '$lib/api';
import { errorNotification } from '$lib/form'; import { errorNotification } from '$lib/form';
import { browser } from '$app/env';
let scanning = true; let scanning = true;
let foundConfig = null; let foundConfig = null;
let packageManager = 'npm';
export let apiUrl; export let apiUrl;
export let projectId; export let projectId;
@ -48,10 +50,11 @@
function checkPackageJSONContents({ key, json }) { function checkPackageJSONContents({ key, json }) {
return json?.dependencies?.hasOwnProperty(key) || json?.devDependencies?.hasOwnProperty(key); return json?.dependencies?.hasOwnProperty(key) || json?.devDependencies?.hasOwnProperty(key);
} }
function checkTemplates({ json }) { function checkTemplates({ json, packageManager }) {
for (const [key, value] of Object.entries(scanningTemplates)) { for (const [key, value] of Object.entries(scanningTemplates)) {
if (checkPackageJSONContents({ key, json })) { if (checkPackageJSONContents({ key, json })) {
return buildPacks.find((bp) => bp.name === value.buildPack); foundConfig = findBuildPack(value.buildPack, packageManager);
break;
} }
} }
} }
@ -64,6 +67,10 @@
const packageJson = files.find( const packageJson = files.find(
(file) => file.name === 'package.json' && file.type === 'blob' (file) => file.name === 'package.json' && file.type === 'blob'
); );
const yarnLock = files.find((file) => file.name === 'yarn.lock' && file.type === 'blob');
const pnpmLock = files.find(
(file) => file.name === 'pnpm-lock.yaml' && file.type === 'blob'
);
const dockerfile = files.find((file) => file.name === 'Dockerfile' && file.type === 'blob'); const dockerfile = files.find((file) => file.name === 'Dockerfile' && file.type === 'blob');
const cargoToml = files.find((file) => file.name === 'Cargo.toml' && file.type === 'blob'); const cargoToml = files.find((file) => file.name === 'Cargo.toml' && file.type === 'blob');
const requirementsTxt = files.find( const requirementsTxt = files.find(
@ -71,6 +78,10 @@
); );
const indexHtml = files.find((file) => file.name === 'index.html' && file.type === 'blob'); const indexHtml = files.find((file) => file.name === 'index.html' && file.type === 'blob');
const indexPHP = files.find((file) => file.name === 'index.php' && file.type === 'blob'); const indexPHP = files.find((file) => file.name === 'index.php' && file.type === 'blob');
if (yarnLock) packageManager = 'yarn';
if (pnpmLock) packageManager = 'pnpm';
if (dockerfile) { if (dockerfile) {
foundConfig.buildPack = 'docker'; foundConfig.buildPack = 'docker';
} else if (packageJson) { } else if (packageJson) {
@ -82,15 +93,15 @@
} }
); );
const json = JSON.parse(data) || {}; const json = JSON.parse(data) || {};
foundConfig = checkTemplates({ json }); checkTemplates({ json, packageManager });
} else if (cargoToml) { } else if (cargoToml) {
foundConfig = buildPacks.find((bp) => bp.name === 'rust'); foundConfig = findBuildPack('rust');
} else if (requirementsTxt) { } else if (requirementsTxt) {
foundConfig = buildPacks.find((bp) => bp.name === 'python'); foundConfig = findBuildPack('python');
} else if (indexHtml) { } else if (indexHtml) {
foundConfig = buildPacks.find((bp) => bp.name === 'static'); foundConfig = findBuildPack('static', packageManager);
} else if (indexPHP) { } else if (indexPHP) {
foundConfig = buildPacks.find((bp) => bp.name === 'php'); foundConfig = findBuildPack('php');
} }
} else if (type === 'github') { } else if (type === 'github') {
const files = await get(`${apiUrl}/repos/${repository}/contents?ref=${branch}`, { const files = await get(`${apiUrl}/repos/${repository}/contents?ref=${branch}`, {
@ -100,6 +111,10 @@
const packageJson = files.find( const packageJson = files.find(
(file) => file.name === 'package.json' && file.type === 'file' (file) => file.name === 'package.json' && file.type === 'file'
); );
const yarnLock = files.find((file) => file.name === 'yarn.lock' && file.type === 'file');
const pnpmLock = files.find(
(file) => file.name === 'pnpm-lock.yaml' && file.type === 'file'
);
const dockerfile = files.find((file) => file.name === 'Dockerfile' && file.type === 'file'); const dockerfile = files.find((file) => file.name === 'Dockerfile' && file.type === 'file');
const cargoToml = files.find((file) => file.name === 'Cargo.toml' && file.type === 'file'); const cargoToml = files.find((file) => file.name === 'Cargo.toml' && file.type === 'file');
const requirementsTxt = files.find( const requirementsTxt = files.find(
@ -107,6 +122,10 @@
); );
const indexHtml = files.find((file) => file.name === 'index.html' && file.type === 'file'); const indexHtml = files.find((file) => file.name === 'index.html' && file.type === 'file');
const indexPHP = files.find((file) => file.name === 'index.php' && file.type === 'file'); const indexPHP = files.find((file) => file.name === 'index.php' && file.type === 'file');
if (yarnLock) packageManager = 'yarn';
if (pnpmLock) packageManager = 'pnpm';
if (dockerfile) { if (dockerfile) {
foundConfig.buildPack = 'docker'; foundConfig.buildPack = 'docker';
} else if (packageJson) { } else if (packageJson) {
@ -115,18 +134,19 @@
Accept: 'application/vnd.github.v2.raw' Accept: 'application/vnd.github.v2.raw'
}); });
const json = JSON.parse(data) || {}; const json = JSON.parse(data) || {};
foundConfig = checkTemplates({ json }); checkTemplates({ json, packageManager });
} else if (cargoToml) { } else if (cargoToml) {
foundConfig = buildPacks.find((bp) => bp.name === 'rust'); foundConfig = findBuildPack('rust');
} else if (requirementsTxt) { } else if (requirementsTxt) {
foundConfig = buildPacks.find((bp) => bp.name === 'python'); foundConfig = findBuildPack('python');
} else if (indexHtml) { } else if (indexHtml) {
foundConfig = buildPacks.find((bp) => bp.name === 'static'); foundConfig = findBuildPack('static', packageManager);
} else if (indexPHP) { } else if (indexPHP) {
foundConfig = buildPacks.find((bp) => bp.name === 'php'); foundConfig = findBuildPack('php');
} }
} }
} catch (error) { } catch (error) {
scanning = true;
if ( if (
error.error === 'invalid_token' || error.error === 'invalid_token' ||
error.error_description === error.error_description ===
@ -154,11 +174,13 @@
}, 100); }, 100);
} }
} }
return errorNotification(error); if (error.message === 'Bad credentials') {
} finally { browser && window.location.reload();
if (!foundConfig) foundConfig = buildPacks.find((bp) => bp.name === 'node');
scanning = false;
} }
return errorNotification(error);
}
if (!foundConfig) foundConfig = findBuildPack('node', packageManager);
scanning = false;
} }
onMount(async () => { onMount(async () => {
await scanRepository(); await scanRepository();
@ -174,10 +196,16 @@
<div class="text-xl tracking-tight">Scanning repository to suggest a build pack for you...</div> <div class="text-xl tracking-tight">Scanning repository to suggest a build pack for you...</div>
</div> </div>
{:else} {:else}
{#if packageManager === 'yarn' || packageManager === 'pnpm'}
<div class="flex justify-center p-6">
Found lock file for <span class="font-bold text-orange-500 pl-1">{packageManager}</span>.
Using it for predefined commands commands.
</div>
{/if}
<div class="max-w-7xl mx-auto flex flex-wrap justify-center"> <div class="max-w-7xl mx-auto flex flex-wrap justify-center">
{#each buildPacks as buildPack} {#each buildPacks as buildPack}
<div class="p-2"> <div class="p-2">
<BuildPack {buildPack} {scanning} bind:foundConfig /> <BuildPack {buildPack} {scanning} {packageManager} bind:foundConfig />
</div> </div>
{/each} {/each}
</div> </div>

View File

@ -30,7 +30,7 @@
import type Prisma from '@prisma/client'; import type Prisma from '@prisma/client';
import { page } from '$app/stores'; import { page } from '$app/stores';
import { enhance, errorNotification } from '$lib/form'; import { errorNotification } from '$lib/form';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { post } from '$lib/api'; import { post } from '$lib/api';