Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

Add optional 2-way sync between the CLI (theme serve) and the Theme Editor #2174

Merged
merged 16 commits into from
Mar 25, 2022

Conversation

karreiro
Copy link
Contributor

@karreiro karreiro commented Mar 23, 2022

⚠️ I've split this PR into meaningful commits to make the review process a bit easier (check it with git log -12). They do not reflect the order of implementation but a more logical path to follow.

WHY are these changes introduced?

Currently, when developers run theme serve, the CLI replaces the remote development theme with the local version.

Many developers expect that (1-way sync) behavior and already have tooling/workflows relying on that.

However, other developers prefer to rely on a 2-way sync logic. In other words: when something changes in the Theme Editor, the CLI (theme serve) should auto get the remote updated version; and when something changes in the local files, the CLI should auto pushes the updated version.

Thus, this PR adds an optional 2-way sync capabilities between the CLI (theme serve) and the Theme Editor with the new --theme-editor-sync flag.

image

WHAT is this pull request doing?

This PR approaches the 2-way sync with 3 pillars:

  • 1. The theme serve startup

    When developers run theme serve with the --theme-editor-sync flag, the CLI checks (before pushing the local files to the development theme) if there are changes on remote .json files.

    If so, the CLI prompts users to check which version they prefer to keep, or even if they want a merged version of files (ref: JsonUpdateHandler and JsonDeleteHandler).

  • 2. The theme serve pulling mechanism

    When developers run theme serve with the --theme-editor-sync flag, the CLI adopts will an approach similar to --pull-json-interval to pull .json files (ref: RemoteWatcher).

  • 3. the Theme Editor conflicts mechanism

    The CLI already automatically uploads the updated .json file when partners locally change them, and the Theme Editor already has a mechanism to avoid conflicts. Thus, no changes will be performed on this side.

Goals and non-goals

This PR introduces the --theme-editor-sync flag to help developers (that expect 2-way sync features) on avoiding scenarios where they lose their data/work (e.g., when re-run theme serve after working in the Theme Editor).

It focuses on performing checks/helpful-actions during the start-up and auto-pulling files when the theme serve is running.

This PR doesn't aim to introduce consensus ordering between the CLI and the Theme Editor, mutation history, and ensure conflict-free features in the Syncer.

How to test your changes?

Sync test case

  • Run shopify theme serve --theme-editor-sync
  • Open the Theme Editor
  • Change something
  • Notice the change is synced

with_sync_no_message_and_sync_demo

Startup case

  • Open the Theme Editor
  • Change something
  • Run shopify theme serve --theme-editor-sync
  • Notice the CLI asks which version it should keep

modified_version_remotely

Other test cases:

Many updated files localy test case
  • With local theme with many modified files
  • Run shopify theme serve --theme-editor-sync
  • Notice the CLI asks about how to proceed
  • Select "Keep the local version"
  • Notice the CLI uploads the JSON files
    apply_all
  • Also, try the "Keep the remote version" (notice the CLI will download the JSON files)
  • Finally, try the "Merge files" (notice the CLI will union merge the local and remote the JSON files)
Files removed locally (restore test case)
  • Remove a JSON file from your local theme
  • Run shopify theme serve --theme-editor-sync
  • Notice the CLI asks before removing the file from your remote development theme
  • Recover your JSON file
  • Notice the is recovered
    startup_recover_local_delete
Files removed locally (delete test case)
  • Run shopify theme serve --theme-editor-sync
  • Change templates/index.json locally
  • Change templates/index.json in the Theme Editor
  • Notice that users may solve the conflict at the editor
  • Delete your JSON file
  • Notice the is removed remotely
    remove_forever
theme serve without the --theme-editor-sync flag test case
  • Run shopify theme serve with modified files locally
  • Notice the CLI doesn't ask about conflicts
  • Notice that now the Theme Editor message is
    Customize this theme in the Theme Editor, and use 'theme pull' to get the changes
  • Notice the pulling mechanism is not activated
    regular_diff_message
    dontask_apply_to_all

Post-release steps

Include the --theme-editor-sync in the theme servedocumentation.

Update checklist

  • I've added a CHANGELOG entry for this PR (if the change is public-facing)
  • I've considered possible cross-platform impacts (Mac, Linux, Windows).
  • I've left the version number as is (we'll handle incrementing this when releasing).
  • I've included any post-release steps in the section above (if needed).

- The `RemoteWatcher` to pull files in the given interval
  - Notice the `RemoteWatcher` relies in the `ThreadPool` (we will check
    it in a future commit
- The `Syncer` to avoid overriding JSON files
  - Use the new `Checksums` class
  - Use the new `IgnoreHelper` module
  - Use the new `JsonDeleteHandler` module (we will check it in a future
    commit)
  - Use the new `JsonUpdateHandler` module (we will check it in a future
    commit)
  - Introduce a new queueable method (`union_merge`)
  - Update the the `upload_theme!` to split the updates between JSON and
    non-JSON files (JSON files are handled by the modules mentioned
    above)
  - Add new `merge_file` wrapper into `ShopifyCLI::Git`
  - Use the new wrapper in the `Theme::Syncer::Merger` to merge theme
    files
…Handler` modules

to handle JSON deletes/updates in the `Syncer` by asking users
how to proceed (when JSON files should not be overwritten)
…nUpdateHandler`:

  - `SelectDeleteStrategy` asks about the strategy to handle deleted
    files
  - `SelectUpdateStrategy` asks about the strategy to handle updated
    files
  - `BaseStrategyForm` supports holds the logic shared by forms mentioned
    above
  - `ApplyToAll` asks users if they want to apply the selected value to
    all other assets (to avoid asking users too much, in some context
    they may have up to 50 updated files)
@karreiro karreiro requested review from macournoyer, a team, pepicrft and gonzaloriestra and removed request for a team, pepicrft and gonzaloriestra March 23, 2022 13:33
Copy link
Contributor

@macournoyer macournoyer left a comment

Choose a reason for hiding this comment

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

Damn! 👏 Nice work. Top hatted... It's magical 🪄

I skimmed through some parts of the code, but core logic looks right.

What do you think about dropping the value in --theme-editor-sync=SEC, just --theme-editor-sync w/ a default? I don't see why anyone would want to tweak that? And we can change the default later if it's polling too much.

@karreiro
Copy link
Contributor Author

Awesome idea 🔥 Thank you, @macournoyer! I've applied your suggestion in a new commit :)

@lesterdefreitas
Copy link

@karreiro thanks so much for this, it's so helpful!

@adam-ainsworth
Copy link

This really should be more prominent in the documents. I thought I'd lost a couple of hours' work and then discovered this. Resigned to redoing everything, I noticed that there are previous versions of files in the code editor, and I was able to recover my data and schema files.

If Shopify wants to be taken seriously, they really need to sort this sort of thing out.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
4 participants