Skip to content

Update your app from epic stack or examples #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 26, 2025
Merged

Conversation

jacobparis
Copy link
Contributor

This PR implements the "epicli update" command to pull changes from the epic stack into your project, as well as renames "generate" to "apply" and allows pulling changes from an example project

jacobparis and others added 2 commits March 25, 2025 22:04
test

use the right patches

fix: add closing documents

fix: handle the single commit case

fix: remove dry run

feature: add filter and ignore patterns

fix: remove dead code

fix: clean up variable names

chore: refactor apply and update

chore: move into files

fix: move onComplete callback

fix: create readme
import { printCommits } from '../utils/print-commits.js'
import { gitUseRepo } from '../utils/repo.js'

const epicStackBookmarks = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may be misunderstanding how this works, but I wasn't expecting these to be hard coded 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard-coded was faster for a proof of concept – I think it makes sense to keep this as a file but move it to the epic stack repo instead of in the CLI. I'll leave that choice up to you

  • it takes the full list of commits between user's position and latest, and walks forward until either it hits a bookmark or reaches the end
  • if it hits a bookmark, it stops there, takes that label and instructions to add to the prompt, and lets the user update
  • if it doesn't, then their update just includes all commits and there's no special instructions

So this isn't something you'll have to maintain super often, but when there's a big change and you want a checkpoint when people are updating, you can add it here. Most likely this will be updated as people mention difficulties with auto updating certain files. For example I found it missed migrating imports sometimes until I added that to the prompt, and then it started getting them right every time.

Since the user is in control of the prompt they use, they may try their own special instructions and contribute back if they find something that works well.

You could consider an epicli.json file like below or adding the bookmarks to the package.json#epic-stack property

the pkgless implementation

For context in pkgless, each package can define a pkgless.json file (evolved from sly.json) for how it consumes other pkgs

  • set a "template" repo plus its version (thematically the package.json#epic-stack property)
  • add "libraries" to install from a particular github directory (like shadcn, or epic-stack's components folder)
  • set "items" to link particular files to github, like an entry.server.ts or a little bundle of auth.server.ts + session.server.ts, and of course pull updates any time those get new commits

then there's a separate key (currently "meta") that defines how this package is CONSUMED, and that's how pkgless.com/templates knows which hosts a template works with and what its stack looks like.

A repo either has this pkgless.json#meta in its project root (or roots for monorepo cases) or I have a definitely-pkgless repo (thematically like definitely-typed) which allows the community to create and maintain this metadata without requiring each repo owner to buy in and add a file to their codebase.

{
  "meta": {
    "template": true,
    "description": "An opinionated full stack app starter template.",
    "environments": ["fly.io"],
    "bookmarks": [
      {
        "commit": "62e65077269d803627418677f180a77aab2bff53",
        "description": "Use native ESM"
      },
      {
        "commit": "bc93804353cf89c8c901e1a8b629ad25ac0a4e3c",
        "description": "Add shadcn/ui"
      },
      {
        "commit": "5cb51100ddc97cd31ec53036c42f7fae7ff15572",
        "description": "Bring improvements from workshops"
      },
      {
        "commit": "49897824f942576c32aba6876ff52e323eec5144",
        "description": "Change relative imports to node resolution"
      },
      {
        "commit": "90ef60d4b2e762a1888fc72abd71f40a5142f978",
        "description": "Update @epic-web/config"
      },
      {
        "commit": "158ed99889e628410cf760e78bb07e09622a87e4",
        "description": "React Router v7"
      },
      {
        "commit": "c33b520795f7cb713894f535e23d7c7400932853",
        "description": "v7 typegen"
      },
      {
        "commit": "0345ff7d775569352a18f13908c817623e2981d5",
        "description": "Move images from SQLite to Tigris"
      }
    ],
    "technologies": [
      "remix",
      "react",
      "react-router", 
      "typescript",
      "tailwindcss",
      "prisma",
      "docker",
      "sqlite",
      "resend",
      "conform",
      "radix-ui",
      "playwright",
      "msw",
      "vitest",
      "prettier",
      "eslint",
      "zod",
      "sentry",
      "tigris"
    ],

Copy link
Member

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good enough to release. Thanks!

/**
* Parses git diff output and categorizes changes by type
*/
export function parseDiff(diffOutput: string): DiffFile[] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason we're not using https://github.com/yeonjuan/parse-git-diff instead of implementing this ourselves?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I stole this util from Sly where it kinda grew organically from "I don't need a lib for this!". Probably better to use that lib here

console.log(chalk.green(`${chalk.bold('Adding')} ${actualFilesToAdd}`))

if (actualFilesToAdd > 0) {
for (const file of filesToAdd) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that I would rather have the added files be handled like the other patches: by the AI. It's possible people have moved things around or other things have changed and I think the AI will (hopefully) be able to recognize a better place to add the file.

As an example of where this can be an issue, database migration files are in a specific order based on the date they were created and my hope is the AI will recognize this and ensure the new migration file is added to the end even if the user has migration files which are newer than what's in the example or the update of the epic stack.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah that's an interesting idea, for that I was leaning toward excluding migrations entirely and just having it re-run prisma migrate dev to generate them from the updated schema

@kentcdodds kentcdodds merged commit 5321778 into main Mar 26, 2025
6 checks passed
@kentcdodds kentcdodds deleted the support-updates branch March 26, 2025 05:08
Copy link

🎉 This PR is included in version 1.3.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants