Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Repository state machine #654

Merged

Conversation

smashwilson
Copy link
Contributor

@smashwilson smashwilson commented Apr 13, 2017

Don't worry, this doesn't really have 75+ commits, it just builds on top of #633.

Refactor the Repository model into a state machine. This will fix #608 by allowing us to render distinct things depending on more granular information than this.props.repository === null and simplify a bunch of code because we can ensure we always have a non-null Repository instance available.

Here's the state hierarchy:

  • State
    • Undetermined
    • Absent
    • Loading
    • Initializing
    • Cloning
    • Empty
    • Present
    • Destroyed

Countdown to Blastoff 🚀

  • Introduce the State class hierarchy.
    • Implement methods on State that provide default behavior for visible methods: returning empty collections or null objects for accessors, throwing an Error for action methods.
    • Mark State methods intended to be used from a Repository with a @shouldDelegate decorator.
    • Selectively override methods in each State subclass. Most of Repository moves to Present.
    • Allow State subclasses to transition to one another by constructor name (to avoid circular dependencies).
    • Export only the default state (Loading) to encapsulate the states.
    • Introduce an Absent state to represent a missing working directory.
  • Incorporate state management and delegation into Repository.
    • Synchronously construct Repository instances in their initial state.
    • Provide methods to transition among states.
    • Emit an event when the current state changes.
    • Create a Promise that can be used to wait for a loading repository to complete.
    • Delegate a bunch of stuff to this.state.
    • Add a test case to ensure that the delegated methods are up to date with the @shouldDelegate decorations.
    • Adjust the rest of the Repository tests to accommodate the state transition model.
  • Introduce model objects for Branch, Remote, and Commit.
    • Create models and null objects for each.
    • Return model or null instances from appropriate methods in State and Present.
    • Propagate changes to those methods' callers.
    • Fix up PropTypes.
    • Move test for githubInfoFromRemote.
  • Use the Repository constructor in WorkdirContext.
  • Mark repository as .isRequired in our PropTypes.
  • Render GitTabController differently depending on the current repository state.
    • The "click here to initialize" view should be shown when isEmpty().
    • Maybe just grey it all out when isLoading().
    • Show the existing view when isPresent().
  • Introduce an Undetermined state that's used when activated without any projects in the workspace. It should automatically transition to Absent after a delay if no projects are loaded.
  • Render StatusBarTileController differently depending on the current repository state.
  • Prompt for and create a working directory when performing init or clone from the Absent state.
    • This should be the case with an active TextEditor on a file that isn't within a git repository, too.
  • Change the init verbiage in GitTabView depending on whether or not you have an existing directory to init.
  • Use atom.getLoadSettings() to determine whether the Undetermined state acts like a Loading state or an Absent one.
  • Document the states and provide a state transition diagram.
  • Handle the deletion of the final project directory

@smashwilson smashwilson merged commit 2080ca4 into aw-single-project-regression Apr 20, 2017
@smashwilson smashwilson deleted the aw-go-go-gadget-repository-state-machine branch April 20, 2017 19:09
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant