0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-01-06 22:10:10 -05:00

Adds automatic, seasonally appropriate messages from Houston (#9476)

* feat: allow Houston to wear Scarfs

* refactor: allow 1 object to be passed instead of separate

* set messages back to original state / add ties

* refactor to getClothes method

* refactor: add clothes per season

* refactor: add messages with timing too

* refactor to new file

* refactor: use `hat` & `tie` instead of `clothes`

* refactor: use `getSeasonalHouston` only once

* chore: upgrade dependencies

* fix mistake in date

* feat(create-astro): refactor seasonal logic

* chore: remove unused entrypoint

* refactor: simplify seasonal data

* chore: add changeset

---------

Co-authored-by: Nate Moore <nate@astro.build>
Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
This commit is contained in:
Elian 2024-01-05 22:00:47 +01:00 committed by GitHub
parent 75084b49d0
commit 651f45b401
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 136 additions and 43 deletions

View file

@ -0,0 +1,5 @@
---
"create-astro": patch
---
Improves seasonal message handling by automatically detecting the local date

View file

@ -31,7 +31,7 @@
"//a": "MOST PACKAGES SHOULD GO IN DEV_DEPENDENCIES! THEY WILL BE BUNDLED.",
"//b": "DEPENDENCIES IS FOR UNBUNDLED PACKAGES",
"dependencies": {
"@astrojs/cli-kit": "^0.4.0",
"@astrojs/cli-kit": "^0.4.1",
"giget": "1.1.3"
},
"devDependencies": {

View file

@ -4,6 +4,7 @@ import arg from 'arg';
import os from 'node:os';
import { getName, getVersion } from '../messages.js';
import getSeasonalData from '../data/seasonal.js';
export interface Context {
help: boolean;
@ -25,7 +26,9 @@ export interface Context {
stdin?: typeof process.stdin;
stdout?: typeof process.stdout;
exit(code: number): never;
welcome?: string;
hat?: string;
tie?: string;
tasks: Task[];
}
@ -83,6 +86,8 @@ export async function getContext(argv: string[]): Promise<Context> {
((os.platform() === 'win32' && !fancy) || skipHouston) ??
[yes, no, install, git, typescript].some((v) => v !== undefined);
const { messages, hats, ties } = getSeasonalData({ fancy });
const context: Context = {
help,
prompt,
@ -95,7 +100,9 @@ export async function getContext(argv: string[]): Promise<Context> {
projectName,
template,
ref: ref ?? 'latest',
hat: random(['❄️', '🎄', '🎁']), // fancy ? random(['🎩', '🎩', '🎩', '🎩', '🎓', '👑', '🧢', '🍦']) : undefined,
welcome: random(messages),
hat: hats ? random(hats) : undefined,
tie: ties ? random(ties) : undefined,
yes,
install: install ?? (noInstall ? false : undefined),
git: git ?? (noGit ? false : undefined),

View file

@ -1,15 +1,15 @@
import type { Context } from './context.js';
import { color, label } from '@astrojs/cli-kit';
import { random } from '@astrojs/cli-kit/utils';
import { banner, say, welcome } from '../messages.js';
import { banner, say } from '../messages.js';
export async function intro(
ctx: Pick<Context, 'hat' | 'skipHouston' | 'version' | 'username' | 'fancy'>
ctx: Pick<Context, 'skipHouston' | 'welcome' | 'hat' | 'tie' | 'version' | 'username' | 'fancy'>
) {
banner();
if (!ctx.skipHouston) {
const { welcome, hat, tie } = ctx;
await say(
[
[
@ -21,9 +21,9 @@ export async function intro(
),
Promise.resolve(ctx.username).then((username) => `${username}!`),
],
random(welcome),
],
{ clear: true, hat: ctx.hat }
welcome ?? 'Let\'s build something awesome!',
] as string[],
{ clear: true, hat, tie }
);
}
}

View file

@ -3,7 +3,7 @@ import type { Context } from './context.js';
import { nextSteps, say } from '../messages.js';
export async function next(ctx: Pick<Context, 'hat' | 'cwd' | 'packageManager' | 'skipHouston'>) {
export async function next(ctx: Pick<Context, 'hat' | 'tie' | 'cwd' | 'packageManager' | 'skipHouston'>) {
let projectDir = path.relative(process.cwd(), ctx.cwd);
const commandMap: { [key: string]: string } = {
@ -17,7 +17,7 @@ export async function next(ctx: Pick<Context, 'hat' | 'cwd' | 'packageManager' |
await nextSteps({ projectDir, devCmd });
if (!ctx.skipHouston) {
await say(['Good luck out there, astronaut! 🚀'], { hat: ctx.hat });
await say(['Good luck out there, astronaut! 🚀'], { hat: ctx.hat, tie: ctx.tie });
}
return;
}

View file

@ -0,0 +1,108 @@
interface SeasonalHouston {
hats?: string[];
ties?: string[];
messages: string[]
}
export default function getSeasonalHouston({ fancy }: { fancy?: boolean }): SeasonalHouston {
const season = getSeason();
switch (season) {
case 'new-year': {
const year = new Date().getFullYear();
return {
hats: rarity(0.5, ['🎩']),
ties: rarity(0.25, ['🎊', '🎀', '🎉']),
messages: [
`New year, new Astro site!`,
`Kicking ${year} off with Astro?! What an honor!`,
`Happy ${year}! Let's make something cool.`,
`${year} is your year! Let's build something awesome.`,
`${year} is the year of Astro!`,
`${year} is clearly off to a great start!`,
`Thanks for starting ${year} with Astro!`
]
}
}
case 'spooky': return {
hats: rarity(0.5, ['🎃', '👻', '☠️', '💀', '🕷️', '🔮']),
ties: rarity(0.25, ['🦴', '🍬', '🍫']),
messages: [
`I'm afraid I can't help you... Just kidding!`,
`Boo! Just kidding. Let's make a website!`,
`Let's haunt the internet. OooOooOOoo!`,
`No tricks here. Seeing you is always treat!`,
`Spiders aren't the only ones building the web!`,
`Let's conjure up some web magic!`,
`Let's harness the power of Astro to build a frightful new site!`,
`We're conjuring up a spooktacular website!`,
`Prepare for a web of spooky wonders to be woven.`,
`Chills and thrills await you on your new project!`,
]
}
case 'holiday': return {
hats: rarity(0.75, ['🎁', '🎄', '🌲']),
ties: rarity(0.75, ['🧣']),
messages: [
`'Tis the season to code and create.`,
`Jingle all the way through your web creation journey!`,
`Bells are ringing, and so are your creative ideas!`,
`Let's make the internet our own winter wonderland!`,
`It's time to decorate a brand new website!`,
`Let's unwrap the magic of the web together!`,
`Hope you're enjoying the holiday season!`,
`I'm dreaming of a brand new website!`,
`No better holiday gift than a new site!`,
`Your creativity is the gift that keeps on giving!`,
]
}
default: return {
hats: fancy ? ['🎩', '🎩', '🎩', '🎩', '🎓', '👑', '🧢', '🍦'] : undefined,
ties: fancy ? rarity(0.33, ['🎀', '🧣']) : undefined,
messages: [
`Let's claim your corner of the internet.`,
`I'll be your assistant today.`,
`Let's build something awesome!`,
`Let's build something great!`,
`Let's build something fast!`,
`Let's build the web we want.`,
`Let's make the web weird!`,
`Let's make the web a better place!`,
`Let's create a new project!`,
`Let's create something unique!`,
`Time to build a new website.`,
`Time to build a faster website.`,
`Time to build a sweet new website.`,
`We're glad to have you on board.`,
`Keeping the internet weird since 2021.`,
`Initiating launch sequence...`,
`Initiating launch sequence... right... now!`,
`Awaiting further instructions.`,
]
}
}
}
type Season = 'spooky' | 'holiday' | 'new-year';
function getSeason(): Season | undefined {
const date = new Date();
const month = date.getMonth() + 1;
const day = date.getDate() + 1;
if (month === 1 && day <= 7) {
return 'new-year';
}
if (month === 10 && day > 7) {
return 'spooky'
}
if (month === 12 && day > 7 && day < 25) {
return 'holiday'
}
}
// Generates an array padded with empty strings to make decorations more rare
function rarity(frequency: number, emoji: string[]) {
if (frequency === 1) return emoji;
if (frequency === 0) return [''];
const empty = Array.from({ length: Math.round(emoji.length * frequency) }, () => '')
return [...emoji, ...empty];
}

View file

@ -24,8 +24,8 @@ export function setStdout(writable: typeof process.stdout) {
stdout = writable;
}
export async function say(messages: string | string[], { clear = false, hat = '' } = {}) {
return houston(messages, { clear, hat, stdout });
export async function say(messages: string | string[], { clear = false, hat = '', tie = ''} = {}) {
return houston(messages, { clear, hat, tie, stdout });
}
export async function spinner(args: {
@ -39,33 +39,6 @@ export async function spinner(args: {
export const title = (text: string) => align(label(text), 'end', 7) + ' ';
export const welcome = [
// `Let's claim your corner of the internet.`,
// `I'll be your assistant today.`,
// `Let's build something awesome!`,
// `Let's build something great!`,
// `Let's build something fast!`,
// `Let's build the web we want.`,
// `Let's make the web weird!`,
// `Let's make the web a better place!`,
// `Let's create a new project!`,
// `Let's create something unique!`,
// `Time to build a new website.`,
// `Time to build a faster website.`,
// `Time to build a sweet new website.`,
// `We're glad to have you on board.`,
// `Keeping the internet weird since 2021.`,
// `Initiating launch sequence...`,
// `Initiating launch sequence... right... now!`,
// `Awaiting further instructions.`,
`Ho, ho, ho! 'Tis the season to code and create.`,
`Jingle all the way through your web creation journey!`,
`Let's unwrap the magic of the web together!`,
`Bells are ringing, and so are your creative ideas!`,
`It's starting to look a lot like Christmas on the internet.`,
`It's time to decorate the web with your festive ideas!`,
];
export const getName = () =>
new Promise<string>((resolve) => {
exec('git config user.name', { encoding: 'utf-8' }, (_1, gitName) => {

View file

@ -3737,8 +3737,8 @@ importers:
packages/create-astro:
dependencies:
'@astrojs/cli-kit':
specifier: ^0.4.0
version: 0.4.0
specifier: ^0.4.1
version: 0.4.1
giget:
specifier: 1.1.3
version: 1.1.3
@ -5280,8 +5280,8 @@ packages:
sisteransi: 1.0.5
dev: false
/@astrojs/cli-kit@0.4.0:
resolution: {integrity: sha512-M7R2Af/Gh13pwZ2zjTkTPt87x4IjRw/bSRCmjJGWEGeW3nLNzuEeRY8tleeIGbbfUsm3DJg+UF5rCrQGoviHgQ==}
/@astrojs/cli-kit@0.4.1:
resolution: {integrity: sha512-bVzyKzEpIwqjihBU/aUzt1LQckJuHK0agd3/ITdXhPUYculrc6K1/K7H+XG4rwjXtg+ikT3PM05V1MVYWiIvQw==}
engines: {node: '>=18.14.1'}
dependencies:
chalk: 5.3.0