Module: Tempest::AccountsMigration

Defined in:
lib/tempest/accounts_migration.rb

Overview

One-shot, idempotent migration that converts the legacy single-account layout (<base>/session.json etc.) into the per-DID layout introduced in 0.3.0 (<base>/accounts/<did>/session.json + <base>/accounts.json).

Runs at the top of every command entry point. The presence of accounts.json is the completion marker; partial failures recover automatically thanks to ‘File.rename`’s atomicity and AccountsStore’s orphan self-heal.

Class Method Summary collapse

Class Method Details

.run(env: ENV, stderr: $stderr, logger: nil) ⇒ Object

Returns one of :migrated, :skipped, :noop. :migrated is the only state that produces stderr output.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/tempest/accounts_migration.rb', line 22

def run(env: ENV, stderr: $stderr, logger: nil)
  accounts_json = Tempest::AccountPaths.accounts_json_path(env)
  return :skipped if File.exist?(accounts_json)

  legacy_session = Tempest::AccountPaths.legacy_session_path(env)
  return :noop unless File.exist?(legacy_session)

  data = JSON.parse(File.read(legacy_session))
  did = data.fetch("did")
  handle = data.fetch("handle")
  identifier = data["identifier"] || handle
  pds_host = data["pds_host"] || Tempest::Config::DEFAULT_PDS_HOST

   = Tempest::AccountPaths.(env, did: did)
  FileUtils.mkdir_p(Tempest::AccountPaths.accounts_dir(env), mode: 0o700)
  FileUtils.mkdir_p(, mode: 0o700)

  File.rename(legacy_session, Tempest::AccountPaths.session_path(env, did: did))

  legacy_cursor = Tempest::AccountPaths.legacy_cursor_path(env)
  if File.exist?(legacy_cursor)
    File.rename(legacy_cursor, Tempest::AccountPaths.cursor_path(env, did: did))
  end

  legacy_timeline = Tempest::AccountPaths.legacy_timeline_path(env)
  if File.exist?(legacy_timeline)
    File.rename(legacy_timeline, Tempest::AccountPaths.timeline_path(env, did: did))
  end

  store = Tempest::AccountsStore.new(env: env, logger: logger)
  store.(
    did: did,
    handle: handle,
    identifier: identifier,
    pds_host: pds_host,
    added_at: Time.now.utc,
  )

  logger&.info("accounts", event: "migrated", did: did, account_dir: )
  stderr.puts "[tempest] migrated session to #{}/"
  :migrated
end