Merge branch 'master' into overridable-static
@@ -1,20 +1,13 @@
1{ system ? builtins.currentSystem
1{ system ? builtins.currentSystem
2, profiling ? false
2, profiling ? false
3, iosSdkVersion ? "10.2"
3, iosSdkVersion ? "10.2"
4+, __useLegacyCompilers ? false
6− getReflexPlatform = sys: import ./dep/reflex-platform { inherit iosSdkVersion; system = sys; };
7+ cleanSource = builtins.filterSource (name: _: let baseName = builtins.baseNameOf name; in !(
7− reflex-platform = getReflexPlatform system;
8+ builtins.match "^\\.ghc\\.environment.*" baseName != null ||
8− inherit (reflex-platform) hackGet nixpkgs;
9+ baseName == "cabal.project.local"
9− pkgs = nixpkgs;
10+ ));
10−in with pkgs.haskell.lib; with pkgs.lib;
12− # TODO: Remove this after updating nixpkgs: https://github.com/NixOS/nixpkgs/issues/37750
13− justStaticExecutables' = drv: let
14− drv' = justStaticExecutables drv;
15− in if pkgs.stdenv.isDarwin
16− then removeConfigureFlag drv' "--ghc-option=-optl=-dead_strip"
19 commandRuntimeDeps = pkgs: with pkgs; [
12 commandRuntimeDeps = pkgs: with pkgs; [
@@ -24,103 +17,108 @@ let
27− #TODO: Upstream
20+ getReflexPlatform = getReflexPlatform' __useLegacyCompilers;
28− # Modify a Haskell package to add completion scripts for the given
21+ getReflexPlatform' = __useLegacyCompilers: sys: import ./dep/reflex-platform {
29− # executable produced by it. These completion scripts will be picked up
22+ inherit iosSdkVersion __useLegacyCompilers;
30− # automatically if the resulting derivation is installed, e.g. by
23+ system = sys;
31− # `nix-env -i`.
24+ enableLibraryProfiling = profiling;
32− addOptparseApplicativeCompletionScripts = exeName: pkg: overrideCabal pkg (drv: {
33− postInstall = (drv.postInstall or "") + ''
34− BASH_COMP_DIR="$out/share/bash-completion/completions"
35− mkdir -p "$BASH_COMP_DIR"
36− "$out/bin/${exeName}" --bash-completion-script "$out/bin/${exeName}" >"$BASH_COMP_DIR/ob"
38− ZSH_COMP_DIR="$out/share/zsh/vendor-completions"
26+ nixpkgsOverlays = [
39− mkdir -p "$ZSH_COMP_DIR"
27+ (self: super: {
40− "$out/bin/${exeName}" --zsh-completion-script "$out/bin/${exeName}" >"$ZSH_COMP_DIR/_ob"
28+ obeliskExecutableConfig = import ./lib/executable-config { nixpkgs = pkgs; filterGitSource = cleanSource; };
42− FISH_COMP_DIR="$out/share/fish/vendor_completions.d"
32+ haskellOverlays = [
43− mkdir -p "$FISH_COMP_DIR"
44− "$out/bin/${exeName}" --fish-completion-script "$out/bin/${exeName}" >"$FISH_COMP_DIR/ob.fish"
48− # The haskell environment used to build Obelisk itself, e.g. the 'ob' command
34+ # Fix misc upstream packages
49− ghcObelisk = reflex-platform.ghc.override {
35+ (self: super: let
50− overrides = composeExtensions defaultHaskellOverrides (self: super: {
36+ pkgs = self.callPackage ({ pkgs }: pkgs) {};
51− mkDerivation = args: super.mkDerivation (args // {
37+ in {
52− enableLibraryProfiling = profiling;
38+ # Need deriveSomeUniverse
39+ # PR: https://github.com/dmwit/universe/pull/32
40+ universe-template = self.callCabal2nix "universe-template" (pkgs.fetchFromGitHub {
41+ owner = "obsidiansystems";
43+ rev = "5a2fc823caa4163411d7e41aa80e67cefb15944a";
44+ sha256 = "0ll2z0fh18z6x8jl8kbp7ldagwccz3wjmvrw1gw752z058n82yfa";
48+ # Add obelisk packages
50+ pkgs = self.callPackage ({ pkgs }: pkgs) {};
52+ obelisk-asset-manifest = self.callCabal2nix "obelisk-asset-manifest" (hackGet ./lib/asset + "/manifest") {};
53+ obelisk-asset-serve-snap = self.callCabal2nix "obelisk-asset-serve-snap" (hackGet ./lib/asset + "/serve-snap") {};
54+ obelisk-backend = self.callCabal2nix "obelisk-backend" (cleanSource ./lib/backend) {};
55+ obelisk-cliapp = self.callCabal2nix "obelisk-cliapp" (cleanSource ./lib/cliapp) {};
56+ obelisk-command = (self.callCabal2nix "obelisk-command" (cleanSource ./lib/command) {}).overrideAttrs
58+ buildInputs = drv.buildInputs ++ [ pkgs.makeWrapper ];
60+ ${drv.postFixup or ""}
61+ # Make `ob` reference its runtime dependencies.
62+ wrapProgram "$out"/bin/ob --prefix PATH : ${pkgs.lib.makeBinPath (commandRuntimeDeps pkgs)}
65+ obelisk-executable-config = pkgs.obeliskExecutableConfig.haskellPackage self;
66+ obelisk-executable-config-inject = pkgs.obeliskExecutableConfig.platforms.web.inject self;
67+ obelisk-frontend = self.callCabal2nix "obelisk-frontend" (cleanSource ./lib/frontend) {};
68+ obelisk-run = self.callCabal2nix "obelisk-run" (cleanSource ./lib/run) {};
69+ obelisk-route = self.callCabal2nix "obelisk-route" (cleanSource ./lib/route) {};
70+ obelisk-selftest = self.callCabal2nix "obelisk-selftest" (cleanSource ./lib/selftest) {};
71+ obelisk-snap = self.callCabal2nix "obelisk-snap" (cleanSource ./lib/snap) {};
72+ obelisk-snap-extras = self.callCabal2nix "obelisk-snap-extras" (cleanSource ./lib/snap-extras) {};
55 # Dynamic linking with split objects dramatically increases startup time (about 0.5 seconds on a decent machine with SSD)
75 # Dynamic linking with split objects dramatically increases startup time (about 0.5 seconds on a decent machine with SSD)
56− obelisk-command = addOptparseApplicativeCompletionScripts "ob" (justStaticExecutables' super.obelisk-command);
76+ (self: super: let
57− });
77+ pkgs = self.callPackage ({ pkgs }: pkgs) {};
58− };
78+ haskellLib = pkgs.haskell.lib;
80+ # Modify a Haskell package to add completion scripts for the given
81+ # executable produced by it. These completion scripts will be picked up
82+ # automatically if the resulting derivation is installed, e.g. by
84+ addOptparseApplicativeCompletionScripts = exeName: pkg: haskellLib.overrideCabal pkg (drv: {
85+ postInstall = (drv.postInstall or "") + ''
86+ BASH_COMP_DIR="$out/share/bash-completion/completions"
87+ mkdir -p "$BASH_COMP_DIR"
88+ "$out/bin/${exeName}" --bash-completion-script "$out/bin/${exeName}" >"$BASH_COMP_DIR/ob"
60− fixUpstreamPkgs = self: super: {
90+ ZSH_COMP_DIR="$out/share/zsh/vendor-completions"
61− algebraic-graphs = pkgs.haskell.lib.doJailbreak
91+ mkdir -p "$ZSH_COMP_DIR"
62− (self.callCabal2nix "algebraic-graphs" (pkgs.fetchFromGitHub {
92+ "$out/bin/${exeName}" --zsh-completion-script "$out/bin/${exeName}" >"$ZSH_COMP_DIR/_ob"
63− owner = "snowleopard";
65− rev = "480a73137e9b38ad3f1bc2c628847953d2fb3e25";
66− sha256 = "0dpwi5ffs88brl3lz51bwb004c6zm8ds8pkw1vzsg2a6aaiyhlzl";
69− # Need deriveSomeUniverse
94+ FISH_COMP_DIR="$out/share/fish/vendor_completions.d"
70− # PR: https://github.com/dmwit/universe/pull/32
95+ mkdir -p "$FISH_COMP_DIR"
71− universe-template = self.callCabal2nix "universe-template" (pkgs.fetchFromGitHub {
96+ "$out/bin/${exeName}" --fish-completion-script "$out/bin/${exeName}" >"$FISH_COMP_DIR/ob.fish"
72− owner = "obsidiansystems";
97+ '';
73− repo = "universe";
98+ });
74− rev = "5a2fc823caa4163411d7e41aa80e67cefb15944a";
99+ in {
75− sha256 = "0ll2z0fh18z6x8jl8kbp7ldagwccz3wjmvrw1gw752z058n82yfa";
100+ obelisk-command = addOptparseApplicativeCompletionScripts "ob" (haskellLib.justStaticExecutables super.obelisk-command);
76− } + /template) {};
101+ obelisk-selftest = haskellLib.justStaticExecutables super.obelisk-selftest;
79− cleanSource = builtins.filterSource (name: _: let baseName = builtins.baseNameOf name; in !(
104+ ];
80− builtins.match "^\\.ghc\\.environment.*" baseName != null ||
81− baseName == "cabal.project.local"
84− executableConfig = import ./lib/executable-config { nixpkgs = pkgs; filterGitSource = cleanSource; };
107+ reflex-platform = getReflexPlatform' false system;
108+ inherit (reflex-platform) hackGet nixpkgs;
86− addLibs = self: super: {
111+ # The haskell environment used to build Obelisk itself, e.g. the 'ob' command
87− obelisk-asset-manifest = self.callCabal2nix "obelisk-asset-manifest" (hackGet ./lib/asset + "/manifest") {};
112+ ghcObelisk = reflex-platform.ghc;
88− obelisk-asset-serve-snap = self.callCabal2nix "obelisk-asset-serve-snap" (hackGet ./lib/asset + "/serve-snap") {};
89− obelisk-backend = self.callCabal2nix "obelisk-backend" (cleanSource ./lib/backend) {};
90− obelisk-cliapp = self.callCabal2nix "obelisk-cliapp" (cleanSource ./lib/cliapp) {};
91− obelisk-command = (self.callCabal2nix "obelisk-command" (cleanSource ./lib/command) {}).overrideAttrs
93− buildInputs = drv.buildInputs ++ [ pkgs.makeWrapper ];
95− ${drv.postInstall or ""}
97− cp -r ${./migration} $out/migration;
100− ${drv.postFixup or ""}
101− # Make `ob` reference its runtime dependencies.
102− wrapProgram "$out"/bin/ob --prefix PATH : ${pkgs.lib.makeBinPath (commandRuntimeDeps pkgs)}
105− obelisk-executable-config = executableConfig.haskellPackage self;
106− obelisk-executable-config-inject = executableConfig.platforms.web.inject self;
107− obelisk-frontend = self.callCabal2nix "obelisk-frontend" (cleanSource ./lib/frontend) {};
108− obelisk-migration = self.callCabal2nix "obelisk-migration" (cleanSource ./lib/migration) {};
109− obelisk-run = self.callCabal2nix "obelisk-run" (cleanSource ./lib/run) {};
110− obelisk-route = self.callCabal2nix "obelisk-route" (cleanSource ./lib/route) {};
111− obelisk-selftest = self.callCabal2nix "obelisk-selftest" (cleanSource ./lib/selftest) {};
112− obelisk-snap = self.callCabal2nix "obelisk-snap" (cleanSource ./lib/snap) {};
113− obelisk-snap-extras = self.callCabal2nix "obelisk-snap-extras" (cleanSource ./lib/snap-extras) {};
116 inherit (import ./lib/asset/assets.nix { inherit nixpkgs; }) mkAssets;
114 inherit (import ./lib/asset/assets.nix { inherit nixpkgs; }) mkAssets;
118− defaultHaskellOverrides = composeExtensions fixUpstreamPkgs addLibs;
120−with pkgs.lib;
116+ haskellLib = pkgs.haskell.lib;
122 inherit reflex-platform;
119 inherit reflex-platform;
123 inherit (reflex-platform) nixpkgs pinBuildInputs;
120 inherit (reflex-platform) nixpkgs pinBuildInputs;
121+ inherit (nixpkgs) lib;
124 pathGit = ./.; # Used in CI by the migration graph hash algorithm to correctly ignore files.
122 pathGit = ./.; # Used in CI by the migration graph hash algorithm to correctly ignore files.
125 path = reflex-platform.filterGit ./.;
123 path = reflex-platform.filterGit ./.;
126 obelisk = ghcObelisk;
124 obelisk = ghcObelisk;
@@ -133,7 +131,7 @@ rec {
134 PATH="${command}/bin:$PATH"
132 PATH="${command}/bin:$PATH"
135 export OBELISK_IMPL="${hackGet ./.}"
133 export OBELISK_IMPL="${hackGet ./.}"
136− "${justStaticExecutables' ghcObelisk.obelisk-selftest}/bin/obelisk-selftest" "$@"
134+ "${ghcObelisk.obelisk-selftest}/bin/obelisk-selftest" "$@"
138 #TODO: Why can't I build ./skeleton directly as a derivation? `nix-build -E ./.` doesn't work
136 #TODO: Why can't I build ./skeleton directly as a derivation? `nix-build -E ./.` doesn't work
139 skeleton = pkgs.runCommand "skeleton" {
137 skeleton = pkgs.runCommand "skeleton" {
@@ -141,8 +139,7 @@ rec {
142 ln -s "$dir" "$out"
140 ln -s "$dir" "$out"
144− nullIfAbsent = p: if pathExists p then p else null;
142+ nullIfAbsent = p: if lib.pathExists p then p else null;
145− haskellOverrides = addLibs;
146 #TODO: Avoid copying files within the nix store. Right now, obelisk-asset-manifest-generate copies files into a big blob so that the android/ios static assets can be imported from there; instead, we should get everything lined up right before turning it into an APK, so that copies, if necessary, only exist temporarily.
143 #TODO: Avoid copying files within the nix store. Right now, obelisk-asset-manifest-generate copies files into a big blob so that the android/ios static assets can be imported from there; instead, we should get everything lined up right before turning it into an APK, so that copies, if necessary, only exist temporarily.
147 processAssets = { src, packageName ? "obelisk-generated-static", moduleName ? "Obelisk.Generated.Static" }: pkgs.runCommand "asset-manifest" {
144 processAssets = { src, packageName ? "obelisk-generated-static", moduleName ? "Obelisk.Generated.Static" }: pkgs.runCommand "asset-manifest" {
148 inherit src;
145 inherit src;
@@ -159,7 +156,7 @@ rec {
159 compressedJs = frontend: pkgs.runCommand "compressedJs" { buildInputs = [ pkgs.closurecompiler ]; } ''
156 compressedJs = frontend: pkgs.runCommand "compressedJs" { buildInputs = [ pkgs.closurecompiler ]; } ''
160 mkdir $out
157 mkdir $out
162− ln -s "${justStaticExecutables frontend}/bin/frontend.jsexe/all.js" all.unminified.js
159+ ln -s "${haskellLib.justStaticExecutables frontend}/bin/frontend.jsexe/all.js" all.unminified.js
163 closure-compiler --externs "${reflex-platform.ghcjsExternsJs}" -O ADVANCED --jscomp_warning=checkVars --create_source_map="all.js.map" --source_map_format=V3 --js_output_file="all.js" all.unminified.js
160 closure-compiler --externs "${reflex-platform.ghcjsExternsJs}" -O ADVANCED --jscomp_warning=checkVars --create_source_map="all.js.map" --source_map_format=V3 --js_output_file="all.js" all.unminified.js
164 echo "//# sourceMappingURL=all.js.map" >> all.js
161 echo "//# sourceMappingURL=all.js.map" >> all.js
@@ -235,7 +232,7 @@ rec {
235 pkgs.runCommand "serverExe" {} ''
232 pkgs.runCommand "serverExe" {} ''
236 mkdir $out
233 mkdir $out
238− ln -s "${justStaticExecutables backend}"/bin/* $out/
235+ ln -s "${haskellLib.justStaticExecutables backend}"/bin/* $out/
239 ln -s "${mkAssets assets}" $out/static.assets
236 ln -s "${mkAssets assets}" $out/static.assets
240 cp -r ${config} $out/config
237 cp -r ${config} $out/config
241 ln -s ${mkAssets (compressedJs frontend)} $out/frontend.jsexe.assets
238 ln -s ${mkAssets (compressedJs frontend)} $out/frontend.jsexe.assets
@@ -274,18 +271,17 @@ rec {
274 staticName = "obelisk-generated-static";
271 staticName = "obelisk-generated-static";
275 processedStatic = processAssets { src = staticFiles; };
272 processedStatic = processAssets { src = staticFiles; };
276 # The packages whose names and roles are defined by this package
273 # The packages whose names and roles are defined by this package
277− predefinedPackages = filterAttrs (_: x: x != null) {
274+ predefinedPackages = lib.filterAttrs (_: x: x != null) {
278 ${frontendName} = nullIfAbsent (base + "/frontend");
275 ${frontendName} = nullIfAbsent (base + "/frontend");
279 ${commonName} = nullIfAbsent (base + "/common");
276 ${commonName} = nullIfAbsent (base + "/common");
280 ${backendName} = nullIfAbsent (base + "/backend");
277 ${backendName} = nullIfAbsent (base + "/backend");
282 combinedPackages = predefinedPackages // packages;
279 combinedPackages = predefinedPackages // packages;
283 projectOverrides = self: super: {
280 projectOverrides = self: super: {
284− ${staticName} = dontHaddock (self.callCabal2nix staticName processedStatic.haskellManifest {});
281+ ${staticName} = haskellLib.dontHaddock (self.callCabal2nix staticName processedStatic.haskellManifest {});
285− ${backendName} = addBuildDepend super.${backendName} self.obelisk-run;
282+ ${backendName} = haskellLib.addBuildDepend super.${backendName} self.obelisk-run;
287− totalOverrides = composeExtensions (composeExtensions defaultHaskellOverrides projectOverrides) overrides;
284+ totalOverrides = lib.composeExtensions projectOverrides overrides;
288− inherit (nixpkgs) lib;
289 inherit (lib.strings) hasPrefix;
285 inherit (lib.strings) hasPrefix;
290 privateConfigDirs = ["config/backend"];
286 privateConfigDirs = ["config/backend"];
291 injectableConfig = builtins.filterSource (path: _:
287 injectableConfig = builtins.filterSource (path: _:
@@ -296,16 +292,16 @@ rec {
296 overrides = totalOverrides;
292 overrides = totalOverrides;
297 packages = combinedPackages;
293 packages = combinedPackages;
298 shells = {
294 shells = {
299− ghcSavedSplices = (filter (x: hasAttr x combinedPackages) [
295+ ghcSavedSplices = (lib.filter (x: lib.hasAttr x combinedPackages) [
300 commonName
296 commonName
301 frontendName
297 frontendName
303− ghc = (filter (x: hasAttr x combinedPackages) [
299+ ghc = (lib.filter (x: lib.hasAttr x combinedPackages) [
304 backendName
300 backendName
305 commonName
301 commonName
306 frontendName
302 frontendName
308− ghcjs = filter (x: hasAttr x combinedPackages) [
304+ ghcjs = lib.filter (x: lib.hasAttr x combinedPackages) [
309 frontendName
305 frontendName
310 commonName
306 commonName
@@ -314,14 +310,14 @@ rec {
314 ${if android == null then null else frontendName} = {
310 ${if android == null then null else frontendName} = {
315 executableName = "frontend";
311 executableName = "frontend";
316 ${if builtins.pathExists staticFiles then "assets" else null} =
312 ${if builtins.pathExists staticFiles then "assets" else null} =
317− executableConfig.platforms.android.inject injectableConfig processedStatic.symlinked;
313+ nixpkgs.obeliskExecutableConfig.platforms.android.inject injectableConfig processedStatic.symlinked;
318 } // android;
314 } // android;
321 ${if ios == null then null else frontendName} = {
317 ${if ios == null then null else frontendName} = {
322 executableName = "frontend";
318 executableName = "frontend";
323 ${if builtins.pathExists staticFiles then "staticSrc" else null} =
319 ${if builtins.pathExists staticFiles then "staticSrc" else null} =
324− executableConfig.platforms.ios.inject injectableConfig processedStatic.symlinked;
320+ nixpkgs.obeliskExecutableConfig.platforms.ios.inject injectableConfig processedStatic.symlinked;
325 } // ios;
321 } // ios;
327 passthru = { inherit android ios packages overrides tools shellToolOverrides withHoogle staticFiles; };
323 passthru = { inherit android ios packages overrides tools shellToolOverrides withHoogle staticFiles; };
@@ -334,13 +330,11 @@ rec {
334 linuxExe = linuxExe (base + "/config");
330 linuxExe = linuxExe (base + "/config");
335 exe = serverOn system (base + "/config") ;
331 exe = serverOn system (base + "/config") ;
336 server = args@{ hostName, adminEmail, routeHost, enableHttps, config }: let
332 server = args@{ hostName, adminEmail, routeHost, enableHttps, config }: let
337− injectableConfig = builtins.filterSource (path: _: !(hasPrefix (toString config + "/backend") (toString path))) config;
333+ injectableConfig = builtins.filterSource (path: _: !(lib.hasPrefix (toString config + "/backend") (toString path))) config;
338 in server (args // { exe = linuxExe injectableConfig; });
334 in server (args // { exe = linuxExe injectableConfig; });
339 obelisk = import (base + "/.obelisk/impl") {};
335 obelisk = import (base + "/.obelisk/impl") {};
341 haskellPackageSets = {
337 haskellPackageSets = {
342− ghc = reflex-platform.ghc.override {
338+ inherit (reflex-platform) ghc;
343− overrides = defaultHaskellOverrides;
dep/reflex-platform/github.json+2−2
@@ -2,6 +2,6 @@
2 "owner": "reflex-frp",
2 "owner": "reflex-frp",
3 "repo": "reflex-platform",
3 "repo": "reflex-platform",
4 "branch": "develop",
4 "branch": "develop",
5− "rev": "92f235e0533b9722be729d785a033faf21e81872",
5+ "rev": "0c022883469da05987810557b61d37b7ae3e922e",
6− "sha256": "1r3kcvy0zf6qdvnasins43hb77lpn0r26vvmnh3cf3yrvpy86sam"
6+ "sha256": "0aissxk9fpzymvr4qqnwkfvr5jya2h7qrxbx5byg0dv627six8yw"
lib/cliapp/obelisk-cliapp.cabal+1
@@ -12,6 +12,7 @@ library
12 , bytestring
12 , bytestring
13 , exceptions
13 , exceptions
14 , io-streams
14 , io-streams
15 , logging-effect
16 , logging-effect
16 , monad-loops
17 , monad-loops
lib/cliapp/src/Obelisk/CliApp.hs+6−2
@@ -8,7 +8,6 @@ module Obelisk.CliApp
10 , CliThrow
10 , CliThrow
12 , CliT(..)
11 , CliT(..)
14 , CliConfig
13 , CliConfig
@@ -22,22 +21,27 @@ module Obelisk.CliApp
22 , withSpinner'
21 , withSpinner'
24 -- .Logging
23 -- .Logging
24+ , AsUnstructuredError (..)
25 , newCliConfig
25 , newCliConfig
26 , getLogLevel
26 , getLogLevel
28 , failWith
28 , failWith
29 , withExitFailMessage
30 , withExitFailMessage
31 -- Control.Monad.Log
32 -- Control.Monad.Log
32 , Severity (..)
33 , Severity (..)
34 -- .Process
35 -- .Process
35− , ProcessFailed (..)
36+ , ProcessFailure (..)
37+ , AsProcessFailure (..)
36 , readProcessAndLogStderr
38 , readProcessAndLogStderr
39+ , readProcessAndLogOutput
37 , callProcessAndLogOutput
40 , callProcessAndLogOutput
38 , createProcess_
41 , createProcess_
39 , callProcess
42 , callProcess
40 , callCommand
43 , callCommand
43import Control.Monad.Log (Severity (..))
47import Control.Monad.Log (Severity (..))
lib/cliapp/src/Obelisk/CliApp/Demo.hs+5−2
@@ -13,7 +13,10 @@ import Control.Monad.Catch (MonadMask)
14import Obelisk.CliApp
14import Obelisk.CliApp
16−cliDemo :: (MonadIO m, MonadMask m, Cli m, HasCliConfig m) => m ()
17+ :: ( MonadIO m, MonadMask m
18+ , CliLog m, HasCliConfig e m, CliThrow e m, AsProcessFailure e, AsUnstructuredError e)
17cliDemo = withSpinner "CLI Demo" $ do
20cliDemo = withSpinner "CLI Demo" $ do
18 putLog Notice "This demo will showcase the CLI library functionality"
21 putLog Notice "This demo will showcase the CLI library functionality"
19 _ <- withSpinner' "Searching long for something" (Just $ \c -> "Discovered " <> T.pack (show c) <> " objects") $ do
22 _ <- withSpinner' "Searching long for something" (Just $ \c -> "Discovered " <> T.pack (show c) <> " objects") $ do
@@ -40,7 +43,7 @@ cliDemo = withSpinner "CLI Demo" $ do
40 withSpinner "Looking around" $ do
43 withSpinner "Looking around" $ do
42 output <- readProcessAndLogStderr Notice $ proc "ls" ["-l", "/"]
45 output <- readProcessAndLogStderr Notice $ proc "ls" ["-l", "/"]
43− putLog Notice $ "Output was: " <> T.pack output
46+ putLog Notice $ "Output was: " <> output
45 callProcessAndLogOutput (Notice, Error) $ proc "ls" ["-l", "/does-not-exist"]
48 callProcessAndLogOutput (Notice, Error) $ proc "ls" ["-l", "/does-not-exist"]
lib/cliapp/src/Obelisk/CliApp/Logging.hs+43−16
@@ -4,11 +4,13 @@
4{-# LANGUAGE LambdaCase #-}
4{-# LANGUAGE LambdaCase #-}
5{-# LANGUAGE MultiParamTypeClasses #-}
5{-# LANGUAGE MultiParamTypeClasses #-}
6{-# LANGUAGE OverloadedStrings #-}
6{-# LANGUAGE OverloadedStrings #-}
7+{-# LANGUAGE RankNTypes #-}
7{-# LANGUAGE ScopedTypeVariables #-}
8{-# LANGUAGE ScopedTypeVariables #-}
8-- | Provides a logging handler that facilitates safe ouputting to terminal using MVar based locking.
9-- | Provides a logging handler that facilitates safe ouputting to terminal using MVar based locking.
9-- | Spinner.hs and Process.hs work on this guarantee.
10-- | Spinner.hs and Process.hs work on this guarantee.
10module Obelisk.CliApp.Logging
11module Obelisk.CliApp.Logging
12+ ( AsUnstructuredError (..)
11− ( newCliConfig
13+ , newCliConfig
13 , verboseLogLevel
15 , verboseLogLevel
14 , isOverwrite
16 , isOverwrite
@@ -18,6 +20,7 @@ module Obelisk.CliApp.Logging
19 , putLogRaw
21 , putLogRaw
20 , failWith
22 , failWith
21 , withExitFailMessage
24 , withExitFailMessage
22 , writeLog
25 , writeLog
23 , allowUserToMakeLoggingVerbose
26 , allowUserToMakeLoggingVerbose
@@ -27,9 +30,10 @@ module Obelisk.CliApp.Logging
28import Control.Concurrent (ThreadId, forkIO, killThread, threadDelay)
31import Control.Concurrent (ThreadId, forkIO, killThread, threadDelay)
29import Control.Concurrent.MVar (modifyMVar_, newMVar)
32import Control.Concurrent.MVar (modifyMVar_, newMVar)
33+import Control.Lens (Prism', review)
30import Control.Monad (unless, void, when)
34import Control.Monad (unless, void, when)
31import Control.Monad.Catch (MonadCatch, MonadMask, bracket, catch, throwM)
35import Control.Monad.Catch (MonadCatch, MonadMask, bracket, catch, throwM)
32−import Control.Monad.Except (MonadError, throwError)
36+import Control.Monad.Except (throwError)
33import Control.Monad.IO.Class (liftIO)
37import Control.Monad.IO.Class (liftIO)
34import Control.Monad.Log (Severity (..), WithSeverity (..), logMessage, runLoggingT)
38import Control.Monad.Log (Severity (..), WithSeverity (..), logMessage, runLoggingT)
35import Control.Monad.Loops (iterateUntil)
39import Control.Monad.Loops (iterateUntil)
@@ -48,17 +52,23 @@ import System.IO (BufferMode (NoBuffering), hFlush, hReady, hSetBuffering, stder
48import qualified Obelisk.CliApp.TerminalString as TS
52import qualified Obelisk.CliApp.TerminalString as TS
49import Obelisk.CliApp.Types
53import Obelisk.CliApp.Types
51−newCliConfig :: Severity -> Bool -> Bool -> IO CliConfig
55+newCliConfig
59+ -> (e -> (Text, Int))
52−newCliConfig sev noColor noSpinner = do
61+newCliConfig sev noColor noSpinner errorLogExitCode = do
53 level <- newIORef sev
62 level <- newIORef sev
54 lock <- newMVar False
63 lock <- newMVar False
55 tipDisplayed <- newIORef False
64 tipDisplayed <- newIORef False
56 stack <- newIORef ([], [])
65 stack <- newIORef ([], [])
57− return $ CliConfig level noColor noSpinner lock tipDisplayed stack
66+ return $ CliConfig level noColor noSpinner lock tipDisplayed stack errorLogExitCode
59−runCli :: MonadIO m => CliConfig -> CliT m a -> m a
68+runCli :: MonadIO m => CliConfig e -> CliT e m a -> m a
61 flip runLoggingT (handleLog c)
70 flip runLoggingT (handleLog c)
71+ . flip runReaderT (_cliConfig_errorLogExitCode c)
63 . flip runReaderT c
73 . flip runReaderT c
@@ -77,18 +87,18 @@ getSeverity = \case
77 Output_LogRaw (WithSeverity sev _) -> Just sev
87 Output_LogRaw (WithSeverity sev _) -> Just sev
78 _ -> Nothing
88 _ -> Nothing
80−getLogLevel :: (MonadIO m, HasCliConfig m) => m Severity
90+getLogLevel :: (MonadIO m, HasCliConfig e m) => m Severity
81getLogLevel = getLogLevel' =<< getCliConfig
91getLogLevel = getLogLevel' =<< getCliConfig
83−getLogLevel' :: MonadIO m => CliConfig -> m Severity
93+getLogLevel' :: MonadIO m => CliConfig e -> m Severity
84getLogLevel' = liftIO . readIORef . _cliConfig_logLevel
94getLogLevel' = liftIO . readIORef . _cliConfig_logLevel
86−setLogLevel :: (MonadIO m, HasCliConfig m) => Severity -> m ()
96+setLogLevel :: (MonadIO m, HasCliConfig e m) => Severity -> m ()
87setLogLevel sev = do
97setLogLevel sev = do
88 l <- _cliConfig_logLevel <$> getCliConfig
98 l <- _cliConfig_logLevel <$> getCliConfig
89 liftIO $ writeIORef l sev
99 liftIO $ writeIORef l sev
91−handleLog :: MonadIO m => CliConfig -> Output -> m ()
101+handleLog :: MonadIO m => CliConfig e -> Output -> m ()
92handleLog conf output = do
102handleLog conf output = do
93 level <- getLogLevel' conf
103 level <- getLogLevel' conf
94 liftIO $ modifyMVar_ (_cliConfig_lock conf) $ \wasOverwriting -> do
104 liftIO $ modifyMVar_ (_cliConfig_lock conf) $ \wasOverwriting -> do
@@ -126,17 +136,34 @@ handleLog' noColor output = do
126 return $ isOverwrite output
136 return $ isOverwrite output
128-- | Like `putLog` but without the implicit newline added.
138-- | Like `putLog` but without the implicit newline added.
129−putLogRaw :: Cli m => Severity -> Text -> m ()
139+putLogRaw :: CliLog m => Severity -> Text -> m ()
130putLogRaw sev = logMessage . Output_LogRaw . WithSeverity sev
140putLogRaw sev = logMessage . Output_LogRaw . WithSeverity sev
142+-- | Indicates unstructured errors form one variant (or conceptual projection)
143+-- of the error type.
145+-- Shouldn't really use this, but who has time to clean up that much!
146+class AsUnstructuredError e where
147+ asUnstructuredError :: Prism' e Text
149+instance AsUnstructuredError Text where
150+ asUnstructuredError = id
132-- | Like `putLog Alert` but also abrupts the program.
152-- | Like `putLog Alert` but also abrupts the program.
133−failWith :: MonadError Text m => Text -> m a
153+failWith :: (CliThrow e m, AsUnstructuredError e) => Text -> m a
134−failWith = throwError
154+failWith = throwError . review asUnstructuredError
157+ :: (HasCliConfig e m, CliThrow e m, CliLog m)
159+errorToWarning e = do
161+ putLog Warning $ fst $ _cliConfig_errorLogExitCode c e
136-- | Intercept ExitFailure exceptions and log the given alert before exiting.
163-- | Intercept ExitFailure exceptions and log the given alert before exiting.
138-- This is useful when you want to provide contextual information to a deeper failure.
165-- This is useful when you want to provide contextual information to a deeper failure.
139−withExitFailMessage :: (Cli m, MonadCatch m) => Text -> m a -> m a
166+withExitFailMessage :: (CliLog m, MonadCatch m) => Text -> m a -> m a
140withExitFailMessage msg f = f `catch` \(e :: ExitCode) -> do
167withExitFailMessage msg f = f `catch` \(e :: ExitCode) -> do
141 case e of
168 case e of
142 ExitFailure _ -> putLog Alert msg
169 ExitFailure _ -> putLog Alert msg
@@ -162,7 +189,7 @@ writeLog withNewLine noColor (WithSeverity severity s)
163-- Call this function in a thread, and kill it to turn off keystroke monitoring.
190-- Call this function in a thread, and kill it to turn off keystroke monitoring.
164allowUserToMakeLoggingVerbose
191allowUserToMakeLoggingVerbose
165− :: (MonadIO m, MonadMask m, Cli m, HasCliConfig m)
192+ :: (MonadIO m, MonadMask m, CliLog m, HasCliConfig e m)
166 => String -- ^ The key to press in order to make logging verbose
193 => String -- ^ The key to press in order to make logging verbose
168allowUserToMakeLoggingVerbose keyCode = bracket showTip (liftIO . killThread) $ \_ -> do
195allowUserToMakeLoggingVerbose keyCode = bracket showTip (liftIO . killThread) $ \_ -> do
@@ -195,7 +222,7 @@ getChars = reverse <$> f mempty
195 True -> f (x:xs)
222 True -> f (x:xs)
196 False -> return (x:xs)
223 False -> return (x:xs)
198−fork :: (HasCliConfig m, MonadIO m) => CliT IO () -> m ThreadId
225+fork :: (HasCliConfig e m, MonadIO m) => CliT e IO () -> m ThreadId
199fork f = do
226fork f = do
200 c <- getCliConfig
227 c <- getCliConfig
201 liftIO $ forkIO $ runCli c f
228 liftIO $ forkIO $ runCli c f
lib/cliapp/src/Obelisk/CliApp/Process.hs+73−38
@@ -9,25 +9,29 @@
9-- | An extension of `System.Process` that integrates with logging (`Obelisk.CLI.Logging`)
9-- | An extension of `System.Process` that integrates with logging (`Obelisk.CLI.Logging`)
10-- and is thus spinner friendly.
10-- and is thus spinner friendly.
11module Obelisk.CliApp.Process
11module Obelisk.CliApp.Process
12− ( ProcessFailed (..)
12+ ( ProcessFailure (..)
13+ , AsProcessFailure (..)
13 , readProcessAndLogStderr
14 , readProcessAndLogStderr
15+ , readProcessAndLogOutput
14 , callProcessAndLogOutput
16 , callProcessAndLogOutput
15 , createProcess
17 , createProcess
16 , createProcess_
18 , createProcess_
17 , callProcess
19 , callProcess
18 , callCommand
20 , callCommand
21−import Control.Applicative (liftA2)
24+import Control.Monad ((<=<), join, void)
22−import Control.Monad (void, (<=<))
23−import Control.Monad.Catch (Exception(..), MonadMask, throwM)
25+import Control.Monad.Except (throwError)
24import Control.Monad.IO.Class (MonadIO, liftIO)
26import Control.Monad.IO.Class (MonadIO, liftIO)
27+import Control.Lens (Prism', review)
28+import qualified Data.ByteString as BS
25import qualified Data.ByteString.Char8 as BSC
29import qualified Data.ByteString.Char8 as BSC
26import Data.Function (fix)
30import Data.Function (fix)
27import Data.Monoid ((<>))
31import Data.Monoid ((<>))
32+import Data.Text (Text)
28import qualified Data.Text as T
33import qualified Data.Text as T
29−import Data.Text.Encoding (decodeUtf8)
34+import qualified Data.Text.Encoding as T
30−import qualified Data.Text.IO as T
31import System.Exit (ExitCode (..))
35import System.Exit (ExitCode (..))
32import System.IO (Handle)
36import System.IO (Handle)
33import System.IO.Streams (InputStream, handleToInputStream)
37import System.IO.Streams (InputStream, handleToInputStream)
@@ -39,60 +43,90 @@ import qualified System.Process as Process
40import Control.Monad.Log (Severity (..))
44import Control.Monad.Log (Severity (..))
41import Obelisk.CliApp.Logging (putLog, putLogRaw)
45import Obelisk.CliApp.Logging (putLog, putLogRaw)
42−import Obelisk.CliApp.Types (Cli)
46+import Obelisk.CliApp.Types (CliLog, CliThrow)
48+-- TODO put back in `Obelisk.CliApp.Process` and use prisms for extensible exceptions
44−data ProcessFailed = ProcessFailed Process.CmdSpec Int -- exit code
49+data ProcessFailure = ProcessFailure Process.CmdSpec Int -- exit code
45 deriving Show
50 deriving Show
47−instance Exception ProcessFailed where
52+-- | Indicates arbitrary process failures form one variant (or conceptual projection) of
48− displayException (ProcessFailed spec exitCode) =
53+-- the error type.
49− unwords ["ProcessFailed", reconstructCommand spec, show exitCode]
54+class AsProcessFailure e where
55+ asProcessFailure :: Prism' e ProcessFailure
57+instance AsProcessFailure ProcessFailure where
58+ asProcessFailure = id
51readProcessAndLogStderr
60readProcessAndLogStderr
52− :: (MonadIO m, MonadMask m, Cli m)
61+ :: (MonadIO m, CliLog m, CliThrow e m, AsProcessFailure e)
53− => Severity -> CreateProcess -> m String
62+ => Severity -> CreateProcess -> m Text
54readProcessAndLogStderr sev process = do
63readProcessAndLogStderr sev process = do
55 (out, _err) <- withProcess process $ \_out err -> do
64 (out, _err) <- withProcess process $ \_out err -> do
56 streamToLog =<< liftIO (streamHandle sev err)
65 streamToLog =<< liftIO (streamHandle sev err)
57− -- TODO: Why are we using Text here?
58− liftIO $ T.unpack . T.strip <$> T.hGetContents out
66+ liftIO $ T.decodeUtf8 <$> BS.hGetContents out
60−-- | Like `System.Process.callProcess` but logs the combined output--stdout and stderr with the corresponding
68+-- | Like `System.Process.readProcess` but logs the combined output (stdout and stderr)
61−-- severity.
69+-- with the corresponding severity.
63−-- Usually this function is called as `callProcessAndLogOutput (Debug, Error)`. However some processes
71+-- Usually this function is called as `callProcessAndLogOutput (Debug, Error)`. However
72+-- some processes are known to spit out diagnostic or informative messages in stderr, in
73+-- which case it is advisable to call it with a non-Error severity for stderr, like
74+-- `callProcessAndLogOutput (Debug, Debug)`.
75+readProcessAndLogOutput
76+ :: (MonadIO m, CliLog m, CliThrow e m, AsProcessFailure e)
77+ => (Severity, Severity) -> CreateProcess -> m Text
78+readProcessAndLogOutput (sev_out, sev_err) process = do
79+ (_, Just out, Just err, p) <- createProcess $ process
80+ { std_out = CreatePipe , std_err = CreatePipe }
82+ -- TODO interleave stdout and stderr in log correctly
83+ streamToLog =<< liftIO (streamHandle sev_err err)
84+ outText <- liftIO $ T.decodeUtf8 <$> BS.hGetContents out
85+ putLogRaw sev_out outText
87+ liftIO (waitForProcess p) >>= \case
88+ ExitSuccess -> pure outText
89+ ExitFailure code -> throwError $ review asProcessFailure $ ProcessFailure (cmdspec process) code
91+-- | Like `System.Process.callProcess` but logs the combined output (stdout and stderr)
92+-- with the corresponding severity.
94+-- Usually this function is called as `callProcessAndLogOutput (Debug, Error)`. However
64−-- are known to spit out diagnostic or informative messages in stderr, in which case it is advisable to call
95+-- some processes are known to spit out diagnostic or informative messages in stderr, in
96+-- which case it is advisable to call it with a non-Error severity for stderr, like
65−-- it with a non-Error severity for stderr, like `callProcessAndLogOutput (Debug, Debug)`.
97+-- `callProcessAndLogOutput (Debug, Debug)`.
66callProcessAndLogOutput
98callProcessAndLogOutput
67− :: (MonadIO m, MonadMask m, Cli m)
99+
100+ :: (MonadIO m, CliLog m, CliThrow e m, AsProcessFailure e)
68 => (Severity, Severity) -> CreateProcess -> m ()
101 => (Severity, Severity) -> CreateProcess -> m ()
69−callProcessAndLogOutput (sev_out, sev_err) process = do
102+callProcessAndLogOutput (sev_out, sev_err) process =
70 void $ withProcess process $ \out err -> do
103 void $ withProcess process $ \out err -> do
71− stream <- liftIO $ do
104+ stream <- liftIO $ join $ combineStream
72− uncurry combineStream =<< liftA2 (,) (streamHandle sev_out out) (streamHandle sev_err err)
105+ <$> streamHandle sev_out out
106+ <*> streamHandle sev_err err
73 streamToLog stream
107 streamToLog stream
75 combineStream s1 s2 = concurrentMerge [s1, s2]
109 combineStream s1 s2 = concurrentMerge [s1, s2]
77-- | Like `System.Process.createProcess` but also logs (debug) the process being run
111-- | Like `System.Process.createProcess` but also logs (debug) the process being run
78createProcess
112createProcess
79− :: (MonadIO m, Cli m)
113+ :: (MonadIO m, CliLog m)
80 => CreateProcess -> m (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
114 => CreateProcess -> m (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
81createProcess p = do
115createProcess p = do
82− putLog Debug $ "Creating process: " <> T.pack (reconstructCommand (cmdspec p))
116+ putLog Debug $ "Creating process: " <> reconstructCommand (cmdspec p)
83 liftIO $ Process.createProcess p
117 liftIO $ Process.createProcess p
85-- | Like `System.Process.createProcess_` but also logs (debug) the process being run
119-- | Like `System.Process.createProcess_` but also logs (debug) the process being run
86createProcess_
120createProcess_
87− :: (MonadIO m, Cli m)
121+ :: (MonadIO m, CliLog m)
88 => String -> CreateProcess -> m (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
122 => String -> CreateProcess -> m (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
89createProcess_ name p = do
123createProcess_ name p = do
90− putLog Debug $ "Creating process " <> T.pack name <> ": " <> T.pack (reconstructCommand (cmdspec p))
124+ putLog Debug $ "Creating process " <> T.pack name <> ": " <> reconstructCommand (cmdspec p)
91 liftIO $ Process.createProcess p
125 liftIO $ Process.createProcess p
93-- | Like `System.Process.callProcess` but also logs (debug) the process being run
127-- | Like `System.Process.callProcess` but also logs (debug) the process being run
94callProcess
128callProcess
95− :: (MonadIO m, Cli m)
129+ :: (MonadIO m, CliLog m)
96 => String -> [String] -> m ()
130 => String -> [String] -> m ()
97callProcess exe args = do
131callProcess exe args = do
98 putLog Debug $ "Calling process " <> T.pack exe <> " with args: " <> T.pack (show args)
132 putLog Debug $ "Calling process " <> T.pack exe <> " with args: " <> T.pack (show args)
@@ -100,14 +134,14 @@ callProcess exe args = do
101-- | Like `System.Process.callCommand` but also logs (debug) the command being run
135-- | Like `System.Process.callCommand` but also logs (debug) the command being run
102callCommand
136callCommand
103− :: (MonadIO m, Cli m)
137+ :: (MonadIO m, CliLog m)
104 => String -> m ()
138 => String -> m ()
105callCommand cmd = do
139callCommand cmd = do
106 putLog Debug $ "Calling command " <> T.pack cmd
140 putLog Debug $ "Calling command " <> T.pack cmd
107 liftIO $ Process.callCommand cmd
141 liftIO $ Process.callCommand cmd
109withProcess
143withProcess
110− :: (MonadIO m, MonadMask m, Cli m)
144+ :: (MonadIO m, CliLog m, CliThrow e m, AsProcessFailure e)
111 => CreateProcess -> (Handle -> Handle -> m ()) -> m (Handle, Handle)
145 => CreateProcess -> (Handle -> Handle -> m ()) -> m (Handle, Handle)
112withProcess process f = do -- TODO: Use bracket.
146withProcess process f = do -- TODO: Use bracket.
113 -- FIXME: Using `withCreateProcess` here leads to something operating illegally on closed handles.
147 -- FIXME: Using `withCreateProcess` here leads to something operating illegally on closed handles.
@@ -118,7 +152,7 @@ withProcess process f = do -- TODO: Use bracket.
119 liftIO (waitForProcess p) >>= \case
153 liftIO (waitForProcess p) >>= \case
120 ExitSuccess -> return (out, err)
154 ExitSuccess -> return (out, err)
121− ExitFailure code -> throwM $ ProcessFailed (cmdspec process) code
155+ ExitFailure code -> throwError $ review asProcessFailure $ ProcessFailure (cmdspec process) code
123-- Create an input stream from the file handle, associating each item with the given severity.
157-- Create an input stream from the file handle, associating each item with the given severity.
124streamHandle :: Severity -> Handle -> IO (InputStream (Severity, BSC.ByteString))
158streamHandle :: Severity -> Handle -> IO (InputStream (Severity, BSC.ByteString))
@@ -126,16 +160,17 @@ streamHandle sev = Streams.map (sev,) <=< handleToInputStream
127-- | Read from an input stream and log its contents
161-- | Read from an input stream and log its contents
128streamToLog
162streamToLog
129− :: (MonadIO m, MonadMask m, Cli m)
163+ :: (MonadIO m, CliLog m)
130 => InputStream (Severity, BSC.ByteString) -> m ()
164 => InputStream (Severity, BSC.ByteString) -> m ()
131streamToLog stream = fix $ \loop -> do
165streamToLog stream = fix $ \loop -> do
132 liftIO (Streams.read stream) >>= \case
166 liftIO (Streams.read stream) >>= \case
133 Nothing -> return ()
167 Nothing -> return ()
134− Just (sev, line) -> putLogRaw sev (decodeUtf8 line) >> loop
168+ Just (sev, line) -> putLogRaw sev (T.decodeUtf8 line) >> loop
170+-- | Pretty print a 'CmdSpec'
136−reconstructCommand :: Process.CmdSpec -> String
171+reconstructCommand :: Process.CmdSpec -> Text
137−reconstructCommand (Process.ShellCommand str) = str
172+reconstructCommand (Process.ShellCommand str) = T.pack str
138reconstructCommand (Process.RawCommand c as) = processToShellString c as
173reconstructCommand (Process.RawCommand c as) = processToShellString c as
140− processToShellString cmd args = unwords $ map quoteAndEscape (cmd : args)
175+ processToShellString cmd args = T.unwords $ map quoteAndEscape (cmd : args)
141− quoteAndEscape x = T.unpack $ "'" <> T.replace "'" "'\''" (T.pack x) <> "'"
176+ quoteAndEscape x = "'" <> T.replace "'" "'\''" (T.pack x) <> "'"
lib/cliapp/src/Obelisk/CliApp/Spinner.hs+4−4
@@ -24,11 +24,11 @@ import System.Console.ANSI (Color (Blue, Cyan, Green, Red))
25import Obelisk.CliApp.Logging (allowUserToMakeLoggingVerbose, fork, putLog)
25import Obelisk.CliApp.Logging (allowUserToMakeLoggingVerbose, fork, putLog)
26import Obelisk.CliApp.TerminalString (TerminalString (..), enquiryCode)
26import Obelisk.CliApp.TerminalString (TerminalString (..), enquiryCode)
27−import Obelisk.CliApp.Types (Cli, CliConfig (..), HasCliConfig, Output (..), getCliConfig)
27+import Obelisk.CliApp.Types (CliLog, CliConfig (..), HasCliConfig, Output (..), getCliConfig)
29-- | Run an action with a CLI spinner.
29-- | Run an action with a CLI spinner.
30withSpinner
30withSpinner
31− :: (MonadIO m, MonadMask m, Cli m, HasCliConfig m)
31+ :: (MonadIO m, MonadMask m, CliLog m, HasCliConfig e m)
32 => Text -> m a -> m a
32 => Text -> m a -> m a
33withSpinner s = withSpinner' s $ Just $ const s
33withSpinner s = withSpinner' s $ Just $ const s
@@ -39,13 +39,13 @@ withSpinner s = withSpinner' s $ Just $ const s
39-- The 'no trail' property automatically carries over to sub-spinners (in that
39-- The 'no trail' property automatically carries over to sub-spinners (in that
40-- they won't leave a trail either).
40-- they won't leave a trail either).
41withSpinnerNoTrail
41withSpinnerNoTrail
42− :: (MonadIO m, MonadMask m, Cli m, HasCliConfig m)
42+ :: (MonadIO m, MonadMask m, CliLog m, HasCliConfig e m)
43 => Text -> m a -> m a
43 => Text -> m a -> m a
44withSpinnerNoTrail s = withSpinner' s Nothing
44withSpinnerNoTrail s = withSpinner' s Nothing
46-- | Advanced version that controls the display and content of the trail message.
46-- | Advanced version that controls the display and content of the trail message.
47withSpinner'
47withSpinner'
48− :: (MonadIO m, MonadMask m, Cli m, HasCliConfig m)
48+ :: (MonadIO m, MonadMask m, CliLog m, HasCliConfig e m)
50 -> Maybe (a -> Text) -- ^ Leave an optional trail with the given message creator
50 -> Maybe (a -> Text) -- ^ Leave an optional trail with the given message creator
lib/cliapp/src/Obelisk/CliApp/Types.hs+38−26
@@ -1,14 +1,18 @@
1{-# LANGUAGE ConstraintKinds #-}
1{-# LANGUAGE ConstraintKinds #-}
2{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleInstances #-}
3{-# LANGUAGE FlexibleInstances #-}
4+{-# LANGUAGE FunctionalDependencies #-}
5+{-# LANGUAGE LambdaCase #-}
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8+{-# LANGUAGE OverloadedStrings #-}
9+{-# LANGUAGE UndecidableInstances #-}
6module Obelisk.CliApp.Types where
10module Obelisk.CliApp.Types where
8import Control.Concurrent.MVar (MVar)
12import Control.Concurrent.MVar (MVar)
9import Control.Monad.Catch (MonadCatch, MonadMask, MonadThrow)
13import Control.Monad.Catch (MonadCatch, MonadMask, MonadThrow)
10import Control.Monad.Log (LoggingT, MonadLog, Severity (..), WithSeverity (..), logMessage)
14import Control.Monad.Log (LoggingT, MonadLog, Severity (..), WithSeverity (..), logMessage)
11−import Control.Monad.Reader (MonadIO, ReaderT (..), MonadReader, ask)
15+import Control.Monad.Reader (MonadIO, ReaderT (..), MonadReader (..), ask, mapReaderT)
12import Control.Monad.Writer (WriterT)
16import Control.Monad.Writer (WriterT)
13import Control.Monad.State (StateT)
17import Control.Monad.State (StateT)
14import Control.Monad.Except (ExceptT, MonadError (..))
18import Control.Monad.Except (ExceptT, MonadError (..))
@@ -32,40 +36,44 @@ data Output
33type CliLog m = MonadLog Output m
37type CliLog m = MonadLog Output m
35−type CliThrow m = MonadError Text m
39+type CliThrow e m = MonadError e m
37−-- TODO could remove for granularity
38−type Cli m = (CliLog m, CliThrow m)
40-- | Log a message to the console.
41-- | Log a message to the console.
42-- Logs safely even if there are ongoing spinners.
43-- Logs safely even if there are ongoing spinners.
43−putLog :: Cli m => Severity -> Text -> m ()
44+putLog :: CliLog m => Severity -> Text -> m ()
44putLog sev = logMessage . Output_Log . WithSeverity sev
45putLog sev = logMessage . Output_Log . WithSeverity sev
46−newtype DieT m a = DieT { unDieT :: LoggingT Output m a }
47+newtype DieT e m a = DieT { unDieT :: ReaderT (e -> (Text, Int)) (LoggingT Output m) a }
48 ( Functor, Applicative, Monad, MonadIO
49 ( Functor, Applicative, Monad, MonadIO
50 , MonadThrow, MonadCatch, MonadMask
50 , MonadThrow, MonadCatch, MonadMask
51 , MonadLog Output
51 , MonadLog Output
54−instance MonadTrans DieT where
54+instance MonadTrans (DieT e) where
55− lift = DieT . lift
55+ lift = DieT . lift . lift
57+-- | Error printer is private to DieT
58+instance MonadReader r m => MonadReader r (DieT e m) where
59+ ask = DieT $ lift $ ask
60+ local = (\f (DieT a) -> DieT $ f a) . mapReaderT . local
61+ reader = DieT . lift . lift . reader
57-- TODO generalize to bigger error types
63-- TODO generalize to bigger error types
58−instance MonadIO m => MonadError Text (DieT m) where
64+instance MonadIO m => MonadError e (DieT e m) where
59− throwError s = do
65+ throwError e = do
67+ let (output, exitCode) = handler e
60− putLog Alert s
68+ putLog Alert output
61− liftIO $ exitWith $ ExitFailure 2
69+ liftIO $ exitWith $ ExitFailure exitCode
63 -- Cannot catch
71 -- Cannot catch
64 catchError m _ = m
72 catchError m _ = m
66--------------------------------------------------------------------------------
74--------------------------------------------------------------------------------
68−data CliConfig = CliConfig
76+data CliConfig e = CliConfig
69 { -- | We are capable of changing the log level at runtime
77 { -- | We are capable of changing the log level at runtime
70 _cliConfig_logLevel :: IORef Severity
78 _cliConfig_logLevel :: IORef Severity
71 , -- | Disallow coloured output
79 , -- | Disallow coloured output
@@ -78,36 +86,40 @@ data CliConfig = CliConfig
78 _cliConfig_tipDisplayed :: IORef Bool
86 _cliConfig_tipDisplayed :: IORef Bool
79 , -- | Stack of logs from nested spinners
87 , -- | Stack of logs from nested spinners
80 _cliConfig_spinnerStack :: IORef ([Bool], [TerminalString])
88 _cliConfig_spinnerStack :: IORef ([Bool], [TerminalString])
89+ , -- | Failure handler. How to log error and what exit status to use.
90+ _cliConfig_errorLogExitCode :: e -> (Text, Int)
83−class Monad m => HasCliConfig m where
93+class Monad m => HasCliConfig e m | m -> e where
84− getCliConfig :: m CliConfig
94+ getCliConfig :: m (CliConfig e)
86−instance HasCliConfig m => HasCliConfig (ReaderT r m) where
96+instance HasCliConfig e m => HasCliConfig e (ReaderT r m) where
87 getCliConfig = lift getCliConfig
97 getCliConfig = lift getCliConfig
89−instance (Monoid w, HasCliConfig m) => HasCliConfig (WriterT w m) where
99+instance (Monoid w, HasCliConfig e m) => HasCliConfig e (WriterT w m) where
90 getCliConfig = lift getCliConfig
100 getCliConfig = lift getCliConfig
92−instance HasCliConfig m => HasCliConfig (StateT s m) where
102+instance HasCliConfig e m => HasCliConfig e (StateT s m) where
93 getCliConfig = lift getCliConfig
103 getCliConfig = lift getCliConfig
95−instance HasCliConfig m => HasCliConfig (ExceptT e m) where
105+instance HasCliConfig e m => HasCliConfig e (ExceptT e m) where
96 getCliConfig = lift getCliConfig
106 getCliConfig = lift getCliConfig
98--------------------------------------------------------------------------------
108--------------------------------------------------------------------------------
100−newtype CliT m a = CliT
110+newtype CliT e m a = CliT
101− { unCliT :: ReaderT CliConfig (DieT m) a
111+ { unCliT :: ReaderT (CliConfig e) (DieT e m) a
104 ( Functor, Applicative, Monad, MonadIO
114 ( Functor, Applicative, Monad, MonadIO
105 , MonadThrow, MonadCatch, MonadMask
115 , MonadThrow, MonadCatch, MonadMask
116+ , MonadLog Output -- CliLog
117+ , MonadError e -- CliThrow
106− , MonadLog Output, MonadError Text, MonadReader CliConfig
118+ , MonadReader (CliConfig e) -- HasCliConfig
109−instance MonadTrans CliT where
121+instance MonadTrans (CliT e) where
110 lift = CliT . lift . lift
122 lift = CliT . lift . lift
112−instance Monad m => HasCliConfig (CliT m) where
124+instance Monad m => HasCliConfig e (CliT e m)where
113 getCliConfig = ask
125 getCliConfig = ask
lib/command/obelisk-command.cabal+1−3
@@ -15,7 +15,6 @@ library
16 , bytestring
16 , bytestring
17 , obelisk-cliapp
17 , obelisk-cliapp
19 , containers
18 , containers
20 , data-default
19 , data-default
21 , directory
20 , directory
@@ -32,6 +31,7 @@ library
32 , modern-uri
31 , modern-uri
33 , monad-loops
32 , monad-loops
36 , network-uri
36 , network-uri
37 , optparse-applicative
37 , optparse-applicative
@@ -52,8 +52,6 @@ library
52 Obelisk.Command.Project
52 Obelisk.Command.Project
53 Obelisk.Command.Run
53 Obelisk.Command.Run
54 Obelisk.Command.Thunk
54 Obelisk.Command.Thunk
55− Obelisk.Command.Upgrade
56− Obelisk.Command.Upgrade.Hash
57 Obelisk.Command.Utils
55 Obelisk.Command.Utils
58 Obelisk.Command.VmBuilder
56 Obelisk.Command.VmBuilder
59 -- -fobject-code is so that the StaticPointers extension can work in ghci
57 -- -fobject-code is so that the StaticPointers extension can work in ghci
lib/command/src/Obelisk/App.hs+47−7
@@ -2,11 +2,15 @@
2{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleInstances #-}
3{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5+{-# LANGUAGE LambdaCase #-}
5{-# LANGUAGE MultiParamTypeClasses #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
6{-# LANGUAGE ScopedTypeVariables #-}
7{-# LANGUAGE ScopedTypeVariables #-}
7{-# LANGUAGE StandaloneDeriving #-}
8{-# LANGUAGE StandaloneDeriving #-}
9+{-# LANGUAGE TemplateHaskell #-}
10+{-# LANGUAGE TupleSections #-}
8module Obelisk.App where
11module Obelisk.App where
10import Control.Monad.Catch (MonadCatch, MonadMask, MonadThrow)
14import Control.Monad.Catch (MonadCatch, MonadMask, MonadThrow)
11import Control.Monad.Reader (MonadIO, ReaderT (..), ask, runReaderT)
15import Control.Monad.Reader (MonadIO, ReaderT (..), ask, runReaderT)
12import Control.Monad.Writer (WriterT)
16import Control.Monad.Writer (WriterT)
@@ -17,18 +21,50 @@ import Data.Text (Text)
17import System.Directory (XdgDirectory (XdgData), getXdgDirectory)
21import System.Directory (XdgDirectory (XdgData), getXdgDirectory)
18import Control.Monad.Log (MonadLog)
22import Control.Monad.Log (MonadLog)
20−import Obelisk.CliApp (CliConfig, CliLog, CliThrow, CliT (..), HasCliConfig, runCli, Output)
24+import Obelisk.CliApp
30+ , AsProcessFailure (..)
31+ , AsUnstructuredError (..)
38+ = ObeliskError_ProcessError
39+ { obeliskError_err :: ProcessFailure
40+ , obeliskError_mAnn :: Maybe Text
42+ | ObeliskError_Unstructured Text
44+makePrisms ''ObeliskError
46+instance AsUnstructuredError ObeliskError where
47+ asUnstructuredError = _ObeliskError_Unstructured
49+-- Only project when the other field is null, otherwise we are not law abiding.
50+instance AsProcessFailure ObeliskError where
51+ asProcessFailure = _ObeliskError_ProcessError . prism (, Nothing) f
53+ (pf, Nothing) -> Right pf
54+ pann@(_, Just _) -> Left pann
22newtype Obelisk = Obelisk
56newtype Obelisk = Obelisk
23− { _obelisk_cliConfig :: CliConfig
57+ { _obelisk_cliConfig :: CliConfig ObeliskError
26newtype ObeliskT m a = ObeliskT
60newtype ObeliskT m a = ObeliskT
27− { unObeliskT :: ReaderT Obelisk (CliT m) a
61+ { unObeliskT :: ReaderT Obelisk (CliT ObeliskError m) a
30 ( Functor, Applicative, Monad, MonadIO, MonadThrow, MonadCatch, MonadMask
64 ( Functor, Applicative, Monad, MonadIO, MonadThrow, MonadCatch, MonadMask
31− , MonadLog Output, MonadError Text, HasCliConfig)
65+ , MonadLog Output -- CliLog
66+ , MonadError ObeliskError -- CliThrow ObeliskError
67+ , HasCliConfig ObeliskError)
33instance MonadTrans ObeliskT where
69instance MonadTrans ObeliskT where
34 lift = ObeliskT . lift . lift
70 lift = ObeliskT . lift . lift
@@ -57,14 +93,18 @@ runObelisk c =
57 . flip runReaderT c
93 . flip runReaderT c
58 . unObeliskT
94 . unObeliskT
60−type MonadObelisk m =
96+type MonadInfallibleObelisk m =
61 ( CliLog m
97 ( CliLog m
63− , HasCliConfig m
98+ , HasCliConfig ObeliskError m
64 , HasObelisk m
99 , HasObelisk m
65 , MonadIO m
100 , MonadIO m
66 , MonadMask m
101 , MonadMask m
104+type MonadObelisk m =
105+ ( MonadInfallibleObelisk m
106+ , CliThrow ObeliskError m
69getObeliskUserStateDir :: IO FilePath
109getObeliskUserStateDir :: IO FilePath
70getObeliskUserStateDir = getXdgDirectory XdgData "obelisk"
110getObeliskUserStateDir = getXdgDirectory XdgData "obelisk"
lib/command/src/Obelisk/Command.hs+44−112
@@ -8,15 +8,13 @@
8module Obelisk.Command where
8module Obelisk.Command where
10import Control.Monad
10import Control.Monad
11−import Control.Monad.Catch (catch)
12import Control.Monad.IO.Class (liftIO)
11import Control.Monad.IO.Class (liftIO)
13import qualified Data.Binary as Binary
12import qualified Data.Binary as Binary
14import Data.Bool (bool)
13import Data.Bool (bool)
15import qualified Data.ByteString.Base16 as Base16
14import qualified Data.ByteString.Base16 as Base16
16import qualified Data.ByteString.Lazy as LBS
15import qualified Data.ByteString.Lazy as LBS
17import Data.List
16import Data.List
18−import Data.Maybe (catMaybes, listToMaybe)
17+import Data.Maybe (catMaybes)
19−import Data.Text (Text)
20import qualified Data.Text as T
18import qualified Data.Text as T
21import Data.Text.Encoding
19import Data.Text.Encoding
22import GHC.StaticPtr
20import GHC.StaticPtr
@@ -35,11 +33,8 @@ import Obelisk.Command.Deploy
35import Obelisk.Command.Project
33import Obelisk.Command.Project
36import Obelisk.Command.Run
34import Obelisk.Command.Run
37import Obelisk.Command.Thunk
35import Obelisk.Command.Thunk
38−import Obelisk.Command.Upgrade
39−import Obelisk.Command.Upgrade.Hash (getDirectoryHash, getHashAtGitRevision)
40import Obelisk.Command.Utils
36import Obelisk.Command.Utils
41import qualified Obelisk.Command.VmBuilder as VmBuilder
37import qualified Obelisk.Command.VmBuilder as VmBuilder
42−import Obelisk.Migration (Hash)
45data Args = Args
40data Args = Args
@@ -96,16 +91,11 @@ data ObCommand
96 | ObCommand_Thunk ThunkCommand
91 | ObCommand_Thunk ThunkCommand
97 | ObCommand_Repl
92 | ObCommand_Repl
98 | ObCommand_Watch
93 | ObCommand_Watch
99− | ObCommand_Upgrade (Maybe Text)
100 | ObCommand_Internal ObInternal
94 | ObCommand_Internal ObInternal
101 deriving Show
95 deriving Show
103data ObInternal
97data ObInternal
104 = ObInternal_RunStaticIO StaticKey
98 = ObInternal_RunStaticIO StaticKey
105− | ObInternal_Hash (Maybe Text)
106− | ObInternal_CreateMigration
107− | ObInternal_VerifyMigration
108− | ObInternal_Migrate Hash
109 | ObInternal_CLIDemo
99 | ObInternal_CLIDemo
110 deriving Show
100 deriving Show
@@ -136,7 +126,6 @@ obCommand cfg = hsubparser
136 , command "thunk" $ info (ObCommand_Thunk <$> thunkCommand) $ progDesc "Manipulate thunk directories"
126 , command "thunk" $ info (ObCommand_Thunk <$> thunkCommand) $ progDesc "Manipulate thunk directories"
137 , command "repl" $ info (pure ObCommand_Repl) $ progDesc "Open an interactive interpreter"
127 , command "repl" $ info (pure ObCommand_Repl) $ progDesc "Open an interactive interpreter"
138 , command "watch" $ info (pure ObCommand_Watch) $ progDesc "Watch current project for errors and warnings"
128 , command "watch" $ info (pure ObCommand_Watch) $ progDesc "Watch current project for errors and warnings"
139− , command "upgrade" $ info (ObCommand_Upgrade <$> argument (maybeReader $ Just . Just . T.pack) (action "branch" <> metavar "GITBRANCH" <> value Nothing <> help "Git branch of obelisk to update to (defaults to the thunk's branch)")) $ progDesc "Upgrade Obelisk in the project"
141 <|> subparser
130 <|> subparser
@@ -182,7 +171,6 @@ deployInitOpts = DeployInitOpts
182 <*> strOption (long "route" <> metavar "PUBLICROUTE" <> help "Publicly accessible URL of your app")
171 <*> strOption (long "route" <> metavar "PUBLICROUTE" <> help "Publicly accessible URL of your app")
183 <*> strOption (long "admin-email" <> metavar "ADMINEMAIL" <> help "Email address where administrative alerts will be sent")
172 <*> strOption (long "admin-email" <> metavar "ADMINEMAIL" <> help "Email address where administrative alerts will be sent")
184 <*> flag True False (long "disable-https" <> help "Disable automatic https configuration for the backend")
173 <*> flag True False (long "disable-https" <> help "Disable automatic https configuration for the backend")
185− <*> strOption (long "upstream" <> value "origin" <> metavar "REMOTE" <> help "git remote to use for the src thunk" <> showDefault)
187type TeamID = String
175type TeamID = String
188data PlatformDeployment = Android | IOS TeamID
176data PlatformDeployment = Android | IOS TeamID
@@ -205,17 +193,12 @@ data DeployInitOpts = DeployInitOpts
205 , _deployInitOpts_route :: String
193 , _deployInitOpts_route :: String
206 , _deployInitOpts_adminEmail :: String
194 , _deployInitOpts_adminEmail :: String
207 , _deployInitOpts_enableHttps :: Bool
195 , _deployInitOpts_enableHttps :: Bool
208− , _deployInitOpts_remote :: String
210 deriving Show
197 deriving Show
212internalCommand :: Parser ObInternal
199internalCommand :: Parser ObInternal
213internalCommand = subparser $ mconcat
200internalCommand = subparser $ mconcat
214 [ command "run-static-io" $ info (ObInternal_RunStaticIO <$> argument (eitherReader decodeStaticKey) (action "static-key")) mempty
201 [ command "run-static-io" $ info (ObInternal_RunStaticIO <$> argument (eitherReader decodeStaticKey) (action "static-key")) mempty
215− , command "hash" $ info (ObInternal_Hash <$> argument (maybeReader $ Just . Just . T.pack) (action "rev" <> metavar "GITREVISION" <> value Nothing <> help "Calculate for the specified git revision (defaults to working copy")) $ progDesc "Computes hash of working directory (or git revision)"
216− , command "create-migration" $ info (pure ObInternal_CreateMigration) mempty
217− , command "verify-migration" $ info (pure ObInternal_VerifyMigration) mempty
218− , command "migrate" $ info (ObInternal_Migrate <$> strArgument (action "fromHash" <> metavar "FROMHASH" <> help "Migrate from this hash")) $ progDesc "Perform a migrate from the given hash to HEAD of obelisk thunk"
219 , command "clidemo" $ info (pure ObInternal_CLIDemo) mempty
202 , command "clidemo" $ info (pure ObInternal_CLIDemo) mempty
@@ -227,32 +210,17 @@ thunkDirectoryParser = fmap (dropTrailingPathSeparator . normalise) . strArgumen
227 , help "Path to directory containing thunk data"
210 , help "Path to directory containing thunk data"
230−data ThunkPackOpts = ThunkPackOpts
231− { _thunkPackOpts_directory :: FilePath
232− , _thunkPackOpts_upstream :: String
236data ThunkCommand
213data ThunkCommand
237 = ThunkCommand_Update [FilePath]
214 = ThunkCommand_Update [FilePath]
238 | ThunkCommand_Unpack [FilePath]
215 | ThunkCommand_Unpack [FilePath]
239− | ThunkCommand_Pack [ThunkPackOpts]
216+ | ThunkCommand_Pack [FilePath]
240 deriving Show
217 deriving Show
242−thunkPackOpts :: Parser ThunkPackOpts
243−thunkPackOpts = (ThunkPackOpts <$> thunkDirectoryParser <*>) . strOption $ mconcat
247− , help "Git remote that packed thunk will point to"
251thunkCommand :: Parser ThunkCommand
219thunkCommand :: Parser ThunkCommand
252thunkCommand = hsubparser $ mconcat
220thunkCommand = hsubparser $ mconcat
253 [ command "update" $ info (ThunkCommand_Update <$> some thunkDirectoryParser) $ progDesc "Update thunk to latest revision available"
221 [ command "update" $ info (ThunkCommand_Update <$> some thunkDirectoryParser) $ progDesc "Update thunk to latest revision available"
254 , command "unpack" $ info (ThunkCommand_Unpack <$> some thunkDirectoryParser) $ progDesc "Unpack thunk into git checkout of revision it points to"
222 , command "unpack" $ info (ThunkCommand_Unpack <$> some thunkDirectoryParser) $ progDesc "Unpack thunk into git checkout of revision it points to"
255− , command "pack" $ info (ThunkCommand_Pack <$> some thunkPackOpts) $ progDesc "Pack git checkout into thunk that points at given upstream"
223+ , command "pack" $ info (ThunkCommand_Pack <$> some thunkDirectoryParser) $ progDesc "Pack git checkout into thunk that points at the current branch's upstream"
258parserPrefs :: ParserPrefs
226parserPrefs :: ParserPrefs
@@ -270,7 +238,22 @@ mkObeliskConfig = do
270 -- This function should not use argument parser (full argument parsing happens post handoff)
238 -- This function should not use argument parser (full argument parsing happens post handoff)
271 let logLevel = toLogLevel $ "-v" `elem` cliArgs
239 let logLevel = toLogLevel $ "-v" `elem` cliArgs
272 notInteractive <- not <$> isInteractiveTerm
240 notInteractive <- not <$> isInteractiveTerm
241+-- instance MonadIO m => MonadError (Either Text ProcessFailed) (DieT m) where
242+-- throwError = \case
245+-- liftIO $ exitWith $ ExitFailure 2
246+-- Right (ProcessFailed p code) -> do
247+-- putLog Alert $ "Process exited with code " <> T.pack (show code) <> "; " <> T.pack (show p)
248+-- liftIO $ exitWith $ ExitFailure 2
273− cliConf <- newCliConfig logLevel notInteractive notInteractive
249+ cliConf <- newCliConfig logLevel notInteractive notInteractive $ \case
250+ ObeliskError_ProcessError (ProcessFailure p code) ann ->
251+ ( "Process exited with code " <> T.pack (show code) <> "; " <> reconstructCommand p
252+ <> maybe "" ("\n\n" <>) ann
255+ ObeliskError_Unstructured msg -> (msg, 2)
274 return $ Obelisk cliConf
257 return $ Obelisk cliConf
276 toLogLevel = bool Notice Debug
259 toLogLevel = bool Notice Debug
@@ -308,67 +291,29 @@ main' argsCfg = do
308 , "logging-level=" <> show logLevel
291 , "logging-level=" <> show logLevel
311− (mainWithHandOff argsCfg <=< parseHandoff) =<< liftIO getArgs
294+ --TODO: We'd like to actually use the parser to determine whether to hand off,
312− `catch`
295+ --but in the case where this implementation of 'ob' doesn't support all
313− \(ProcessFailed p code) -> failWith $ "Process exited with code " <> tshow code <> "; " <> tshow p
296+ --arguments being passed along, this could fail. For now, we don't bother
314−
297+ --with optparse-applicative until we've done the handoff.
315−-- Type representing the result of a handoff calculation.
298+ let go as = do
316−data HandOff m
299+ args' <- liftIO $ handleParseResult (execParserPure parserPrefs (argsInfo argsCfg) as)
317− = HandOff_Yes FilePath [String] -- Handoff immediately to the given impl with the given args
318− | HandOff_Decide (m Bool) FilePath [String] -- Handoff only if the action returns True
319− | HandOff_No [String] -- Do not handoff, and continue with the given args
321−mainWithHandOff :: MonadObelisk m => ArgsConfig -> HandOff m -> m ()
322−mainWithHandOff argsCfg = \case
323− HandOff_Yes impl as -> do
324− putLog Debug $ "Handing off to project obelisk " <> T.pack impl
325− liftIO $ executeFile impl False ("--no-handoff" : as) Nothing
326− HandOff_Decide f impl as -> do
327− withSpinner' "Deciding whether to handoff"
329− "Continuing in ambient obelisk without handing off"
330− "Handed off to project obelisk") f >>= \case
331− True -> mainWithHandOff argsCfg $ HandOff_Yes impl as
332− False -> mainWithHandOff argsCfg $ HandOff_No as
334− putLog Debug $ "Not handing off"
335− args' <- liftIO $ parseCLIArgs argsCfg as
336− warnIfExtraneousFlag args'
337− ob $ _args_command args'
339− warnIfExtraneousFlag a = case _args_noHandOffPassed a of
300+ case _args_noHandOffPassed args' of
340− False -> return ()
301+ False -> return ()
341− True -> putLog Warning $
342− "Ignoring unexpected --no-handoff (should only be passed once and as the first argument)"
302+ True -> putLog Warning "--no-handoff should only be passed once and as the first argument; ignoring"
343−
303+ ob $ _args_command args'
345−parseHandoff :: MonadObelisk m => [String] -> m (HandOff m)
346−parseHandoff as' = case hasNoHandoff as' of
348− pure $ HandOff_No as
349− (False, as) -> findProjectObeliskCommand "." >>= \case
304+ handoffAndGo as = findProjectObeliskCommand "." >>= \case
350− Nothing -> do
305+ Nothing -> go as -- If not in a project, just run ourselves
351− putLog Debug "Not in a project; no need to hand off"
352− pure $ HandOff_No as
353− Just impl -> case getSubCommand as of
306+ Just impl -> do
354− Just "upgrade" ->
307+ -- Invoke the real implementation, using --no-handoff to prevent infinite recursion
355− pure $ HandOff_Decide (decideHandOffToProjectOb ".") impl as
308+ putLog Debug $ "Handing off to " <> T.pack impl
356− _ ->
309+ liftIO $ executeFile impl False ("--no-handoff" : myArgs) Nothing
357− pure $ HandOff_Yes impl as
310+ case myArgs of
359− getSubCommand = listToMaybe . filter (not . isPrefixOf "-")
360− hasNoHandoff = \case
361− "--no-handoff" : xs ->
362− -- If we've been told not to hand off, don't hand off
311+ "--no-handoff" : as -> go as -- If we've been told not to hand off, don't hand off
365− -- Otherwise bash completion would always hand-off even if the user isn't trying to
312+ a:as -- Otherwise bash completion would always hand-off even if the user isn't trying to
366− | "--bash-completion" `isPrefixOf` x && "--no-handoff" `elem` xs ->
313+ | "--bash-completion" `isPrefixOf` a
367− (True, x:xs)
314+ && "--no-handoff" `elem` as -> go (a:as)
368− | otherwise ->
315+ | otherwise -> handoffAndGo (a:as)
369− (False, x:xs)
316+ as -> handoffAndGo as
373ob :: MonadObelisk m => ObCommand -> m ()
318ob :: MonadObelisk m => ObCommand -> m ()
374ob = \case
319ob = \case
@@ -390,7 +335,7 @@ ob = \case
390 Right (ThunkData_Packed ptr) -> return ptr
335 Right (ThunkData_Packed ptr) -> return ptr
391 Right (ThunkData_Checkout (Just ptr)) -> return ptr
336 Right (ThunkData_Checkout (Just ptr)) -> return ptr
392 Right (ThunkData_Checkout Nothing) ->
337 Right (ThunkData_Checkout Nothing) ->
393− getThunkPtr' False root (T.pack $ _deployInitOpts_remote deployOpts)
338+ getThunkPtr' False root
394 let sshKeyPath = _deployInitOpts_sshKey deployOpts
339 let sshKeyPath = _deployInitOpts_sshKey deployOpts
395 hostname = _deployInitOpts_hostname deployOpts
340 hostname = _deployInitOpts_hostname deployOpts
396 route = _deployInitOpts_route deployOpts
341 route = _deployInitOpts_route deployOpts
@@ -411,28 +356,15 @@ ob = \case
411 ObCommand_Thunk tc -> case tc of
356 ObCommand_Thunk tc -> case tc of
412 ThunkCommand_Update thunks -> mapM_ updateThunkToLatest thunks
357 ThunkCommand_Update thunks -> mapM_ updateThunkToLatest thunks
413 ThunkCommand_Unpack thunks -> mapM_ unpackThunk thunks
358 ThunkCommand_Unpack thunks -> mapM_ unpackThunk thunks
414− ThunkCommand_Pack thunks -> forM_ thunks $ \(ThunkPackOpts dir upstream) -> packThunk dir (T.pack upstream)
359+ ThunkCommand_Pack thunks -> forM_ thunks packThunk
415 ObCommand_Repl -> runRepl
360 ObCommand_Repl -> runRepl
416 ObCommand_Watch -> inNixShell' $ static runWatch
361 ObCommand_Watch -> inNixShell' $ static runWatch
417− ObCommand_Upgrade branch -> do
418− upgradeObelisk "." branch
419 ObCommand_Internal icmd -> case icmd of
362 ObCommand_Internal icmd -> case icmd of
420 ObInternal_RunStaticIO k -> liftIO (unsafeLookupStaticPtr @(ObeliskT IO ()) k) >>= \case
363 ObInternal_RunStaticIO k -> liftIO (unsafeLookupStaticPtr @(ObeliskT IO ()) k) >>= \case
421 Nothing -> failWith $ "ObInternal_RunStaticIO: no such StaticKey: " <> T.pack (show k)
364 Nothing -> failWith $ "ObInternal_RunStaticIO: no such StaticKey: " <> T.pack (show k)
422 Just p -> do
365 Just p -> do
423 c <- getObelisk
366 c <- getObelisk
424 liftIO $ runObelisk c $ deRefStaticPtr p
367 liftIO $ runObelisk c $ deRefStaticPtr p
425− ObInternal_Hash revM -> do
426− hash <- case revM of
427− Nothing -> getDirectoryHash [migrationDirName] "."
428− Just rev -> fmap head $ getHashAtGitRevision [rev] [migrationDirName] "."
430− ObInternal_CreateMigration ->
431− createMigrationEdgeFromHEAD "."
432− ObInternal_VerifyMigration ->
434− ObInternal_Migrate fromHash ->
435− migrateObelisk "." fromHash
436 ObInternal_CLIDemo -> cliDemo
368 ObInternal_CLIDemo -> cliDemo
438--TODO: Clean up all the magic strings throughout this codebase
370--TODO: Clean up all the magic strings throughout this codebase
lib/command/src/Obelisk/Command/Deploy.hs+1−1
@@ -113,7 +113,7 @@ deployPush deployPath getNixBuilders = do
113 checkGitCleanStatus srcPath True >>= \case
113 checkGitCleanStatus srcPath True >>= \case
114 True -> do
114 True -> do
115 result <- build
115 result <- build
116− packThunk srcPath "origin" -- get upstream
116+ packThunk srcPath
117 return result
117 return result
118 False -> do
118 False -> do
119 _ <- failWith $ T.pack $ "ob deploy push: ensure " <> srcPath <> " has no pending changes and latest is pushed upstream."
119 _ <- failWith $ T.pack $ "ob deploy push: ensure " <> srcPath <> " has no pending changes and latest is pushed upstream."
lib/command/src/Obelisk/Command/Nix.hs+36−19
@@ -1,8 +1,12 @@
1+{-# LANGUAGE AllowAmbiguousTypes #-}
2+{-# LANGUAGE ConstraintKinds #-}
1{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE LambdaCase #-}
4{-# LANGUAGE LambdaCase #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
5{-# LANGUAGE MultiParamTypeClasses #-}
4{-# LANGUAGE OverloadedStrings #-}
6{-# LANGUAGE OverloadedStrings #-}
7+{-# LANGUAGE Rank2Types #-}
5{-# LANGUAGE ScopedTypeVariables #-}
8{-# LANGUAGE ScopedTypeVariables #-}
9+{-# LANGUAGE TypeApplications #-}
6module Obelisk.Command.Nix
10module Obelisk.Command.Nix
7 ( nixBuild
11 ( nixBuild
8 , withNixRemoteCheck
12 , withNixRemoteCheck
@@ -15,7 +19,9 @@ module Obelisk.Command.Nix
18−import Control.Monad.Catch (catch, throwM)
22+--import Control.Monad.Catch (catch, throwM)
24+import Control.Monad.Except (ExceptT, runExceptT, throwError)
19import Control.Monad.IO.Class (liftIO)
25import Control.Monad.IO.Class (liftIO)
20import Data.Bool (bool)
26import Data.Bool (bool)
21import Data.Default
27import Data.Default
@@ -26,7 +32,7 @@ import System.Directory
26import System.Environment
32import System.Environment
27import System.Process (proc)
33import System.Process (proc)
29−import Obelisk.App (MonadObelisk)
35+import Obelisk.App (MonadInfallibleObelisk, MonadObelisk, ObeliskError (..))
30import Obelisk.CliApp
36import Obelisk.CliApp
32-- | Where to put nix-build output
38-- | Where to put nix-build output
@@ -81,8 +87,11 @@ instance Default NixBuildConfig where
82nixBuild :: MonadObelisk m => NixBuildConfig -> m FilePath
88nixBuild :: MonadObelisk m => NixBuildConfig -> m FilePath
83nixBuild cfg = withSpinner' ("Running nix-build on " <> desc) (Just $ const $ "Built " <> desc) $ do
89nixBuild cfg = withSpinner' ("Running nix-build on " <> desc) (Just $ const $ "Built " <> desc) $ do
84− withNixRemoteCheck $ readProcessAndLogStderr Debug $ proc "nix-build" $ mconcat
90+ output <- withNixRemoteCheck $ readProcessAndLogStderr Debug $ proc "nix-build" $ mconcat
85 [[path], attrArg, args, outLink, buildersArg]
91 [[path], attrArg, args, outLink, buildersArg]
92+ -- Remove final newline that Nix appends
93+ Just (outPath, '\n') <- pure $ T.unsnoc output
94+ pure $ T.unpack outPath
87 path = _target_path $ _nixBuildConfig_target cfg
96 path = _target_path $ _nixBuildConfig_target cfg
88 attr = _target_attr $ _nixBuildConfig_target cfg
97 attr = _target_attr $ _nixBuildConfig_target cfg
@@ -103,19 +112,27 @@ nixBuild cfg = withSpinner' ("Running nix-build on " <> desc) (Just $ const $ "B
103-- tell the user what to do.
112-- tell the user what to do.
105-- Added: June, 2018. Consider removing this eventually.
114-- Added: June, 2018. Consider removing this eventually.
106−withNixRemoteCheck :: MonadObelisk m => m a -> m a
115+withNixRemoteCheck
117+ => (forall m'. MonadInfallibleObelisk m' => ExceptT ObeliskError m' a)
107−withNixRemoteCheck f = f `catch` \e@(ProcessFailed _ _) -> do
119+withNixRemoteCheck f = do
120+ status <- runExceptT f
123+ Left e -> throwError =<< case matching asProcessFailure e of
108− liftIO (lookupEnv "NIX_REMOTE") >>= \case
125+ Right pf -> liftIO (lookupEnv "NIX_REMOTE") >>= \case
109− Just _ -> throwM e
126+ Just _ -> pure e
110− Nothing -> liftIO (writable <$> getPermissions "/nix/var/nix/db") >>= \case
127+ Nothing -> liftIO (writable <$> getPermissions "/nix/var/nix/db") >>= \case
111− True -> throwM e
128+ True -> pure e
112− False -> do
129+ False -> pure $ ObeliskError_ProcessError pf $ Just $ T.unlines
113− putLog Error "!!! "
130+ [ "!!! "
114− putLog Error "!!! A nix command failed to run. You might need to set the NIX_REMOTE environment variable"
131+ , "!!! A nix command failed to run. You might need to set the NIX_REMOTE environment variable"
115− putLog Error "!!! to `daemon`. To do this, run the following before running obelisk:"
132+ , "!!! to `daemon`. To do this, run the following before running obelisk:"
116− putLog Error "!!! "
133+ , "!!! "
117− putLog Error "!!! export NIX_REMOTE=daemon"
134+ , "!!! export NIX_REMOTE=daemon"
118− putLog Error "!!! "
135+ , "!!! "
119− putLog Error "!!! For details, see https://github.com/NixOS/nixpkgs/issues/5713"
136+ , "!!! For details, see https://github.com/NixOS/nixpkgs/issues/5713"
120− putLog Error "!!! "
137+ , "!!! "
lib/command/src/Obelisk/Command/Project.hs−1
@@ -48,7 +48,6 @@ obeliskSourceWithBranch branch = ThunkSource_GitHub $ GitHubSource
48 { _gitHubSource_owner = "obsidiansystems"
48 { _gitHubSource_owner = "obsidiansystems"
49 , _gitHubSource_repo = "obelisk"
49 , _gitHubSource_repo = "obelisk"
50 , _gitHubSource_branch = Just branch
50 , _gitHubSource_branch = Just branch
51− , _gitHubSource_private = False
54data InitSource
53data InitSource
lib/command/src/Obelisk/Command/Run.hs+1−1
@@ -112,7 +112,7 @@ parseCabalPackage dir = do
112 mapM_ (putLog Error) $ fmap (T.pack . show) errors
112 mapM_ (putLog Error) $ fmap (T.pack . show) errors
113 return Nothing
113 return Nothing
115−withUTF8FileContentsM :: (MonadIO m, HasCliConfig m) => FilePath -> (ByteString -> CliT IO a) -> m a
115+withUTF8FileContentsM :: (MonadIO m, HasCliConfig e m) => FilePath -> (ByteString -> CliT e IO a) -> m a
116withUTF8FileContentsM fp f = do
116withUTF8FileContentsM fp f = do
117 c <- getCliConfig
117 c <- getCliConfig
118 liftIO $ withUTF8FileContents fp $ runCli c . f . toUTF8BS
118 liftIO $ withUTF8FileContents fp $ runCli c . f . toUTF8BS
lib/command/src/Obelisk/Command/Thunk.hs+345−265
@@ -27,10 +27,13 @@ module Obelisk.Command.Thunk
27 , updateThunk
27 , updateThunk
28 , getThunkPtr
28 , getThunkPtr
29 , getThunkPtr'
29 , getThunkPtr'
32import Control.Applicative
34import Control.Applicative
33−import Control.Exception (displayException, throwIO, try)
35+import Control.Exception (displayException, try)
36+import Control.Lens.Indexed hiding ((<.>))
34import Control.Monad
37import Control.Monad
35import Control.Monad.Catch (handle)
38import Control.Monad.Catch (handle)
36import Control.Monad.Except
39import Control.Monad.Except
@@ -39,15 +42,14 @@ import qualified Data.Aeson as Aeson
39import Data.Aeson.Encode.Pretty
42import Data.Aeson.Encode.Pretty
40import qualified Data.Aeson.Types as Aeson
43import qualified Data.Aeson.Types as Aeson
41import qualified Data.ByteString.Lazy as LBS
44import qualified Data.ByteString.Lazy as LBS
42−import qualified Data.ByteString.Lazy.Char8 as LBSC
43import Data.Default
45import Data.Default
44−import Data.Either.Combinators (rightToMaybe)
46+import Data.Either.Combinators (fromRight', rightToMaybe)
46import Data.Git.Ref (Ref)
47import Data.Git.Ref (Ref)
47import qualified Data.Git.Ref as Ref
48import qualified Data.Git.Ref as Ref
48import qualified Data.List as L
49import qualified Data.List as L
49import Data.List.NonEmpty (NonEmpty (..))
50import Data.List.NonEmpty (NonEmpty (..))
50import qualified Data.List.NonEmpty as NonEmpty
51import qualified Data.List.NonEmpty as NonEmpty
51import qualified Data.Map as Map
53import qualified Data.Map as Map
52import Data.Maybe
54import Data.Maybe
53import Data.Set (Set)
55import Data.Set (Set)
@@ -57,12 +59,9 @@ import qualified Data.Text as T
57import Data.Text.Encoding
59import Data.Text.Encoding
58import qualified Data.Text.IO as T
60import qualified Data.Text.IO as T
59import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
61import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
60−import Data.Yaml (parseMaybe, (.:))
62+import Data.Yaml (parseMaybe)
61−import qualified Data.Yaml as Yaml
62import GitHub
63import GitHub
63import GitHub.Data.Name
64import GitHub.Data.Name
64−import GitHub.Endpoints.Repos.Contents (archiveForR)
66import Obelisk.Command.Nix
65import Obelisk.Command.Nix
67import System.Directory
66import System.Directory
68import System.FilePath
67import System.FilePath
@@ -70,6 +69,7 @@ import System.IO.Error
70import System.IO.Temp
69import System.IO.Temp
71import System.Posix (getSymbolicLinkStatus, modificationTime)
70import System.Posix (getSymbolicLinkStatus, modificationTime)
72import System.Process (proc)
71import System.Process (proc)
74import Obelisk.App (MonadObelisk)
74import Obelisk.App (MonadObelisk)
75import Obelisk.CliApp
75import Obelisk.CliApp
@@ -112,97 +112,73 @@ data GitHubSource = GitHubSource
112 { _gitHubSource_owner :: Name Owner
112 { _gitHubSource_owner :: Name Owner
113 , _gitHubSource_repo :: Name Repo
113 , _gitHubSource_repo :: Name Repo
114 , _gitHubSource_branch :: Maybe (Name Branch)
114 , _gitHubSource_branch :: Maybe (Name Branch)
115− , _gitHubSource_private :: Bool
117 deriving (Show, Eq, Ord)
116 deriving (Show, Eq, Ord)
119data GitSource = GitSource
118data GitSource = GitSource
120 { _gitSource_url :: URI
119 { _gitSource_url :: URI
121− , _gitSource_branch :: Name Branch
120+ , _gitSource_branch :: Maybe (Name Branch)
122 , _gitSource_fetchSubmodules :: Bool
121 , _gitSource_fetchSubmodules :: Bool
124 deriving (Show, Eq, Ord)
123 deriving (Show, Eq, Ord)
125+-- | Convert a GitHub source to a regular Git source. Assumes no submodules.
126+forgetGithub :: Bool -> GitHubSource -> GitSource
127+forgetGithub useSsh s = GitSource
128+ { _gitSource_url = URI
129+ { uriScheme = Just $ fromRight' $ mkScheme $ if useSsh then "ssh" else "https"
130+ , uriAuthority = Right $ Authority
131+ { authUserInfo = UserInfo (fromRight' $ mkUsername "git") Nothing
133+ , authHost = fromRight' $ mkHost "github.com"
134+ , authPort = Nothing
136+ , uriPath = Just ( False
137+ , fromRight' . mkPathPiece <$>
138+ untagName (_gitHubSource_owner s)
139+ :| [ untagName (_gitHubSource_repo s) <> ".git" ]
142+ , uriFragment = Nothing
144+ , _gitSource_branch = _gitHubSource_branch s
145+ , _gitSource_fetchSubmodules = False
126getThunkGitBranch :: ThunkPtr -> Maybe Text
148getThunkGitBranch :: ThunkPtr -> Maybe Text
127getThunkGitBranch (ThunkPtr _ src) = fmap untagName $ case src of
149getThunkGitBranch (ThunkPtr _ src) = fmap untagName $ case src of
128 ThunkSource_GitHub s -> _gitHubSource_branch s
150 ThunkSource_GitHub s -> _gitHubSource_branch s
129− ThunkSource_Git s -> Just $ _gitSource_branch s
151+ ThunkSource_Git s -> _gitSource_branch s
131commitNameToRef :: Name Commit -> Ref
153commitNameToRef :: Name Commit -> Ref
132commitNameToRef (N c) = Ref.fromHex $ encodeUtf8 c
154commitNameToRef (N c) = Ref.fromHex $ encodeUtf8 c
134-- TODO: Use spinner here.
156-- TODO: Use spinner here.
135−getNixSha256ForUriUnpacked :: MonadObelisk m => URI -> m NixSha256
157+getNixSha256ForUriUnpacked
136getNixSha256ForUriUnpacked uri =
161getNixSha256ForUriUnpacked uri =
137− withExitFailMessage ("nix-prefetch-url: Failed to determine sha256 hash of URL " <> T.pack (show uri)) $ do
162+ withExitFailMessage ("nix-prefetch-url: Failed to determine sha256 hash of URL " <> render uri) $ do
138− fmap T.pack $ withNixRemoteCheck $ readProcessAndLogStderr Debug $
163+ [hash] <- fmap T.lines $ withNixRemoteCheck $ readProcessAndLogOutput (Debug, Debug) $
139− proc "nix-prefetch-url" ["--unpack" , "--type" , "sha256" , show uri]
164+ proc "nix-prefetch-url" ["--unpack" , "--type" , "sha256" , T.unpack $ render uri]
141nixPrefetchGit :: MonadObelisk m => URI -> Text -> Bool -> m NixSha256
167nixPrefetchGit :: MonadObelisk m => URI -> Text -> Bool -> m NixSha256
142nixPrefetchGit uri rev fetchSubmodules =
168nixPrefetchGit uri rev fetchSubmodules =
143− withExitFailMessage ("nix-prefetch-git: Failed to determine sha256 hash of Git repo " <> T.pack (show uri) <> " at " <> rev) $ do
169+ withExitFailMessage ("nix-prefetch-git: Failed to determine sha256 hash of Git repo " <> render uri <> " at " <> rev) $ do
144 out <- withNixRemoteCheck $ readProcessAndLogStderr Debug $
170 out <- withNixRemoteCheck $ readProcessAndLogStderr Debug $
145 proc "nix-prefetch-git" $ filter (/="")
171 proc "nix-prefetch-git" $ filter (/="")
146− [ "--url", show uri
172+ [ "--url", T.unpack $ render uri
147 , "--rev", T.unpack rev
173 , "--rev", T.unpack rev
148 , if fetchSubmodules then "--fetch-submodules" else ""
174 , if fetchSubmodules then "--fetch-submodules" else ""
149 , "--quiet"
175 , "--quiet"
152− case parseMaybe (Aeson..: "sha256") =<< Aeson.decode (LBSC.pack out) of
178+ case parseMaybe (Aeson..: "sha256") =<< Aeson.decodeStrict (encodeUtf8 out) of
153− Nothing -> failWith $ "nix-prefetch-git: unrecognized output " <> T.pack out
179+ Nothing -> failWith $ "nix-prefetch-git: unrecognized output " <> out
154 Just x -> pure x
180 Just x -> pure x
156−getLatestGitRev :: MonadObelisk m => GitSource -> m ThunkRev
157−getLatestGitRev s = withSystemTempDirectory "git-clone" $ \tmpDir -> do
158− withExitFailMessage ("Unable to determine latest git revision for branch " <> branch) $ do
159− let git = fmap T.pack . readProcessAndLogStderr Debug . gitProc tmpDir
161− (git ["clone", "--no-checkout", show $ _gitSource_url s]) -- Might be able to use --bare here instead to go faster.
162− (git ["log", T.unpack branch, "--max-count=1", "--format=%H"])
164− case T.strip <$> safeLast (T.lines out) of
165− Nothing -> failWith $ "Unable to parse git log: " <> out
167− putLog Debug $ "Latest commit in " <> branch <> " is " <> rev
168− sha <- nixPrefetchGit (_gitSource_url s) rev (_gitSource_fetchSubmodules s)
169− putLog Debug $ "Nix sha256 is " <> sha
171− { _thunkRev_commit = Ref.fromHexString $ T.unpack rev
172− , _thunkRev_nixSha256 = sha
175− remote :: Text = "origin"
176− branch :: Text = remote <> "/" <> untagName (_gitSource_branch s)
178− safeLast [] = Nothing
179− safeLast xs = Just $ last xs
181−-- | Get the latest revision available from the given source
182−getLatestRev :: MonadObelisk m => ThunkSource -> m ThunkRev
184− ThunkSource_GitHub s -> do
185− auth <- liftIO $ getHubAuth "github.com"
186− commitsResult <- liftIO $ executeRequestMaybe auth $ commitsWithOptionsForR
187− (_gitHubSource_owner s)
188− (_gitHubSource_repo s)
190− $ case _gitHubSource_branch s of
192− Just b -> [CommitQuerySha $ untagName b]
193− commitInfos <- either (liftIO . throwIO) return commitsResult
194− commitInfo : _ <- return $ toList commitInfos
195− let commit = commitSha commitInfo
196− putLog Debug $ "Latest commit is " <> untagName commit
197− Right archiveUri <- liftIO $ executeRequestMaybe auth $ archiveForR (_gitHubSource_owner s) (_gitHubSource_repo s) ArchiveFormatTarball $ Just $ untagName commit
198− nixSha256 <- getNixSha256ForUriUnpacked archiveUri
199− putLog Debug $ "Nix sha256 is " <> nixSha256
201− { _thunkRev_commit = commitNameToRef commit
202− , _thunkRev_nixSha256 = nixSha256
204− ThunkSource_Git s -> getLatestGitRev s
206--TODO: Pretty print these
182--TODO: Pretty print these
207data ReadThunkError
183data ReadThunkError
208 = ReadThunkError_UnrecognizedFiles
184 = ReadThunkError_UnrecognizedFiles
@@ -311,18 +287,16 @@ parseGitHubSource v = do
311 owner <- v Aeson..: "owner"
287 owner <- v Aeson..: "owner"
312 repo <- v Aeson..: "repo"
288 repo <- v Aeson..: "repo"
313 branch <- v Aeson..:! "branch"
289 branch <- v Aeson..:! "branch"
314− mPrivate <- v Aeson..:! "private"
315 pure $ GitHubSource
290 pure $ GitHubSource
316 { _gitHubSource_owner = owner
291 { _gitHubSource_owner = owner
317 , _gitHubSource_repo = repo
292 , _gitHubSource_repo = repo
318 , _gitHubSource_branch = branch
293 , _gitHubSource_branch = branch
319− , _gitHubSource_private = fromMaybe False mPrivate
322parseGitSource :: Aeson.Object -> Aeson.Parser GitSource
296parseGitSource :: Aeson.Object -> Aeson.Parser GitSource
323parseGitSource v = do
297parseGitSource v = do
324 Just url <- parseGitUri <$> v Aeson..: "url"
298 Just url <- parseGitUri <$> v Aeson..: "url"
325− branch <- v Aeson..: "branch"
299+ branch <- v Aeson..:! "branch"
326 fetchSubmodules <- v Aeson..:! "fetchSubmodules"
300 fetchSubmodules <- v Aeson..:! "fetchSubmodules"
327 pure $ GitSource
301 pure $ GitSource
328 { _gitSource_url = url
302 { _gitSource_url = url
@@ -351,20 +325,14 @@ encodeThunkPtrData (ThunkPtr rev src) = case src of
351 ThunkSource_GitHub s -> encodePretty' githubCfg $ Aeson.object $ catMaybes
325 ThunkSource_GitHub s -> encodePretty' githubCfg $ Aeson.object $ catMaybes
352 [ Just $ "owner" .= _gitHubSource_owner s
326 [ Just $ "owner" .= _gitHubSource_owner s
353 , Just $ "repo" .= _gitHubSource_repo s
327 , Just $ "repo" .= _gitHubSource_repo s
354− , case _gitHubSource_branch s of
328+ , ("branch" .=) <$> _gitHubSource_branch s
355− Just b -> Just $ "branch" .= b
357− , if _gitHubSource_private s
358− then Just $ "private" .= True
360 , Just $ "rev" .= Ref.toHexString (_thunkRev_commit rev)
329 , Just $ "rev" .= Ref.toHexString (_thunkRev_commit rev)
361 , Just $ "sha256" .= _thunkRev_nixSha256 rev
330 , Just $ "sha256" .= _thunkRev_nixSha256 rev
363 ThunkSource_Git s -> encodePretty' plainGitCfg $ Aeson.object $ catMaybes
332 ThunkSource_Git s -> encodePretty' plainGitCfg $ Aeson.object $ catMaybes
364− --TODO: Is this safe? read/show is jank for `URI`
365− [ Just $ "url" .= show (_gitSource_url s)
333+ [ Just $ "url" .= render (_gitSource_url s)
366 , Just $ "rev" .= Ref.toHexString (_thunkRev_commit rev)
334 , Just $ "rev" .= Ref.toHexString (_thunkRev_commit rev)
367− , Just $ "branch" .= _gitSource_branch s
335+ , ("branch" .=) <$> _gitSource_branch s
368 , Just $ "sha256" .= _thunkRev_nixSha256 rev
336 , Just $ "sha256" .= _thunkRev_nixSha256 rev
369 , Just $ "fetchSubmodules" .= _gitSource_fetchSubmodules s
337 , Just $ "fetchSubmodules" .= _gitSource_fetchSubmodules s
@@ -496,20 +464,6 @@ plainGitStandaloneLoaderV2 = T.unlines
496thunkFileNames :: [FilePath]
464thunkFileNames :: [FilePath]
497thunkFileNames = ["default.nix", "github.json", "git.json"]
465thunkFileNames = ["default.nix", "github.json", "git.json"]
499−-- | Look for authentication info from the 'hub' command
501− :: Text -- ^ Domain name
503−getHubAuth domain = do
504− hubConfig <- getXdgDirectory XdgConfig "hub"
505− Yaml.decodeFileEither hubConfig >>= \case
506− Left _ -> return Nothing
507− Right v -> return $ flip parseMaybe v $ \v' -> do
508− Yaml.Array domainConfigs <- v' .: domain --TODO: Determine what multiple domainConfigs means
509− [Yaml.Object domainConfig] <- return $ toList domainConfigs
510− token <- domainConfig .: "oauth_token"
511− return $ OAuth $ encodeUtf8 token
513--TODO: when checking something out, make a shallow clone
467--TODO: when checking something out, make a shallow clone
515-- | Checks a cache directory to see if there is a fresh symlink
469-- | Checks a cache directory to see if there is a fresh symlink
@@ -588,7 +542,7 @@ updateThunk p f = withSystemTempDirectory "obelisk-thunkptr-" $ \tmpDir -> do
588 p' <- copyThunkToTmp tmpDir p
542 p' <- copyThunkToTmp tmpDir p
589 unpackThunk' True p'
543 unpackThunk' True p'
590 result <- f p'
544 result <- f p'
591− updateThunkFromTmp p' "origin" -- TODO: stop hardcoding remote
545+ updateThunkFromTmp p'
592 return result
546 return result
594 copyThunkToTmp tmpDir thunkDir = readThunk thunkDir >>= \case
548 copyThunkToTmp tmpDir thunkDir = readThunk thunkDir >>= \case
@@ -599,8 +553,8 @@ updateThunk p f = withSystemTempDirectory "obelisk-thunkptr-" $ \tmpDir -> do
599 proc "cp" ["-r", "-T", thunkDir, tmpThunk]
553 proc "cp" ["-r", "-T", thunkDir, tmpThunk]
600 return tmpThunk
554 return tmpThunk
601 Right _ -> failWith $ "Thunk is not packed"
555 Right _ -> failWith $ "Thunk is not packed"
602− updateThunkFromTmp p' remote = do
556+ updateThunkFromTmp p' = do
603− packThunk' True p' remote
557+ packThunk' True p'
604 callProcessAndLogOutput (Notice, Error) $
558 callProcessAndLogOutput (Notice, Error) $
605 proc "cp" ["-r", "-T", p', p]
559 proc "cp" ["-r", "-T", p', p]
@@ -619,190 +573,316 @@ unpackThunk' noTrail thunkDir = readThunk thunkDir >>= \case
619 let (thunkParent, thunkName) = splitFileName thunkDir
573 let (thunkParent, thunkName) = splitFileName thunkDir
620 withTempDirectory thunkParent thunkName $ \tmpRepo -> do
574 withTempDirectory thunkParent thunkName $ \tmpRepo -> do
621 let obGitDir = tmpRepo </> ".git" </> "obelisk"
575 let obGitDir = tmpRepo </> ".git" </> "obelisk"
622− case _thunkPtr_source tptr of
576+ s = case _thunkPtr_source tptr of
623− ThunkSource_GitHub s -> do
577+ ThunkSource_GitHub s' -> forgetGithub False s'
624− mauth <- liftIO $ getHubAuth "github.com"
625− repoResult <- liftIO $ executeRequestMaybe mauth $ repositoryR (_gitHubSource_owner s) (_gitHubSource_repo s)
626− githubURI <- either (liftIO . throwIO) (return . repoSshUrl) repoResult >>= \case
627− Nothing -> failWith "Cannot determine clone URI for thunk source"
628− Just c -> return $ T.unpack $ getUrl c
630− withSpinner' ("Fetching thunk " <> T.pack thunkDir)
631− ( finalMsg noTrail $ const $ "Fetched thunk " <> T.pack thunkDir) $ do
632− callProcessAndLogOutput (Debug, Debug) $
633− proc "hub" ["clone", "-n", githubURI, tmpRepo]
634− --If this directory already exists then something is weird and we should fail
635− liftIO $ createDirectory obGitDir
636− callProcessAndLogOutput (Debug, Error) $
637− proc "cp" ["-r", "-T", thunkDir </> ".", obGitDir </> "orig-thunk"]
640− putLog Debug $ "Checking out " <> T.pack (show $ maybe "" untagName $ _gitHubSource_branch s)
641− callProcessAndLogOutput (Debug, Debug) $
645− , maybe [] (\n -> ["-B", T.unpack (untagName n)]) (_gitHubSource_branch s)
646− , pure $ Ref.toHexString $ _thunkRev_commit $ _thunkPtr_rev tptr
648− -- Set upstream branch
649− forM_ (_gitHubSource_branch s) $ \branch ->
650− callProcessAndLogOutput (Debug, Error) $
651− proc "hub" ["-C", tmpRepo, "branch", "-u", "origin/" <> T.unpack (untagName branch)]
652− callProcessAndLogOutput (Notice, Error) $ proc "rm" ["-r", thunkDir]
653− callProcessAndLogOutput (Notice, Error) $ proc "mv" ["-T", tmpRepo, thunkDir]
655− ThunkSource_Git s -> do
578+ ThunkSource_Git s' -> s'
656− withSpinner' ("Fetching thunk " <> T.pack thunkName)
579+ withSpinner' ("Fetching thunk " <> T.pack thunkName)
657− (finalMsg noTrail $ const $ "Fetched thunk " <> T.pack thunkName) $ do
580+ (finalMsg noTrail $ const $ "Fetched thunk " <> T.pack thunkName) $ do
658− let git = callProcessAndLogOutput (Notice, Notice) . gitProc tmpRepo
581+ let git = callProcessAndLogOutput (Notice, Notice) . gitProc tmpRepo
659− git ["clone", if _gitSource_fetchSubmodules s then "--recursive" else "", show (_gitSource_url s)]
583+ ++ ("--recursive" <$ guard (_gitSource_fetchSubmodules s))
584+ ++ [ T.unpack $ render $ _gitSource_url s ]
660− git ["reset", "--hard", Ref.toHexString $ _thunkRev_commit $ _thunkPtr_rev tptr]
585+ git ["reset", "--hard", Ref.toHexString $ _thunkRev_commit $ _thunkPtr_rev tptr]
661− when (_gitSource_fetchSubmodules s) $
586+ when (_gitSource_fetchSubmodules s) $
662− git ["submodule", "update", "--recursive", "--init"]
587+ git ["submodule", "update", "--recursive", "--init"]
663− git ["branch", "-u", "origin/" <> T.unpack (untagName $ _gitSource_branch s)]
588+ case _gitSource_branch s of
664−
589+ Just b -> git ["branch", "-u", "origin/" <> T.unpack (untagName $ b)]
665− liftIO $ createDirectory obGitDir
592+ liftIO $ createDirectory obGitDir
666− callProcessAndLogOutput (Notice, Error) $
593+ callProcessAndLogOutput (Notice, Error) $
667− proc "cp" ["-r", "-T", thunkDir </> ".", obGitDir </> "orig-thunk"]
594+ proc "cp" ["-r", "-T", thunkDir </> ".", obGitDir </> "orig-thunk"]
668− callProcessAndLogOutput (Notice, Error) $
595+ callProcessAndLogOutput (Notice, Error) $
669− proc "rm" ["-r", thunkDir]
596+ proc "rm" ["-r", thunkDir]
670− callProcessAndLogOutput (Notice, Error) $
597+ callProcessAndLogOutput (Notice, Error) $
671− proc "mv" ["-T", tmpRepo, thunkDir]
598+ proc "mv" ["-T", tmpRepo, thunkDir]
673--TODO: add force mode to pack even if changes are present
600--TODO: add force mode to pack even if changes are present
674--TODO: add a rollback mode to pack to the original thunk
601--TODO: add a rollback mode to pack to the original thunk
675−packThunk :: MonadObelisk m => FilePath -> Text -> m ()
602+packThunk :: MonadObelisk m => FilePath -> m ()
676packThunk = packThunk' False
603packThunk = packThunk' False
678−packThunk' :: MonadObelisk m => Bool -> FilePath -> Text -> m ()
605+packThunk' :: MonadObelisk m => Bool -> FilePath -> m ()
679−packThunk' noTrail thunkDir upstream = readThunk thunkDir >>= \case
606+packThunk' noTrail thunkDir = readThunk thunkDir >>= \case
680 Left err -> failWith $ T.pack $ "thunk pack: " <> show err
607 Left err -> failWith $ T.pack $ "thunk pack: " <> show err
681 Right (ThunkData_Packed _) -> failWith "pack: thunk is already packed"
608 Right (ThunkData_Packed _) -> failWith "pack: thunk is already packed"
682 Right (ThunkData_Checkout _) -> do
609 Right (ThunkData_Checkout _) -> do
683 withSpinner' ("Packing thunk " <> T.pack thunkDir)
610 withSpinner' ("Packing thunk " <> T.pack thunkDir)
684 (finalMsg noTrail $ const $ "Packed thunk " <> T.pack thunkDir) $ do
611 (finalMsg noTrail $ const $ "Packed thunk " <> T.pack thunkDir) $ do
685− thunkPtr <- getThunkPtr thunkDir upstream
612+ thunkPtr <- getThunkPtr thunkDir
686 callProcessAndLogOutput (Debug, Error) $ proc "rm" ["-rf", thunkDir]
613 callProcessAndLogOutput (Debug, Error) $ proc "rm" ["-rf", thunkDir]
687 liftIO $ createThunk thunkDir thunkPtr
614 liftIO $ createThunk thunkDir thunkPtr
689−getThunkPtr :: MonadObelisk m => FilePath -> Text -> m ThunkPtr
616+getThunkPtr :: MonadObelisk m => FilePath -> m ThunkPtr
690getThunkPtr = getThunkPtr' True
617getThunkPtr = getThunkPtr' True
692−getThunkPtr' :: MonadObelisk m => Bool -> FilePath -> Text -> m ThunkPtr
619+getThunkPtr' :: forall m. MonadObelisk m => Bool -> FilePath -> m ThunkPtr
693−getThunkPtr' checkClean thunkDir upstream = do
620+getThunkPtr' checkClean thunkDir = do
694− when checkClean $ ensureCleanGitRepo thunkDir True $
621+ when checkClean $ ensureCleanGitRepo thunkDir True $
695− "thunk pack: thunk checkout contains unsaved modifications"
622+ "thunk pack: thunk checkout contains unsaved modifications"
697− -- Check whether there are any stashes
624+ -- Check whether there are any stashes
698− stashOutput <- readGitProcess thunkDir ["stash", "list"]
625+ stashOutput <- readGitProcess thunkDir ["stash", "list"]
699− when checkClean $ case T.null stashOutput of
626+ when checkClean $ case T.null stashOutput of
700− False -> do
627+ False -> do
701− failWith $ T.unlines $
628+ failWith $ T.unlines $
702− [ "thunk pack: thunk checkout has stashes"
629+ [ "thunk pack: thunk checkout has stashes"
703− , "git stash list:"
630+ , "git stash list:"
704− ] ++ T.lines stashOutput
631+ ] ++ T.lines stashOutput
705− True -> return ()
632+ True -> return ()
707− --Check whether all local heads are pushed
634+ -- Get information on all branches and their (optional) designated upstream
708− repoHeads <- T.lines <$> readGitProcess thunkDir ["for-each-ref", "--format=%(refname:short)", "refs/heads/"]
636+ (headDump :: [Text]) <- T.lines <$> readGitProcess thunkDir
709− remotes <- T.lines <$> readGitProcess thunkDir ["remote"]
637+ [ "for-each-ref"
710− --Check that the upstream specified actually exists
638+ , "--format=%(refname:short) %(upstream:short) %(upstream:remotename)"
711− case L.find (== upstream) remotes of
639+ , "refs/heads/"
712− Nothing -> failWith $ "thunk pack: upstream " <> upstream <> " does not exist. Available upstreams are " <> T.intercalate ", " remotes
640+ ]
713− Just _ -> return ()
641+
714− -- iterate over cartesian product
642+ (headInfo :: Map Text (Maybe (Text, Text)))
643+ <- fmap Map.fromList $ forM headDump $ \line -> do
644+ (branch : restOfLine) <- pure $ T.words line
645+ mUpstream <- case restOfLine of
647+ [u, r] -> pure $ Just (u, r)
648+ (_:_) -> failWith "git for-each-ref invalid output"
649+ pure (branch, mUpstream)
651+ putLog Debug $ "branches: " <> T.pack (show headInfo)
653+ let errorMap :: Map Text ()
654+ headUpstream :: Map Text (Text, Text)
655+ (errorMap, headUpstream) = flip Map.mapEither headInfo $ \case
659+ putLog Debug $ "branches with upstream branch set: " <> T.pack (show headUpstream)
661+ -- Check that every branch has a remote equivalent
715− when checkClean $ forM_ repoHeads $ \hd -> do
662+ when checkClean $ do
716− [localRev] <- T.lines <$> readGitProcess thunkDir ["rev-parse", T.unpack hd]
663+ let untrackedBranches = Map.keys errorMap
717− forM_ remotes $ \rm -> do
664+ when (not $ L.null untrackedBranches) $ failWith $ T.unlines $
718− --TODO: The error you get if a branch isn't pushed anywhere could be made more user friendly
665+ [ "thunk pack: Certain branches in the thunk have no upstream branch \
719− [remoteMergeRev] <- fmap T.lines $ readGitProcess thunkDir
666+ \set. This means don't know to check whether all your work is \
720− ["merge-base", T.unpack localRev, "remotes/" <> T.unpack rm <> "/" <> T.unpack hd]
667+ \saved. The offending branches are:"
721− case remoteMergeRev == localRev of
668+ , ""
722− False -> failWith $ mconcat [ "thunk unpack: branch ", hd, " has not been pushed to ", rm ]
669+ , T.unwords untrackedBranches
723− True -> return ()
670+ , ""
724−
671+ , "To fix this, you probably want to do:"
674+ ((\branch -> "git push -u origin " <> branch) <$> untrackedBranches) ++
676+ , "These will push the branches to the default remote under the same \
677+ \name, and (thanks to the `-u`) remember that choice so you don't \
678+ \get this error again."
681+ -- loosely by https://stackoverflow.com/questions/7773939/show-git-ahead-and-behind-info-for-all-branches-including-remotes
682+ stats <- iforM headUpstream $ \branch (upstream, _remote) -> do
683+ (stat :: [Text]) <- T.lines <$> readGitProcess thunkDir
684+ [ "rev-list", "--left-right"
685+ , T.unpack branch <> "..." <> T.unpack upstream
687+ let ahead = length $ [ () | Just ('<', _) <- T.uncons <$> stat ]
688+ behind = length $ [ () | Just ('>', _) <- T.uncons <$> stat ]
689+ pure (upstream, (ahead, behind))
691+ -- Those branches which have commits ahead of, i.e. not on, the upstream
692+ -- branch. Purely being behind is fine.
693+ let nonGood = Map.filter ((/= 0) . fst . snd) stats
695+ when (not $ Map.null nonGood) $ failWith $ T.unlines $
696+ [ "thunk pack: Certain branches in the thunk have commits not yet pushed upstream:"
699+ (flip map (Map.toList nonGood) $ \(branch, (upstream, (ahead, behind))) -> mconcat
700+ [" ", branch, " ahead: ", T.pack (show ahead), " behind: ", T.pack (show behind), " remote branch ", upstream]) ++
702+ , "Please push these upstream and try again. (Or just fetch, if they are somehow \
703+ \pushed but this repo's remote tracking branches don't know it.)"
725− --We assume it's safe to pack the thunk at this point
706+ -- We assume it's safe to pack the thunk at this point
707+ putLog Informational $ "All changes safe in git remotes. OK to pack thunk."
709+ -- Get current branch ``
710+ mCurrentBranch <- listToMaybe
712+ <$> readGitProcess thunkDir ["rev-parse", "--abbrev-ref", "HEAD"]
714+ let remote = maybe "origin" snd $ flip Map.lookup headUpstream =<< mCurrentBranch
726− [remoteUri'] <- fmap T.lines $ readGitProcess thunkDir ["config", "--get", "remote." <> T.unpack upstream <> ".url"]
716+ [remoteUri'] <- fmap T.lines $ readGitProcess thunkDir
719+ , "remote." <> T.unpack remote <> ".url"
722+ remoteUri <- case parseGitUri remoteUri' of
728− let uriParseFailure = "Could not identify git remote: " <> remoteUri'
723+ Nothing -> failWith $ "Could not identify git remote: " <> remoteUri'
729− mRemoteUri = parseGitUri remoteUri'
724+ Just uri -> pure uri
730− case mRemoteUri of
725+ uriThunkPtr remoteUri mCurrentBranch
731− Nothing -> failWith uriParseFailure
726+
732− Just remoteUri -> do
727+-- | Get the latest revision available from the given source
733− refs <- fmap (map (refsToTuples . T.words) . T.lines) $ readGitProcess thunkDir ["show-ref", "--head"]
728+getLatestRev :: MonadObelisk m => ThunkSource -> m ThunkRev
734− -- safe because exactly one hash is associated with HEAD
729+getLatestRev os = do
735− let Just currentHead = fst <$> L.find ((== "HEAD") . snd) refs
730+ let gitS = case os of
736− remoteHeads = Map.fromList $ catMaybes $ fmap
731+ ThunkSource_GitHub s -> forgetGithub False s
737− (\(x,y) -> (,) x <$> T.stripPrefix ("refs/remotes/" <> upstream <> "/") y)
732+ ThunkSource_Git s -> s
738− refs
733+ (_, commit) <- gitGetCommitBranch (_gitSource_url gitS) (untagName <$> _gitSource_branch gitS)
739− localHeads = Map.fromList $ catMaybes $ fmap
734+ case os of
740− (\(x,y) -> (,) x <$> T.stripPrefix "refs/heads/" y)
735+ ThunkSource_GitHub s -> githubThunkRev s commit
741− refs
736+ ThunkSource_Git s -> gitThunkRev s commit
742− currentUpstreamBranch = Map.lookup currentHead remoteHeads
737+
743− <|> Map.lookup currentHead localHeads
738+-- | Convert a URI to a thunk
744− if isGithubThunk remoteUri
739+--
745− then githubThunkPtr remoteUri currentHead currentUpstreamBranch
740+-- If the URL is a github URL, we try to just download an archive for
746− else gitThunkPtr remoteUri currentHead currentUpstreamBranch
741+-- performance. If that doesn't work (e.g. authentication issue), we fall back
747− where
742+-- on just doing things the normal way for git repos in general, and save it as
748− refsToTuples [x, y] = (x, y)
743+-- a regular git thunk.
749− refsToTuples x = error $ "thunk pack: cannot parse ref " <> show x
744+uriThunkPtr :: MonadObelisk m => URI -> Maybe Text -> m ThunkPtr
750− isGithubThunk u
745+uriThunkPtr uri mbranch = do
751− | Just uriAuth <- uriAuthority u
746+ (_, commit) <- gitGetCommitBranch uri mbranch
752− = case uriScheme u of
747+ (src, rev) <- case uriToThunkSource uri mbranch of
753− "ssh:" -> uriAuth == URIAuth "git@" "github.com" ""
748+ ThunkSource_GitHub s -> do
754− s -> s `L.elem` [ "git:", "https:", "http:" ] -- "http:" just redirects to "https:"
749+ rev <- runExceptT $ githubThunkRev s commit
755− && uriRegName uriAuth == "github.com"
750+ case rev of
756− | otherwise = False
751+ Right r -> pure (ThunkSource_GitHub s, r)
757− githubThunkPtr u commit' branch' = do
752+ Left e -> do
758− ["/", owner', repo'] <- return $ splitDirectories (uriPath u)
753+ putLog Warning $ "\
759− let owner = N (T.pack owner')
754+\Failed to fetch archive from GitHub. This is probably a private repo. \
760− dropGitExtension r = fromMaybe r $ T.stripSuffix ".git" r
755+\Falling back on normal fetchgit. Original failure:\n\n"
761− repo = N $ dropGitExtension $ T.pack repo'
756+ errorToWarning e
762− commit = N commit'
757+ let s' = forgetGithub True s
763− branch = N <$> branch'
758+ (,) (ThunkSource_Git s') <$> gitThunkRev s' commit
764− mauth <- liftIO $ getHubAuth "github.com"
759+ ThunkSource_Git s -> (,) (ThunkSource_Git s) <$> gitThunkRev s commit
765− repoResult <- liftIO $ executeRequestMaybe mauth $ repositoryR owner repo
760+ pure $ ThunkPtr
766− repoIsPrivate <- either (liftIO . throwIO) (return . repoPrivate) repoResult
761+ { _thunkPtr_rev = rev
767− archiveResult <- liftIO $ executeRequestMaybe mauth $
762+ , _thunkPtr_source = src
768− archiveForR owner repo ArchiveFormatTarball (Just (untagName commit))
763+ }
769− archiveUri <- either (liftIO . throwIO) return archiveResult
764+
770− hash <- getNixSha256ForUriUnpacked archiveUri
765+-- | N.B. Cannot infer all fields.
771− return $ ThunkPtr
766+--
772− { _thunkPtr_rev = ThunkRev
767+-- If the thunk is a GitHub thunk and fails, we do *not* fall back like with
773− { _thunkRev_commit = commitNameToRef commit
768+-- `uriThunkPtr`. Unlike a plain URL, a thunk src explicitly states which method
774− , _thunkRev_nixSha256 = hash
769+-- should be employed, and so we respect that.
775− }
770+uriToThunkSource :: URI -> Maybe Text -> ThunkSource
776− , _thunkPtr_source = ThunkSource_GitHub $ GitHubSource
771+uriToThunkSource u
777− { _gitHubSource_owner = owner
772+ | Right uriAuth <- uriAuthority u
778− , _gitHubSource_repo = repo
773+ , Just scheme <- unRText <$> uriScheme u
779− , _gitHubSource_branch = branch
774+ , case scheme of
780− , _gitHubSource_private = repoIsPrivate
775+ "ssh" -> uriAuth == Authority
781− }
776+ { authUserInfo = Just $ UserInfo (fromRight' $ mkUsername "git") Nothing
782− }
777+ , authHost = fromRight' $ mkHost "github.com"
783− gitThunkPtr u commit branch' = do
778+ , authPort = Nothing
784− let protocols = ["https:", "ssh:", "git:"]
785− unless (T.toLower (T.pack $ uriScheme u) `elem` protocols) $
786− failWith $ "thunk pack: obelisk currently only supports "
787− <> T.intercalate ", " protocols <> " protocols for non-GitHub remotes"
788− hash <- nixPrefetchGit u commit False
789− branch <- case branch' of
790− Nothing -> failWith "thunk pack: git thunks must track a branch"
791− Just b -> pure $ N b
793− { _thunkPtr_rev = ThunkRev
794− { _thunkRev_commit = commitNameToRef (N commit)
795− , _thunkRev_nixSha256 = hash
797− , _thunkPtr_source = ThunkSource_Git $ GitSource
798− { _gitSource_url = u
799− , _gitSource_branch = branch
800− , _gitSource_fetchSubmodules = False -- TODO: How do we determine if this should be true?
780+ s -> s `L.elem` [ "git", "https", "http" ] -- "http:" just redirects to "https:"
781+ && unRText (authHost uriAuth) == "github.com"
782+ , Just (_, owner :| [repoish]) <- uriPath u
783+ = \mbranch -> ThunkSource_GitHub $ GitHubSource
784+ { _gitHubSource_owner = N $ unRText owner
785+ , _gitHubSource_repo = N $ let
786+ repoish' = unRText repoish
787+ in case T.stripSuffix ".git" repoish' of
790+ , _gitHubSource_branch = N <$> mbranch
793+ | otherwise = \mbranch -> ThunkSource_Git $ GitSource
794+ { _gitSource_url = u
795+ , _gitSource_branch = N <$> mbranch
796+ , _gitSource_fetchSubmodules = False -- TODO: How do we determine if this should be true?
799+-- Funny signature indicates no effects depend on the optional branch name.
806+githubThunkRev s commit = do
807+ owner <- forcePP $ _gitHubSource_owner s
808+ repo <- forcePP $ _gitHubSource_repo s
809+ revTarball <- mkPathPiece $ commit <> ".tar.gz"
810+ let archiveUri = URI
811+ { uriScheme = Just $ fromRight' $ mkScheme "https"
812+ , uriAuthority = Right $ Authority
813+ { authUserInfo = Nothing
814+ , authHost = fromRight' $ mkHost "github.com"
815+ , authPort = Nothing
817+ , uriPath = Just ( False
818+ , owner :| [ repo, fromRight' $ mkPathPiece "archive", revTarball ]
821+ , uriFragment = Nothing
823+ hash <- getNixSha256ForUriUnpacked archiveUri
824+ putLog Debug $ "Nix sha256 is " <> hash
826+ { _thunkRev_commit = commitNameToRef $ N commit
827+ , _thunkRev_nixSha256 = hash
830+ forcePP :: Name entity -> m (RText 'PathPiece)
831+ forcePP = mkPathPiece . untagName
838+gitThunkRev s commit = do
839+ let u = _gitSource_url s
840+ protocols = ["https", "ssh", "git"]
841+ Just scheme <- pure $ unRText <$> uriScheme u
842+ unless (T.toLower scheme `elem` protocols) $
843+ failWith $ "obelisk currently only supports "
844+ <> T.intercalate ", " protocols <> " protocols for non-GitHub remotes"
845+ hash <- nixPrefetchGit u commit $ _gitSource_fetchSubmodules s
846+ putLog Informational $ "Nix sha256 is " <> hash
848+ { _thunkRev_commit = commitNameToRef (N commit)
849+ , _thunkRev_nixSha256 = hash
852+-- | Given the URI to a git remote, and an optional branch name, return the name
853+-- of the branch along with the hash of the commit at tip of that branch.
855+-- If the branch name is passed in, it is returned exactly as-is. If it is not
856+-- passed it, the default branch of the repo is used instead.
858+ :: MonadObelisk m => URI -> Maybe Text -> m (Text, CommitId)
859+gitGetCommitBranch uri mbranch = withExitFailMessage ("Failure for git remote " <> uriMsg) $ do
860+ bothMaps <- gitLsRemote
861+ (T.unpack $ render uri)
862+ (GitRef_Branch <$> mbranch)
863+ branch <- case mbranch of
864+ Nothing -> withExitFailMessage "Failed to find default branch" $ do
865+ b <- rethrowE $ gitLookupDefaultBranch bothMaps
866+ putLog Debug $ "Default branch for remote repo " <> uriMsg <> " is " <> b
869+ commit <- rethrowE $ gitLookupCommitForRef bothMaps (GitRef_Branch branch)
870+ putLog Informational $ "Latest commit in branch " <> branch
871+ <> " from remote repo " <> uriMsg
873+ pure (branch, commit)
875+ rethrowE = either failWith pure
804parseGitUri :: Text -> Maybe URI
878parseGitUri :: Text -> Maybe URI
805−parseGitUri x = parseURIReference (T.unpack x) <|> parseSshShorthand x
879+parseGitUri x = parseAbsoluteURI x <|> parseSshShorthand x
881+parseAbsoluteURI :: Text -> Maybe URI
882+parseAbsoluteURI uri = do
883+ parsedUri <- mkURI uri
884+ guard $ isPathAbsolute parsedUri
807parseSshShorthand :: Text -> Maybe URI
887parseSshShorthand :: Text -> Maybe URI
808parseSshShorthand uri = do
888parseSshShorthand uri = do
@@ -817,4 +897,4 @@ parseSshShorthand uri = do
817 -- This check is used to disambiguate a filepath containing a colon from shorthand
897 -- This check is used to disambiguate a filepath containing a colon from shorthand
818 guard $ isNothing (T.findIndex (=='/') authAndHostname)
898 guard $ isNothing (T.findIndex (=='/') authAndHostname)
819 && not (T.null colonAndPath)
899 && not (T.null colonAndPath)
820− parseURI $ T.unpack properUri
900+ mkURI properUri
lib/command/src/Obelisk/Command/Upgrade.hsdeleted−293
@@ -1,293 +0,0 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3−{-# LANGUAGE LambdaCase #-}
4−{-# LANGUAGE MultiParamTypeClasses #-}
5−{-# LANGUAGE OverloadedStrings #-}
6−{-# LANGUAGE ScopedTypeVariables #-}
7−{-# LANGUAGE TypeApplications #-}
8−module Obelisk.Command.Upgrade where
10−import Control.Monad (forM, unless, void)
11−import Control.Monad.Catch (onException)
12−import Control.Monad.Except
13−import Control.Monad.IO.Class (liftIO)
14−import Data.Maybe (catMaybes)
15−import Data.Monoid (Any (..), getAny)
16−import Data.Semigroup ((<>))
17−import qualified Data.Set as S
18−import Data.Text (Text)
19−import qualified Data.Text as T
20−import System.Directory
21−import System.FilePath
22−import System.Posix.Process (executeFile)
24−import Obelisk.App (MonadObelisk)
26−import Obelisk.Command.Utils
28−import Obelisk.Command.Project (toImplDir)
29−import Obelisk.Command.Project (findProjectObeliskCommand)
30−import Obelisk.Command.Thunk (ThunkData (..), getThunkGitBranch, readThunk, updateThunk)
32−import Obelisk.Command.Upgrade.Hash
33−import Obelisk.Migration
35−newtype HandOffAction = HandoffAction Any
36− deriving (Monoid, Semigroup, Ord, Eq, Show)
38−instance Action HandOffAction where
39− parseEdgeMeta = HandoffAction . Any . (== "True")
42− = MigrationGraph_ObeliskUpgrade
43− | MigrationGraph_ObeliskHandoff
44− deriving (Eq, Show, Bounded, Enum)
46−graphName :: MigrationGraph -> Text
48− MigrationGraph_ObeliskHandoff -> "obelisk-handoff"
49− MigrationGraph_ObeliskUpgrade -> "obelisk-upgrade"
51−fromGraphName :: Text -> MigrationGraph
53− "obelisk-handoff" -> MigrationGraph_ObeliskHandoff
54− "obelisk-upgrade" -> MigrationGraph_ObeliskUpgrade
55− _ -> error "Invalid graph name specified"
58−graphNames = fmap graphName $ [minBound .. maxBound]
60−ensureCleanProject :: MonadObelisk m => FilePath -> m ()
61−ensureCleanProject project =
62− ensureCleanGitRepo project False "Cannot upgrade with uncommited changes"
64−-- | Decide whether we (ambient ob) should handoff to project obelisk before performing upgrade
65−decideHandOffToProjectOb :: MonadObelisk m => FilePath -> m Bool
66−decideHandOffToProjectOb project = do
67− ensureCleanProject project
68− updateThunk (toImplDir project) $ \projectOb -> do
69− (ambientGraph, ambientHash) <- getAmbientObInfo
70− projectHash <- computeVertexHash projectOb
71− case hasVertex projectHash ambientGraph of
73− putLog Warning "Project ob not found in ambient ob's migration graph; handing off anyway"
75− True -> handleMigrationError (findPathAction ambientGraph projectHash ambientHash) >>= \case
77− putLog Warning "No migration path between project and ambient ob; handing off anyway"
79− Just (HandoffAction dontHandoff) -> do
80− return $ not $ getAny dontHandoff
82− getAmbientObInfo = do
83− ambientOb <- getAmbientOb
84− getMigrationGraph' ambientOb MigrationGraph_ObeliskHandoff >>= \case
86− failWith "Ambient ob has no migration (this can't be possible)"
88− -- We don't have ambient's ob source code, so locate its hash from the
89− -- graph. The last vertex should be it.
90− ambientHash <- handleMigrationError $ getLast (_migration_graph m)
91− return (m, ambientHash)
93−-- | Return the path to the current ('ambient') obelisk process Nix directory
94−getAmbientOb :: MonadObelisk m => m FilePath
95−getAmbientOb = takeDirectory . takeDirectory <$> liftIO getObeliskExe
97−upgradeObelisk :: MonadObelisk m => FilePath -> Maybe Text -> m ()
98−upgradeObelisk project gitBranchM = do
99− ensureCleanProject project
100− gitBranch <- maybe (getObeliskBranch project) pure gitBranchM
101− updateObelisk project gitBranch >>= handOffToNewOb project
103−getObeliskBranch :: MonadObelisk m => FilePath -> m Text
104−getObeliskBranch project = readThunk (toImplDir project) >>= \case
105− Left e -> failWith $ T.pack $ show e
106− Right (ThunkData_Checkout _) -> failWith "obelisk thunk must be packed"
107− Right (ThunkData_Packed tptr) -> case getThunkGitBranch tptr of
110− failWith "You must run `ob upgrade` with the Git branch specified explicitly, as the project's obelisk thunk does not specify any."
112−updateObelisk :: MonadObelisk m => FilePath -> Text -> m Hash
113−updateObelisk project gitBranch =
114− withSpinner ("Fetching new obelisk [" <> gitBranch <> "]") $
115− updateThunk (toImplDir project) $ \obImpl -> do
116− fromHash <- computeVertexHash obImpl
117− callProcessAndLogOutput (Debug, Debug) $
118− gitProc obImpl ["checkout", T.unpack gitBranch]
119− callProcessAndLogOutput (Debug, Debug) $
120− gitProc obImpl ["pull"]
123−handOffToNewOb :: MonadObelisk m => FilePath -> Hash -> m ()
124−handOffToNewOb project fromHash = do
125− impl <- withSpinner' "Preparing for handoff" (Just $ ("Handed off to new obelisk " <>) . T.pack) $
126− findProjectObeliskCommand project >>= \case
127− Nothing -> failWith "Not an obelisk project"
128− Just impl -> pure impl
129− let opts = ["internal", "migrate", T.unpack fromHash]
130− liftIO $ executeFile impl False ("--no-handoff" : opts) Nothing
132−migrateObelisk :: MonadObelisk m => FilePath -> Hash -> m ()
133−migrateObelisk project fromHash = void $ withSpinner' "Migrating to new obelisk" (Just id) $ do
134− updateThunk (toImplDir project) $ \obImpl -> revertObImplOnFail obImpl $ do
135− toHash <- computeVertexHash obImpl
136− g <- getMigrationGraph' obImpl MigrationGraph_ObeliskUpgrade >>= \case
137− Nothing -> failWith "New obelisk has no migration metadata"
140− unless (hasVertex fromHash g) $ do
141− failWith $ "Current obelisk hash " <> fromHash <> " missing in migration graph of new obelisk"
142− unless (hasVertex toHash g) $ do
143− -- This usually means that the target obelisk branch does not have
144− -- migration vertex for its latest commit; typically due to developer
146− failWith $ "New obelisk hash " <> toHash <> " missing in its migration graph"
148− if fromHash == toHash
150− pure $ "No upgrade available (new Obelisk is the same)"
152− putLog Debug $ "Migrating from " <> fromHash <> " to " <> toHash
153− handleMigrationError (findPathAction g fromHash toHash) >>= \case
155− failWith "Unable to find migration path"
157− unless (action == mempty) $ do
158− putLog Notice "To upgrade your project to the new version of obelisk, please follow these instructions:\n"
159− putLog Notice action
160− pure $ "Migrated from " <> fromHash <> " to " <> toHash
162− revertObImplOnFail impl f = f `onException` do
163− putLog Notice $ T.pack $ "Reverting changes to " <> impl
164− callProcessAndLogOutput (Notice, Notice) $ gitProc project ["checkout", impl]
166−-- | Get the migration graph for project
168− :: (Action action, MonadObelisk m)
169− => FilePath -> MigrationGraph -> m (Migration action)
170−getMigrationGraph obDir graph = getMigrationGraph' obDir graph >>= \case
171− Nothing -> failWith "Migration graph missing"
175− :: (Action action, MonadObelisk m)
176− => FilePath -> MigrationGraph -> m (Maybe (Migration action))
177−getMigrationGraph' obDir graph = do
178− let name = graphName graph
179− dir = migrationDir obDir
180− putLog Debug $ "Reading migration graph " <> name <> " from " <> T.pack dir
181− liftIO $ readGraph dir name
183−computeVertexHash :: MonadObelisk m => FilePath -> m Hash
184−computeVertexHash = getDirectoryHash [migrationDirName]
186−-- | Verify the integrity of the migration graph in relation to the Git repo.
187−verifyMigration :: MonadObelisk m => FilePath -> m ()
188−verifyMigration obDir = do
189− upgradeGraph <- withSpinner "Reading migration graph" $
190− getMigrationGraph @Text obDir MigrationGraph_ObeliskUpgrade
191− withSpinner "Checking graph integrity" $
192− handleMigrationError $ ensureGraphIntegrity upgradeGraph
193− headVertex <- liftIO (doesDirectoryExist $ obDir </> ".git") >>= \case
195− withSpinner "Checking existence of HEAD vertex" $
198− hash <- computeVertexHash obDir
199− unless (hasVertex hash upgradeGraph) $
200− failWith $ "No vertex found for obelisk hash " <> hash
202− withSpinner "Checking graph linearity" $
203− -- NOTE: We don't support merge commits (i.e., diamonds in a graph) yet.
204− -- Until we do, ensure that the graph is a fully connected linear list.
205− runExceptT (ensureGraphLinearity upgradeGraph) >>= \case
206− Left (NonLinearGraph_MultipleAdjacents vertex) ->
207− failWith $ "Graph is not linear; branches at vertex: " <> tshow vertex
208− Left (NonLinearGraph_NotConnected isolatedVertices) ->
209− failWith $ "Graph is partly linear, with isolated vertices: " <> tshow isolatedVertices
211− failWith $ "Error in migration graph: " <> tshow e
212− Right lastVertex -> unless (lastVertex == headVertex) $
213− failWith $ "Graph is linear, but its last vertex (" <> lastVertex <> ") is different from head vertex (" <> headVertex <> ")"
215−-- | Create an edge from HEAD vertex to the hash corresponding to the Git
216−-- working copy. The HEAD vertex must already exist.
217−createMigrationEdgeFromHEAD :: MonadObelisk m => FilePath -> m ()
218−createMigrationEdgeFromHEAD obDir = do
219− headHash <- getHeadVertex obDir
220− wcHash <- getDirectoryHash migrationIgnore obDir
221− if (headHash == wcHash)
223− putLog Warning "No migration necessary (working copy has the same hash as that of HEAD)"
225− writeEdge (migrationDir obDir) graphNames headHash wcHash >>= \case
227− putLog Warning "No migration was created"
229− putLog Notice $ "Created edge: " <> T.pack edgeDir
231−-- | Return the hash corresponding to HEAD
233−-- Fail if the hash does not exist in project's migration graph.
234−getHeadVertex :: MonadObelisk m => FilePath -> m Hash
235−getHeadVertex obDir = do
236− projectGraph <- getMigrationGraph @Text obDir MigrationGraph_ObeliskUpgrade
237− [headHash] <- getHashAtGitRevision ["HEAD"] migrationIgnore obDir
238− unless (hasVertex headHash projectGraph) $ do
239− -- This means that the HEAD commit has no vertex in the graph,
240− -- possibly due to developer negligence when commiting it.
241− -- Perhaps we should use a post-commit hook or some such thing
242− -- to reject such commits in the first place? For now, just
244− failWith $ "No vertex found for HEAD (" <> headHash <> ")"
247−-- | Create, or update, the migration graph with new edges and new vertices
248−-- corresponding to every commit in the Git history from HEAD.
250−-- NOTE: This creates a linear graph, and doesn't follow the Git graph
252−backfillGraph :: MonadObelisk m => Maybe Int -> FilePath -> m ()
253−backfillGraph lastN obDir = do
254− revs <- fmap (takeM lastN . fmap (fst . T.breakOn " ") . T.lines) $
255− readProc $ gitProc obDir ["log", "--pretty=oneline"]
256− -- Note: we need to take unique hashes only; this is fine for backfilling.
257− -- But future migrations should ensure that there are no duplicate hashes
258− -- (which would cause cycles) such as those introduced by revert commits.
259− vertices :: [Hash] <- withSpinnerNoTrail "Computing hash for git history" $
260− fmap (unique . reverse) $ getHashAtGitRevision revs [migrationDirName] obDir
262− ("Backfilling with " <> tshow (length vertices) <> " vertices")
263− (Just $ \n -> "Backfilled " <> tshow n <> " edges.") $ do
264− let vertexPairs = zip vertices $ drop 1 vertices
265− let edgesDir = migrationDir obDir
266− liftIO $ createDirectoryIfMissing False edgesDir
267− fmap (length . catMaybes) $ forM vertexPairs $ \(v1, v2) -> do
268− writeEdge edgesDir graphNames v1 v2
270− -- Return unique items in the list /while/ preserving order
271− unique = loop mempty
275− | S.member x s = loop s xs
276− | otherwise = x : loop (S.insert x s) xs
277− takeM n' xs = case n' of
281−handleMigrationError :: MonadObelisk m => Except MigrationError a -> m a
282−handleMigrationError m = case runExcept m of
283− Left e -> failWith $ "Error in migration graph: " <> tshow e
286−migrationDir :: FilePath -> FilePath
287−migrationDir project = project </> migrationDirName
289−migrationIgnore :: [FilePath]
290−migrationIgnore = [migrationDirName]
292−migrationDirName :: FilePath
293−migrationDirName = "migration"
lib/command/src/Obelisk/Command/Upgrade/Hash.hs+4−5
@@ -102,15 +102,14 @@ tidyUpGitWorkingCopy :: MonadObelisk m => FilePath -> m ()
102tidyUpGitWorkingCopy dir = withSpinnerNoTrail "Tidying up git working copy" $ do
102tidyUpGitWorkingCopy dir = withSpinnerNoTrail "Tidying up git working copy" $ do
103 ignored <- gitLsFiles dir ["--ignored", "--exclude-standard", "--others"]
103 ignored <- gitLsFiles dir ["--ignored", "--exclude-standard", "--others"]
104 untracked <- gitLsFiles dir ["--exclude-standard", "--others"]
104 untracked <- gitLsFiles dir ["--exclude-standard", "--others"]
105− putLog Debug $ T.pack $ "Ignored: " <> show (length ignored) <> " files."
105+ putLog Debug $ "Ignored: " <> T.pack (show $ length ignored) <> " files."
106− putLog Debug $ T.pack $ "Untracked files:\n" <> unlines untracked
106+ putLog Debug $ "Untracked files:\n" <> T.unlines untracked
107 withSpinnerNoTrail "Removing untracked and ignored files" $ do
107 withSpinnerNoTrail "Removing untracked and ignored files" $ do
108− forM_ (fmap (dir </>) $ ignored <> untracked) $
108+ forM_ (fmap ((dir </>) . T.unpack) $ ignored <> untracked) $
109 liftIO . removePathForcibly
109 liftIO . removePathForcibly
110 -- Empty directories won't be included in these lists. Git doesn't track them
110 -- Empty directories won't be included in these lists. Git doesn't track them
111 -- So we must delete these separately.
111 -- So we must delete these separately.
112 runProc $ proc "find" [dir, "-depth", "-empty", "-type", "d", "-delete"]
112 runProc $ proc "find" [dir, "-depth", "-empty", "-type", "d", "-delete"]
114− gitLsFiles pwd opts = fmap lines $ readProcessAndLogStderr Error $
114+ gitLsFiles pwd opts = fmap T.lines $ readProc $
115 (proc "git" $ ["ls-files", "."] <> opts) { cwd = Just pwd }
115 (proc "git" $ ["ls-files", "."] <> opts) { cwd = Just pwd }
lib/command/src/Obelisk/Command/Utils.hs+104−6
@@ -1,16 +1,30 @@
1{-# LANGUAGE FlexibleContexts #-}
1{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE LambdaCase #-}
3+{-# LANGUAGE MultiWayIf #-}
4+{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE OverloadedStrings #-}
5{-# LANGUAGE OverloadedStrings #-}
6+{-# LANGUAGE PatternGuards #-}
4module Obelisk.Command.Utils where
7module Obelisk.Command.Utils where
6−import Control.Applicative (liftA2)
9+import Control.Applicative hiding (many)
10+import Control.Monad.Except
7import Data.Bool (bool)
11import Data.Bool (bool)
12+import qualified Text.Megaparsec.Char.Lexer as ML
8import Data.Semigroup ((<>))
16import Data.Semigroup ((<>))
18+import qualified Data.Map as M
19+import Data.Maybe (maybeToList)
9import Data.Text (Text)
20import Data.Text (Text)
10import qualified Data.Text as T
21import qualified Data.Text as T
22+import Data.Void (Void)
11import System.Directory (canonicalizePath)
23import System.Directory (canonicalizePath)
12import System.Environment (getExecutablePath)
24import System.Environment (getExecutablePath)
13import qualified System.Process as P
25import qualified System.Process as P
26+import Text.Megaparsec as MP
27+import Text.Megaparsec.Char as MP
15import Obelisk.App (MonadObelisk)
29import Obelisk.App (MonadObelisk)
16import Obelisk.CliApp
30import Obelisk.CliApp
@@ -25,7 +39,7 @@ checkGitCleanStatus repo withIgnored = do
25 runGit = readProcessAndLogStderr Debug . gitProc repo
39 runGit = readProcessAndLogStderr Debug . gitProc repo
26 gitStatus = runGit $ ["status", "--porcelain"] <> bool [] ["--ignored"] withIgnored
40 gitStatus = runGit $ ["status", "--porcelain"] <> bool [] ["--ignored"] withIgnored
27 gitDiff = runGit ["diff"]
41 gitDiff = runGit ["diff"]
28− null <$> liftA2 (<>) gitStatus gitDiff
42+ T.null <$> liftA2 (<>) gitStatus gitDiff
30-- | Ensure that git repo is clean
44-- | Ensure that git repo is clean
31ensureCleanGitRepo :: MonadObelisk m => FilePath -> Bool -> Text -> m ()
45ensureCleanGitRepo :: MonadObelisk m => FilePath -> Bool -> Text -> m ()
@@ -46,9 +60,11 @@ initGit repo = do
46 git ["add", "."]
60 git ["add", "."]
47 git ["commit", "-m", "Initial commit."]
61 git ["commit", "-m", "Initial commit."]
63+gitProcNoRepo :: [String] -> P.CreateProcess
64+gitProcNoRepo = P.proc "git"
49gitProc :: FilePath -> [String] -> P.CreateProcess
66gitProc :: FilePath -> [String] -> P.CreateProcess
50−gitProc repo argsRaw =
67+gitProc repo = gitProcNoRepo . runGitInDir
51− P.proc "git" $ runGitInDir argsRaw
53 runGitInDir args' = case filter (not . null) args' of
69 runGitInDir args' = case filter (not . null) args' of
54 args@("clone":_) -> args <> [repo]
70 args@("clone":_) -> args <> [repo]
@@ -60,7 +76,7 @@ copyDir src dest =
60 (P.proc "cp" ["-a", ".", dest]) { P.cwd = Just src }
76 (P.proc "cp" ["-a", ".", dest]) { P.cwd = Just src }
62readGitProcess :: MonadObelisk m => FilePath -> [String] -> m Text
78readGitProcess :: MonadObelisk m => FilePath -> [String] -> m Text
63−readGitProcess repo = fmap T.pack . readProcessAndLogStderr Notice . gitProc repo
79+readGitProcess repo = readProcessAndLogOutput (Debug, Notice) . gitProc repo
65processToShellString :: FilePath -> [String] -> String
81processToShellString :: FilePath -> [String] -> String
66processToShellString cmd args = unwords $ map quoteAndEscape (cmd : args)
82processToShellString cmd args = unwords $ map quoteAndEscape (cmd : args)
@@ -76,7 +92,89 @@ runProcSilently = callProcessAndLogOutput (Debug, Debug)
77-- | A simpler wrapper for CliApp's readProcessAndLogStderr with sensible defaults.
93-- | A simpler wrapper for CliApp's readProcessAndLogStderr with sensible defaults.
78readProc :: MonadObelisk m => P.CreateProcess -> m Text
94readProc :: MonadObelisk m => P.CreateProcess -> m Text
79−readProc = fmap T.pack . readProcessAndLogStderr Error
95+readProc = readProcessAndLogOutput (Debug, Error)
81tshow :: Show a => a -> Text
97tshow :: Show a => a -> Text
82tshow = T.pack . show
98tshow = T.pack . show
100+gitLookupDefaultBranch :: GitLsRemoteMaps -> Either Text Text
101+gitLookupDefaultBranch (refs, _) = do
102+ ref <- case M.lookup GitRef_Head refs of
103+ Just ref -> pure ref
104+ Nothing -> throwError
105+ "No symref entry for HEAD. \
106+ \ Is your git version at least 1.8.5? \
107+ \ Otherwise `git ls-remote --symref` will not work."
109+ GitRef_Branch b -> pure b
111+ "Default ref " <> showGitRef ref <> " is not a branch!"
113+gitLookupCommitForRef :: GitLsRemoteMaps -> GitRef -> Either Text CommitId
114+gitLookupCommitForRef (_, commits) ref = case M.lookup ref commits of
116+ Nothing -> throwError $ "Did not find commit for " <> showGitRef ref
122+ -> m GitLsRemoteMaps
123+gitLsRemote repository mRef = do
124+ t <- readProc $ gitProcNoRepo $
125+ ["ls-remote", "--symref", repository]
126+ ++ (maybeToList $ T.unpack . showGitRef <$> mRef)
127+ maps <- case MP.runParser parseLsRemote "" t of
128+ Left err -> failWith $ T.pack $ MP.parseErrorPretty' t err
129+ Right table -> pure $ bimap M.fromList M.fromList $ partitionEithers $ table
130+ putLog Debug $ "git ls-remote maps: " <> T.pack (show maps)
133+lexeme :: Parsec Void Text a -> Parsec Void Text a
134+lexeme = ML.lexeme $ void $ MP.takeWhileP (Just "within-line white space") $
135+ flip elem [' ', '\t']
137+-- $ git ls-remote --symref git@github.com:obsidiansystems/obelisk.git HEAD
138+-- ref: refs/heads/master HEAD
139+-- d0a8d25dc93f0acd096bc4ff2f550da9e2d0c8f5 refs/heads/master
140+parseLsRemote :: Parsec Void Text [Either (GitRef, GitRef) (GitRef, CommitId)]
142+ many ((fmap Left (try parseRef) <|> fmap Right parseCommit) <* try MP.eol) <* MP.eof
144+ parseRef :: Parsec Void Text (GitRef, GitRef)
145+ parseRef = MP.label "ref and symbolic ref" $ do
147+ ref <- lexeme $ MP.takeWhileP (Just "ref") $ not . isSpace
148+ symbolicRef <- lexeme $ MP.takeWhileP (Just "symbolic ref") $ not . isSpace
149+ return (toGitRef symbolicRef, toGitRef ref)
150+ parseCommit :: Parsec Void Text (GitRef, CommitId)
151+ parseCommit = MP.label "commit and ref" $ do
152+ commitId <- lexeme $ MP.takeWhileP (Just "commit id") $ not . isSpace
153+ ref <- lexeme $ MP.takeWhileP (Just "ref") $ not . isSpace
154+ return (toGitRef ref, commitId)
158+ | GitRef_Branch Text
161+ deriving (Show, Eq, Ord)
163+showGitRef :: GitRef -> Text
165+ GitRef_Head -> "HEAD"
166+ GitRef_Branch x -> "refs/heads/" <> x
167+ GitRef_Tag x -> "refs/tags/" <> x
170+toGitRef :: Text -> GitRef
172+ "HEAD" -> GitRef_Head
174+ | Just s <- "refs/heads/" `T.stripPrefix` r -> GitRef_Branch s
175+ | Just s <- "refs/tags/" `T.stripPrefix` r -> GitRef_Tag s
176+ | otherwise -> GitRef_Other r
180+type GitLsRemoteMaps = (Map GitRef GitRef, Map GitRef CommitId)
lib/command/src/Obelisk/Command/VmBuilder.hs+10−6
@@ -1,11 +1,12 @@
1{-# LANGUAGE FlexibleContexts #-}
1{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE QuasiQuotes #-}
3{-# LANGUAGE QuasiQuotes #-}
4+{-# LANGUAGE ScopedTypeVariables #-}
4module Obelisk.Command.VmBuilder where
5module Obelisk.Command.VmBuilder where
6import Control.Applicative (liftA2)
7import Control.Applicative (liftA2)
7import Control.Monad (unless)
8import Control.Monad (unless)
8−import Control.Monad.Catch (try)
9+import Control.Monad.Catch (try, handle)
9import Control.Monad.IO.Class (liftIO)
10import Control.Monad.IO.Class (liftIO)
10import Data.Either (isRight)
11import Data.Either (isRight)
11import Data.Monoid ((<>))
12import Data.Monoid ((<>))
@@ -42,13 +43,16 @@ containerName = "obelisk-docker-nix-builder"
43-- | Check to see if the Docker container exists. This will exit with a helpful message if Docker is not installed.
44-- | Check to see if the Docker container exists. This will exit with a helpful message if Docker is not installed.
44containerExists :: MonadObelisk m => m Bool
45containerExists :: MonadObelisk m => m Bool
45−containerExists = withExitFailMessage needDockerMsg $ do
46+containerExists = handle (\(_ :: IOError) -> failWith needDockerMsg) $ do
46− containerNames <- fmap (map T.strip . T.lines . T.pack) $
47+ containerNames <- fmap (map T.strip . T.lines) $
47 readProcessAndLogStderr Error $
48 readProcessAndLogStderr Error $
48 proc "docker" ["container", "list", "--all", "--format", "{{.Names}}"]
49 proc "docker" ["container", "list", "--all", "--format", "{{.Names}}"]
49 pure $ containerName `elem` containerNames
50 pure $ containerName `elem` containerNames
52+ needDockerMsg = T.intercalate "\n"
51− needDockerMsg = "This feature requires that you have Docker installed and the `docker` command available on your PATH. Please go https://docs.docker.com/ to install Docker and try this command again."
53+ [ "This feature requires that you have Docker installed and the `docker` command available on your PATH."
54+ , "Please go https://docs.docker.com/ to install Docker and try this command again."
53-- | SSH port on localhost that connects to the container.
57-- | SSH port on localhost that connects to the container.
54containerSshPort :: Int
58containerSshPort :: Int
@@ -74,14 +78,14 @@ setupNixDocker stateDir = withSpinner ("Creating Docker container named " <> con
74 proc "ssh-keygen" ["-t", "ed25519", "-f", stateDir </> sshKeyFileName, "-P", ""]
78 proc "ssh-keygen" ["-t", "ed25519", "-f", stateDir </> sshKeyFileName, "-P", ""]
76 -- Build the docker container (which uses the SSH keys in the 'ssh' folder)
80 -- Build the docker container (which uses the SSH keys in the 'ssh' folder)
77− containerId <- readProcessAndLogStderr Error $
81+ containerId <- fmap T.strip $ readProcessAndLogStderr Error $
78 proc "docker" ["build", stateDir, "--quiet"]
82 proc "docker" ["build", stateDir, "--quiet"]
79 callProcessAndLogOutput (Debug, Error) $ proc "docker"
83 callProcessAndLogOutput (Debug, Error) $ proc "docker"
81 , "--restart", "always"
85 , "--restart", "always"
82 , "--detach"
86 , "--detach"
83 , "--publish", show containerSshPort <> ":22"
87 , "--publish", show containerSshPort <> ":22"
84− , "--name", containerName, containerId
88+ , "--name", T.unpack containerName, T.unpack containerId
86 exists <- containerExists
90 exists <- containerExists
87 unless exists $
91 unless exists $
lib/migration/obelisk-migration.cabaldeleted−24
@@ -1,24 +0,0 @@
1−name: obelisk-migration
10− algebraic-graphs >= 0.2
24− ghc-options: -Wall -fobject-code
lib/migration/src/Obelisk/Migration.hsdeleted−223
@@ -1,223 +0,0 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE LambdaCase #-}
3−{-# LANGUAGE OverloadedStrings #-}
4−{-# LANGUAGE ScopedTypeVariables #-}
5−{-# LANGUAGE TupleSections #-}
6−module Obelisk.Migration where
8−import Control.Monad (forM, forM_, unless, void)
9−import Control.Monad.Except
10−import Control.Monad.IO.Class (MonadIO, liftIO)
11−import Control.Monad.State.Strict (evalStateT, get, put)
13−import qualified Data.Map as Map
14−import Data.Maybe (catMaybes)
15−import Data.Semigroup ((<>))
17−import qualified Data.Set as Set
18−import Data.Text (Text)
19−import qualified Data.Text as T
20−import qualified Data.Text.IO as T
21−import System.Directory
22−import System.FilePath
24−import Algebra.Graph.AdjacencyMap
28−-- Migration graph with edge metadata
29−data Migration action = Migration
30− { _migration_graph :: AdjacencyMap Hash
31− , _migration_actions :: Map (Hash, Hash) action -- Edge metadata
35−-- A path is a list of edges
36−type Path = [(Hash, Hash)]
39− = GraphInternalError Text
41− | MultipleTerminalVertices
43− | NonEquivalentPaths Hash Hash
44− | MissingEdgeInActionMap (Hash, Hash)
45− | NonLinearGraph_MultipleAdjacents Hash
46− | NonLinearGraph_NotConnected (Set Hash)
47− deriving (Eq, Ord, Show)
49−class Action action where
50− parseEdgeMeta :: Text -> action
52−instance Action Text where
55−-- | Get the directed-acylic graph of migration
56−-- TODO: Consider calling getDag only when reading the graph for efficiency.
57−getDag :: (MonadError MigrationError m, Ord a) => AdjacencyMap a -> m (AdjacencyMap a)
58−getDag g = case topSort g of
60− Nothing -> throwError CyclicGraphError
62−-- | Read the graph from a directory of files.
63−readGraph :: Action action => FilePath -> Text -> IO (Maybe (Migration action))
64−readGraph root name = doesDirectoryExist root >>= \case
65− False -> return Nothing
67− allVertexPairs <- listDirectory root >>= return . catMaybes . fmap getEdgeVertices
68− edgesInfo <- fmap catMaybes $ forM allVertexPairs $ \vs -> do
69− getEdgeFor name vs >>= return . fmap (vs, )
70− return $ pure $ Migration (edges $ fmap fst edgesInfo) (Map.fromList edgesInfo)
72− getEdgeVertices p = case T.splitOn "-" $ T.pack p of
73− [v1, v2] -> Just (v1, v2)
75− getEdgeFor graph (v1, v2) = do
76− let f = root </> (T.unpack $ v1 <> "-" <> v2) </> T.unpack graph
77− doesFileExist f >>= \case
79− c <- parseEdgeMeta <$> T.readFile f
84−-- | Ensure that the migration graph is correct
86−-- In a correct migration graph: for all pairs of nodes, all paths between
87−-- those nodes have the same migration value
89−-- Throw the following if integrity check fails
90−-- * `CyclicGraphError`
91−-- * `NonEquivalentPaths`
95− :: (MonadError MigrationError m, Monoid action, Ord action)
96− => Migration action -> m ()
97−ensureGraphIntegrity m = do
98− graph <- fmap adjacencyMap $ getDag $ _migration_graph m
99− firstVertex <- getFirst $ _migration_graph m
101− visitFrom visited acc start = case Map.lookup start graph of
103− Just adjs -> void $ flip traverse (Set.toList adjs) $ \adj -> do
104− acc' <- fmap (mappend acc) $ getAction m (start, adj)
105− visited' <- case Map.lookup adj visited of
106− Nothing -> pure $ Map.insert adj acc' visited
107− Just adjAcc -> if acc' == adjAcc
109− else throwError $ NonEquivalentPaths start adj
110− visitFrom visited' acc' adj
111− -- We only check all paths from the _first_ vertex; it is not necessary to
112− -- check all paths between _all_ pairs of vertices as that can be proved by
113− -- induction, as long as there is exactly one first vertex (which we check on
115− visitFrom mempty mempty firstVertex
117−-- | Ensure that the graph is a fully connected linear list
119−-- Returns the last vertex in the linear list.
120−ensureGraphLinearity :: MonadError MigrationError m => Migration action -> m Hash
121−ensureGraphLinearity m = do
122− graph <- fmap adjacencyMap $ getDag $ _migration_graph m
123− firstVertex <- getFirst $ _migration_graph m
125− allVertices = vertexSet $ _migration_graph m
126− visitFrom start = case Map.lookup start graph of
127− Nothing -> throwError $ GraphInternalError $ "Vertex not found: " <> start
128− Just adjs -> case (Set.toList adjs) of
129− [] -> pure (start, [start])
130− [adj] -> fmap (start :) <$> visitFrom adj
131− _ -> throwError $ NonLinearGraph_MultipleAdjacents start
132− (lastVertex, visitedVertices) <- visitFrom firstVertex
133− let unvisitedVertices = Set.difference allVertices $ Set.fromList visitedVertices
134− if Set.null unvisitedVertices
135− then pure lastVertex
136− else throwError $ NonLinearGraph_NotConnected unvisitedVertices
138−-- | Find the concatenated actions between two vertices
140−-- All paths between the vertices must have the same mappend'ed action;
141−-- otherwise this will throw.
143−-- Complexity: O(V+E)
145− :: (MonadError MigrationError m, Action action, Monoid action, Ord action)
146− => Migration action -> Hash -> Hash -> m (Maybe action)
147−findPathAction m start end = flip evalStateT Map.empty $ do
148− graph <- fmap adjacencyMap $ getDag $ _migration_graph m
150− findPathFromCached start' = do
151− -- TODO: refactor the caching part into a separate `memoize` function
153− case Map.lookup start' cache of
157− result <- findPathFrom start'
158− put $ Map.insert start' result cache
160− findPathFrom start' = if start' == end
163− else case Map.lookup start' graph of
165− actions <- fmap catMaybes $ flip traverse (Set.toList adjs) $ \adj -> do
166− action0 <- getAction m (start', adj)
167− actionM <- findPathFromCached adj
168− pure $ fmap (mappend action0) $ actionM
169− case uniqs actions of
171− [v] -> pure $ Just v -- Exactly one monoidal value; accept.
172− _ -> throwError $ NonEquivalentPaths start' end
175− uniqs = Set.toList . Set.fromList
176− findPathFromCached start
178−hasVertex :: Hash -> Migration action -> Bool
179−hasVertex h (Migration g _) = Set.member h $ vertexSet g
181−-- | Get the action for the given edge (which must exist)
182−getAction :: MonadError MigrationError m => Migration action -> (Hash, Hash) -> m action
183−getAction (Migration _ h) e = case Map.lookup e h of
185− Nothing -> throwError $ MissingEdgeInActionMap e
187−-- | Get the last vertex of the given DAG. Nothing if empty graph.
189−-- Assumes that the graph is fully connected.
190−getLast :: (MonadError MigrationError m, Ord a, Eq a) => AdjacencyMap a -> m a
191−getLast g = lastVertices >>= \case
192− [] -> throwError NoTerminalVertex
194− _ -> throwError MultipleTerminalVertices
199− . filter (\(_, nexts) -> nexts == [])
203−-- | Get the first vertex of the given DAG. Nothing if empty graph.
204−getFirst :: (MonadError MigrationError m, Ord a, Eq a) => AdjacencyMap a -> m a
205−getFirst = getLast . transpose
207−-- | Write an edge directly to the filesystem.
209−-- Actions are written with empty string.
211−-- Return the edge directory created.
212−writeEdge :: MonadIO m => FilePath -> [Text] -> Hash -> Hash -> m (Maybe FilePath)
213−writeEdge dir actionFiles v1 v2 = do
215− fail $ "Cannot create self loop with: " <> T.unpack v1
216− let edgeDir = dir </> (T.unpack $ v1 <> "-" <> v2)
217− liftIO (doesDirectoryExist edgeDir) >>= \case
218− True -> pure Nothing
220− liftIO $ createDirectory edgeDir
221− forM_ actionFiles $ \fp -> liftIO $
222− writeFile (edgeDir </> T.unpack fp) ""
lib/selftest/src/Obelisk/SelfTest.hs+16−18
@@ -1,3 +1,4 @@
1+{-# LANGUAGE EmptyCase #-}
1{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE PatternGuards #-}
4{-# LANGUAGE PatternGuards #-}
@@ -14,6 +15,7 @@ import Data.Semigroup (Semigroup, (<>))
14import qualified Data.Set as Set
15import qualified Data.Set as Set
15import Data.String
16import Data.String
16import Data.Text (Text)
17import Data.Text (Text)
17import qualified Data.Text as T
19import qualified Data.Text as T
18import qualified Data.Text.IO as T
20import qualified Data.Text.IO as T
19import qualified Network.HTTP.Client as HTTP
21import qualified Network.HTTP.Client as HTTP
@@ -27,7 +29,6 @@ import System.Info
27import System.IO (Handle, hClose)
29import System.IO (Handle, hClose)
28import System.IO.Temp
30import System.IO.Temp
29import System.Process (readProcessWithExitCode, CreateProcess(cwd), readCreateProcessWithExitCode, proc)
31import System.Process (readProcessWithExitCode, CreateProcess(cwd), readCreateProcessWithExitCode, proc)
31import Test.Hspec
32import Test.Hspec
32import Test.HUnit.Base
33import Test.HUnit.Base
@@ -38,7 +39,7 @@ import Obelisk.Run (getConfigRoute)
38data ObRunState
39data ObRunState
39 = ObRunState_Init
40 = ObRunState_Init
40 | ObRunState_Startup
41 | ObRunState_Startup
41− | ObRunState_BackendStarted Text -- Port of backend
42+ | ObRunState_BackendStarted
42 deriving (Eq, Show)
43 deriving (Eq, Show)
44doubleQuotes :: (IsString a, Semigroup a) => a -> a
45doubleQuotes :: (IsString a, Semigroup a) => a -> a
@@ -53,9 +54,10 @@ commit msg = void $ run "git"
53 , doubleQuotes msg
54 , doubleQuotes msg
57+-- TODO replace Void and stop using loosely typed synchronous exceptions
56−runCli :: MonadIO m => CliT IO a -> m a
58+runCli :: MonadIO m => CliT Void IO a -> m a
57runCli f = liftIO $ do
59runCli f = liftIO $ do
58− c <- newCliConfig Notice False False
60+ c <- newCliConfig Notice False False (\case {})
59 CliApp.runCli c f
61 CliApp.runCli c f
61tshow :: Show a => a -> Text
63tshow :: Show a => a -> Text
@@ -220,12 +222,12 @@ testObRunInDir mdir httpManager = handle_sh (\case ExitSuccess -> pure (); e ->
220 writefile "config/common/route" . uri =<< liftIO getFreePort -- Use a free port initially
222 writefile "config/common/route" . uri =<< liftIO getFreePort -- Use a free port initially
221 maybe id chdir mdir $ runHandle "ob" ["run"] $ \stdout -> do
223 maybe id chdir mdir $ runHandle "ob" ["run"] $ \stdout -> do
222 freePort <- liftIO getFreePort
224 freePort <- liftIO getFreePort
223− (_, firstUri) <- handleObRunStdout httpManager stdout
225+ firstUri <- handleObRunStdout httpManager stdout
224 let newUri = uri freePort
226 let newUri = uri freePort
225 when (firstUri == newUri) $ errorExit $
227 when (firstUri == newUri) $ errorExit $
226 "Startup URI (" <> firstUri <> ") is the same as test URI (" <> newUri <> ")"
228 "Startup URI (" <> firstUri <> ") is the same as test URI (" <> newUri <> ")"
227 maybe id (\_ -> chdir "..") mdir $ alterRouteTo newUri stdout
229 maybe id (\_ -> chdir "..") mdir $ alterRouteTo newUri stdout
228− (_, runningUri) <- handleObRunStdout httpManager stdout
230+ runningUri <- handleObRunStdout httpManager stdout
229 if runningUri /= newUri
231 if runningUri /= newUri
230 then errorExit $ "Reloading failed: expected " <> newUri <> " but got " <> runningUri
232 then errorExit $ "Reloading failed: expected " <> newUri <> " but got " <> runningUri
231 else exit 0
233 else exit 0
@@ -272,32 +274,28 @@ alterRouteTo uri stdout = do
272 "Reloading failed: " <> T.pack (show t)
274 "Reloading failed: " <> T.pack (show t)
274-- | Handle stdout of `ob run`: check that the frontend and backend servers are started correctly
276-- | Handle stdout of `ob run`: check that the frontend and backend servers are started correctly
275−handleObRunStdout :: HTTP.Manager -> Handle -> Sh (Text, Text)
277+handleObRunStdout :: HTTP.Manager -> Handle -> Sh Text
276handleObRunStdout httpManager stdout = flip fix ObRunState_Init $ \loop state -> do
278handleObRunStdout httpManager stdout = flip fix ObRunState_Init $ \loop state -> do
277 liftIO (T.hGetLine stdout) >>= \t -> case state of
279 liftIO (T.hGetLine stdout) >>= \t -> case state of
278 ObRunState_Init
280 ObRunState_Init
279− | "Running test..." `T.isPrefixOf` t -> loop ObRunState_Startup
281+ | "Running test..." `T.isPrefixOf` t -> loop ObRunState_BackendStarted
280 ObRunState_Startup
282 ObRunState_Startup
281 | t == "backend stopped; make a change to your code to reload" -> loop ObRunState_Startup
283 | t == "backend stopped; make a change to your code to reload" -> loop ObRunState_Startup
282− | Just port <- "Backend running on port " `T.stripPrefix` t -> loop $ ObRunState_BackendStarted port
284+ -- | Just port <- "Backend running on port " `T.stripPrefix` t -> loop $ ObRunState_BackendStarted port
283 | not (T.null t) -> errorExit $ "Startup: " <> t -- If theres any other output here, startup failed
285 | not (T.null t) -> errorExit $ "Startup: " <> t -- If theres any other output here, startup failed
284− ObRunState_BackendStarted port
286+ ObRunState_BackendStarted
285 | Just uri <- "Frontend running on " `T.stripPrefix` t -> do
287 | Just uri <- "Frontend running on " `T.stripPrefix` t -> do
286− obRunCheck httpManager stdout port uri
288+ obRunCheck httpManager stdout uri
287− pure (port, uri)
289+ pure uri
288 | not (T.null t) -> errorExit $ "Started: " <> t -- If theres any other output here, startup failed
290 | not (T.null t) -> errorExit $ "Started: " <> t -- If theres any other output here, startup failed
289 _ -> loop state
291 _ -> loop state
291-- | Make requests to frontend/backend servers to check they are working properly
293-- | Make requests to frontend/backend servers to check they are working properly
292−obRunCheck :: HTTP.Manager -> Handle -> Text -> Text -> Sh ()
294+obRunCheck :: HTTP.Manager -> Handle -> Text -> Sh ()
293−obRunCheck httpManager stdout backendPort frontendUri = do
295+obRunCheck httpManager _stdout frontendUri = do
294 let req uri = liftIO $ HTTP.parseRequest (T.unpack uri) >>= flip HTTP.httpLbs httpManager
296 let req uri = liftIO $ HTTP.parseRequest (T.unpack uri) >>= flip HTTP.httpLbs httpManager
295 req frontendUri >>= \r -> when (HTTP.responseStatus r /= HTTP.ok200) $ errorExit $
297 req frontendUri >>= \r -> when (HTTP.responseStatus r /= HTTP.ok200) $ errorExit $
296 "Request to frontend server failed: " <> T.pack (show r)
298 "Request to frontend server failed: " <> T.pack (show r)
297− void $ req $ "http://localhost:" <> backendPort
298− liftIO (timeout 1000000 $ T.hGetLine stdout) >>= \case
299− Just t | "127.0.0.1" `T.isPrefixOf` t -> pure () -- Backend request logged
300− x -> errorExit $ "Couldn't get backend request log: " <> T.pack (show x)
302getFreePort :: IO Socket.PortNumber
300getFreePort :: IO Socket.PortNumber
303getFreePort = Socket.withSocketsDo $ do
301getFreePort = Socket.withSocketsDo $ do
migration/001efbbe866b66eebc6ee1ea0a906f2d-b0c1d039514a686529561f186332c91e/obelisk-handoffdeleted
No changes to the content.
migration/001efbbe866b66eebc6ee1ea0a906f2d-b0c1d039514a686529561f186332c91e/obelisk-upgradedeleted
No changes to the content.
migration/00a480749e96ef7e21fbe8f4943152b1-abdb013baf130e1bd7e7fd04e535c44c/obelisk-handoffdeleted
No changes to the content.
migration/00a480749e96ef7e21fbe8f4943152b1-abdb013baf130e1bd7e7fd04e535c44c/obelisk-upgradedeleted
No changes to the content.
migration/00bee4377690b5040bd5b3702dce2a88-98629a336dcd5fa3524a09f8ea6ad636/obelisk-handoffdeleted
No changes to the content.
migration/00bee4377690b5040bd5b3702dce2a88-98629a336dcd5fa3524a09f8ea6ad636/obelisk-upgradedeleted
No changes to the content.
migration/00c627540326314c7154cc209e8a71e9-67bfa5b784a35e66875fb74ad84a38c0/obelisk-handoffdeleted
No changes to the content.
migration/00c627540326314c7154cc209e8a71e9-67bfa5b784a35e66875fb74ad84a38c0/obelisk-upgradedeleted
No changes to the content.
migration/01c0ee6c93a3f9f69e097c41169927ac-2913c440c7ad7731aae96e60a86bf7a8/obelisk-handoffdeleted
No changes to the content.
migration/01c0ee6c93a3f9f69e097c41169927ac-2913c440c7ad7731aae96e60a86bf7a8/obelisk-upgradedeleted
No changes to the content.
migration/01ddc6354698efa1ae5822da3be562dc-a536d01b9c489f5e00e30abf27427da0/obelisk-handoffdeleted
No changes to the content.
migration/01ddc6354698efa1ae5822da3be562dc-a536d01b9c489f5e00e30abf27427da0/obelisk-upgradedeleted
No changes to the content.
migration/01fb7610e4184ad1b491267fcb0c7f43-c0c1452986b8d4c181bb0c6c83c56a2f/obelisk-handoffdeleted
No changes to the content.
migration/01fb7610e4184ad1b491267fcb0c7f43-c0c1452986b8d4c181bb0c6c83c56a2f/obelisk-upgradedeleted
No changes to the content.
migration/0298e61f6a03e553df08dcef03e27bd1-06d184d1fb27966294a8fee1c7df7cb6/obelisk-handoffdeleted
No changes to the content.
migration/0298e61f6a03e553df08dcef03e27bd1-06d184d1fb27966294a8fee1c7df7cb6/obelisk-upgradedeleted
No changes to the content.
migration/02d0f8b5c7472e6f8a99ec2cfcb59807-5b6770965bbef440db49b0703cd243a3/obelisk-handoffdeleted
No changes to the content.
migration/02d0f8b5c7472e6f8a99ec2cfcb59807-5b6770965bbef440db49b0703cd243a3/obelisk-upgradedeleted
No changes to the content.
migration/02f532fd8bb64a167a5349c2ba8e3331-1088e2464720e12067dd74683546b132/obelisk-handoffdeleted
No changes to the content.
migration/02f532fd8bb64a167a5349c2ba8e3331-1088e2464720e12067dd74683546b132/obelisk-upgradedeleted
No changes to the content.
migration/02fb88dab35884e09deef1721c1cfc13-ae824b83b569b3b23b8e198190371ca0/obelisk-handoffdeleted
No changes to the content.
migration/02fb88dab35884e09deef1721c1cfc13-ae824b83b569b3b23b8e198190371ca0/obelisk-upgradedeleted
No changes to the content.
migration/030ed18dacf3571cbb9e3e7d9d99627b-d37d70fe5d7d11e68b59ce12022281c9/obelisk-handoffdeleted
No changes to the content.
migration/030ed18dacf3571cbb9e3e7d9d99627b-d37d70fe5d7d11e68b59ce12022281c9/obelisk-upgradedeleted
No changes to the content.
migration/03b845f308e73a1567eb843dfca182d2-e9ec84bfe7099b713c0fda32308f5815/obelisk-handoffdeleted
No changes to the content.
migration/03b845f308e73a1567eb843dfca182d2-e9ec84bfe7099b713c0fda32308f5815/obelisk-upgradedeleted
No changes to the content.
migration/03b9747848d7f3e995b118f776ef96c7-3da702ef7f531ad6db874ac3f85e9c06/obelisk-handoffdeleted−1
migration/03b9747848d7f3e995b118f776ef96c7-3da702ef7f531ad6db874ac3f85e9c06/obelisk-upgradedeleted
No changes to the content.
migration/04a5ae41e8fcef5f719cb84d01430382-f391c6a74ee14217ce4565c278fceed6/obelisk-handoffdeleted
No changes to the content.
migration/04a5ae41e8fcef5f719cb84d01430382-f391c6a74ee14217ce4565c278fceed6/obelisk-upgradedeleted
No changes to the content.
migration/04dd95ecb889ac1b0a616ddfeec781c4-f790ac9400501511b4ee045e22bc5fe1/obelisk-handoffdeleted
No changes to the content.
migration/04dd95ecb889ac1b0a616ddfeec781c4-f790ac9400501511b4ee045e22bc5fe1/obelisk-upgradedeleted
No changes to the content.
migration/0535e06dd0d61f3e6970b491a17cf1f8-28a6ada033c86e5ae914cc31cecb6239/obelisk-handoffdeleted
No changes to the content.
migration/0535e06dd0d61f3e6970b491a17cf1f8-28a6ada033c86e5ae914cc31cecb6239/obelisk-upgradedeleted
No changes to the content.
migration/053c0b2f84a7a2eadeb5c3f9575ffa0d-2600ab2ec96d3177d2a6b3462e09862d/obelisk-handoffdeleted
No changes to the content.
migration/053c0b2f84a7a2eadeb5c3f9575ffa0d-2600ab2ec96d3177d2a6b3462e09862d/obelisk-upgradedeleted
No changes to the content.
migration/063665b78b6705e7de952f73fa9797bf-172e629829334d2b33cda8d3b5e0b148/obelisk-handoffdeleted
No changes to the content.
migration/063665b78b6705e7de952f73fa9797bf-172e629829334d2b33cda8d3b5e0b148/obelisk-upgradedeleted
No changes to the content.
migration/06d184d1fb27966294a8fee1c7df7cb6-b1692927da5ed59af72fac5be8094fa2/obelisk-handoffdeleted
No changes to the content.
migration/06d184d1fb27966294a8fee1c7df7cb6-b1692927da5ed59af72fac5be8094fa2/obelisk-upgradedeleted
No changes to the content.
migration/071f5b3326b8886de3eddc927b80eb10-28e25b7a8812869a709579cd34e7bcb4/obelisk-handoffdeleted
No changes to the content.
migration/071f5b3326b8886de3eddc927b80eb10-28e25b7a8812869a709579cd34e7bcb4/obelisk-upgradedeleted
No changes to the content.
migration/07900e6c41ab9a78917f66fcf7e0d9b8-554c459ff2cced3e1b11241ed403890d/obelisk-handoffdeleted
No changes to the content.
migration/07900e6c41ab9a78917f66fcf7e0d9b8-554c459ff2cced3e1b11241ed403890d/obelisk-upgradedeleted
No changes to the content.
migration/07900e6c41ab9a78917f66fcf7e0d9b8-8c84f81d9b09a5e0f028f3c6341ffb36/obelisk-handoffdeleted
No changes to the content.
migration/07900e6c41ab9a78917f66fcf7e0d9b8-8c84f81d9b09a5e0f028f3c6341ffb36/obelisk-upgradedeleted−15
@@ -1,15 +0,0 @@
1−# ob deploy: HTTPs support
3−Obelisk deployments now support HTTPs. You must upgrade the deployment repo
4−associated with the obelisk project as follows:
7−cd /your/project's/deployment/repo
8−echo True > enable_https
9−echo admin@yoursite.com > admin_email
10−echo https://yoursite.com/ > config/common/route
11−git add ... && git commit ...
15−If you do not wish to enable HTTPs, write `False` to `enable_https` instead.
migration/0804ef73b54a4dc7fbde18147f33b4f9-00bee4377690b5040bd5b3702dce2a88/obelisk-handoffdeleted
No changes to the content.
migration/0804ef73b54a4dc7fbde18147f33b4f9-00bee4377690b5040bd5b3702dce2a88/obelisk-upgradedeleted
No changes to the content.
migration/08dbdf23867a8efa680283ad251d3429-f2a9ba4a93c3a04acbee2211bca9e27a/obelisk-handoffdeleted
No changes to the content.
migration/08dbdf23867a8efa680283ad251d3429-f2a9ba4a93c3a04acbee2211bca9e27a/obelisk-upgradedeleted
No changes to the content.
migration/0abd9d31c77be8c9a9e83bf1f73276f6-fc42c5fc24031fc6a8836a10cfb45143/obelisk-handoffdeleted
No changes to the content.
migration/0abd9d31c77be8c9a9e83bf1f73276f6-fc42c5fc24031fc6a8836a10cfb45143/obelisk-upgradedeleted
No changes to the content.
migration/0b2cab546a1526414096980fca85d0d3-99aebbfcac51725464bc59571b7d71b8/obelisk-handoffdeleted
No changes to the content.
migration/0b2cab546a1526414096980fca85d0d3-99aebbfcac51725464bc59571b7d71b8/obelisk-upgradedeleted
No changes to the content.
migration/0c6127453069ad707e34ddfedb67e2f9-7c98ef4a123c1a580d368d14e54961b7/obelisk-handoffdeleted
No changes to the content.
migration/0c6127453069ad707e34ddfedb67e2f9-7c98ef4a123c1a580d368d14e54961b7/obelisk-upgradedeleted
No changes to the content.
migration/0c9826e42d5d4fa9988c7db53722826e-c56de2f95c90def16704f62639246bbc/obelisk-handoffdeleted
No changes to the content.
migration/0c9826e42d5d4fa9988c7db53722826e-c56de2f95c90def16704f62639246bbc/obelisk-upgradedeleted
No changes to the content.
migration/0c991bc3c06801f72df48486ee78e350-58479e482d3828ce44f2c8371ed9135a/obelisk-handoffdeleted
No changes to the content.
migration/0c991bc3c06801f72df48486ee78e350-58479e482d3828ce44f2c8371ed9135a/obelisk-upgradedeleted
No changes to the content.
migration/0d3b4cfe9b4c72b830780a4c44942176-214979923f2d7e6278856493c1978fdc/obelisk-handoffdeleted
No changes to the content.
migration/0d3b4cfe9b4c72b830780a4c44942176-214979923f2d7e6278856493c1978fdc/obelisk-upgradedeleted
No changes to the content.
migration/0da1150f0e9fe57d1fafbb6cabe24fa1-a632452cf9c5956becd1a40512472b43/obelisk-handoffdeleted
No changes to the content.
migration/0da1150f0e9fe57d1fafbb6cabe24fa1-a632452cf9c5956becd1a40512472b43/obelisk-upgradedeleted
No changes to the content.
migration/0e4d0f0f0af0925474b0d772be2b145f-b82e9c3fe22feff4bb3a6be49943fd6c/obelisk-handoffdeleted
No changes to the content.
migration/0e4d0f0f0af0925474b0d772be2b145f-b82e9c3fe22feff4bb3a6be49943fd6c/obelisk-upgradedeleted
No changes to the content.
migration/0ec6f67d94d3913cf3243d813238ec39-0804ef73b54a4dc7fbde18147f33b4f9/obelisk-handoffdeleted
No changes to the content.
migration/0ec6f67d94d3913cf3243d813238ec39-0804ef73b54a4dc7fbde18147f33b4f9/obelisk-upgradedeleted
No changes to the content.
migration/0f78d9d6875933336bbf0c1c8888b73f-d1b3f5f5375558bf91d55c88547784b9/obelisk-handoffdeleted
No changes to the content.
migration/0f78d9d6875933336bbf0c1c8888b73f-d1b3f5f5375558bf91d55c88547784b9/obelisk-upgradedeleted
No changes to the content.
migration/0fb3a912a8aaf5ef6f734a25f0bce7e2-cccf4140dc336263489bcf67c8c58f86/obelisk-handoffdeleted
No changes to the content.
migration/0fb3a912a8aaf5ef6f734a25f0bce7e2-cccf4140dc336263489bcf67c8c58f86/obelisk-upgradedeleted
No changes to the content.
migration/0fba399e046852d4ecf8e1dad831a2f9-6620e6dc5622593e5f671127af9ade05/obelisk-handoffdeleted
No changes to the content.
migration/0fba399e046852d4ecf8e1dad831a2f9-6620e6dc5622593e5f671127af9ade05/obelisk-upgradedeleted
No changes to the content.
migration/0fe60df438daa8a2cca5f2b569e361a5-2e3e85cc59aa31f24f18c027542c0510/obelisk-handoffdeleted
No changes to the content.
migration/0fe60df438daa8a2cca5f2b569e361a5-2e3e85cc59aa31f24f18c027542c0510/obelisk-upgradedeleted
No changes to the content.
migration/1088e2464720e12067dd74683546b132-b2282679f6f63cec89d921c3dd512d1e/obelisk-handoffdeleted
No changes to the content.
migration/1088e2464720e12067dd74683546b132-b2282679f6f63cec89d921c3dd512d1e/obelisk-upgradedeleted
No changes to the content.
migration/11a5917ea91e021f1fa541a2fe158c80-d8adb57b2f2266e128ebb6f6d7e65920/obelisk-handoffdeleted
No changes to the content.
migration/11a5917ea91e021f1fa541a2fe158c80-d8adb57b2f2266e128ebb6f6d7e65920/obelisk-upgradedeleted
No changes to the content.
migration/11f38b38c2d38004bb8a9dbfe2ef3e4a-29d9b8b8ae9698888f3ea90b10ff5e92/obelisk-handoffdeleted
No changes to the content.
migration/11f38b38c2d38004bb8a9dbfe2ef3e4a-29d9b8b8ae9698888f3ea90b10ff5e92/obelisk-upgradedeleted
No changes to the content.
migration/1269155fffe21926f3704d5077e04332-1a97559d049bf85cebb762b7e7b70db1/obelisk-handoffdeleted
No changes to the content.
migration/1269155fffe21926f3704d5077e04332-1a97559d049bf85cebb762b7e7b70db1/obelisk-upgradedeleted
No changes to the content.
migration/12c8a24c34c2d8441f3181d179c2baab-bd6728737dffcc3505d30ada344e2f4b/obelisk-handoffdeleted
No changes to the content.
migration/12c8a24c34c2d8441f3181d179c2baab-bd6728737dffcc3505d30ada344e2f4b/obelisk-upgradedeleted
No changes to the content.
migration/131e1d5cc8163ce9a174a8782be23fe7-e323ce1352e512109f1609276fb509b4/obelisk-handoffdeleted
No changes to the content.
migration/131e1d5cc8163ce9a174a8782be23fe7-e323ce1352e512109f1609276fb509b4/obelisk-upgradedeleted
No changes to the content.
migration/13f6767460e94079cdfa6d5e1df79ecb-c106f9398d5c203a1a296b85c7411bf9/obelisk-handoffdeleted
No changes to the content.
migration/13f6767460e94079cdfa6d5e1df79ecb-c106f9398d5c203a1a296b85c7411bf9/obelisk-upgradedeleted
No changes to the content.
migration/145650b66e83adf5bdb8261593076379-e2be519915794ef130249f2be7640382/obelisk-handoffdeleted
No changes to the content.
migration/145650b66e83adf5bdb8261593076379-e2be519915794ef130249f2be7640382/obelisk-upgradedeleted
No changes to the content.
migration/14840816db4b5cfd5580ae099022604a-aaf979dd0121603a8b48127e1ea47c7d/obelisk-handoffdeleted
No changes to the content.
migration/14840816db4b5cfd5580ae099022604a-aaf979dd0121603a8b48127e1ea47c7d/obelisk-upgradedeleted
No changes to the content.
migration/15f3f3f517b38664131b85da0594522f-9715967793be68dfd8c9a7d631f8d589/obelisk-handoffdeleted
No changes to the content.
migration/15f3f3f517b38664131b85da0594522f-9715967793be68dfd8c9a7d631f8d589/obelisk-upgradedeleted
No changes to the content.
migration/1629d0d70e360df6b2280fac36d21e8a-a825fbb74e8d050a5ce10ec4c62b83f5/obelisk-handoffdeleted
No changes to the content.
migration/1629d0d70e360df6b2280fac36d21e8a-a825fbb74e8d050a5ce10ec4c62b83f5/obelisk-upgradedeleted
No changes to the content.
migration/166c5f8e4a0f1dfd227b075a96237386-a5904e3a899e346fe2fe26314f69c075/obelisk-handoffdeleted
No changes to the content.
migration/166c5f8e4a0f1dfd227b075a96237386-a5904e3a899e346fe2fe26314f69c075/obelisk-upgradedeleted
No changes to the content.
migration/16b24e1a12b93ea83d7656a09d5e3338-8a64ec5f2ee43d69607499f085560857/obelisk-handoffdeleted
No changes to the content.
migration/16b24e1a12b93ea83d7656a09d5e3338-8a64ec5f2ee43d69607499f085560857/obelisk-upgradedeleted
No changes to the content.
migration/17089ea0edc0cf4b6f616936f8a06174-a34d758508a0a5d08bc10e76482c4d11/obelisk-handoffdeleted
No changes to the content.
migration/17089ea0edc0cf4b6f616936f8a06174-a34d758508a0a5d08bc10e76482c4d11/obelisk-upgradedeleted
No changes to the content.
migration/172e629829334d2b33cda8d3b5e0b148-a808a04519bbf2874e41028ded9c180c/obelisk-handoffdeleted
No changes to the content.
migration/172e629829334d2b33cda8d3b5e0b148-a808a04519bbf2874e41028ded9c180c/obelisk-upgradedeleted
No changes to the content.
migration/174fa1072ee767be39b7b01aecea5714-6566f0555737425bae9106d1a4a0a2dd/obelisk-handoffdeleted
No changes to the content.
migration/174fa1072ee767be39b7b01aecea5714-6566f0555737425bae9106d1a4a0a2dd/obelisk-upgradedeleted
No changes to the content.
migration/1859cc62bb2f89f528bb2aa170c36e84-be5a7b436cef0ae35cb074700d5f0d00/obelisk-handoffdeleted
No changes to the content.
migration/1859cc62bb2f89f528bb2aa170c36e84-be5a7b436cef0ae35cb074700d5f0d00/obelisk-upgradedeleted
No changes to the content.
migration/190460dabd2b9773c3fe81902d0c8a62-e7385c9eae2b807a483b73be4295b207/obelisk-handoffdeleted
No changes to the content.
migration/190460dabd2b9773c3fe81902d0c8a62-e7385c9eae2b807a483b73be4295b207/obelisk-upgradedeleted
No changes to the content.
migration/1a08b154ae5f898992128e229090c4d8-4e95e2f8ef50420371b71022c644e25d/obelisk-handoffdeleted
No changes to the content.
migration/1a08b154ae5f898992128e229090c4d8-4e95e2f8ef50420371b71022c644e25d/obelisk-upgradedeleted
No changes to the content.
migration/1a97559d049bf85cebb762b7e7b70db1-5cb98d0250bf5224b94e544a5140a54c/obelisk-handoffdeleted
No changes to the content.
migration/1a97559d049bf85cebb762b7e7b70db1-5cb98d0250bf5224b94e544a5140a54c/obelisk-upgradedeleted
No changes to the content.
migration/1ada2d50d7847a12dbe29df4097b5bdc-11a5917ea91e021f1fa541a2fe158c80/obelisk-handoffdeleted
No changes to the content.
migration/1ada2d50d7847a12dbe29df4097b5bdc-11a5917ea91e021f1fa541a2fe158c80/obelisk-upgradedeleted
No changes to the content.
migration/1b1686b03b41bd840ff46776cec7b33a-31a676fd9e1f69bd07380480ec879da0/obelisk-handoffdeleted
No changes to the content.
migration/1b1686b03b41bd840ff46776cec7b33a-31a676fd9e1f69bd07380480ec879da0/obelisk-upgradedeleted
No changes to the content.
migration/1c1c3f2b4426d5d26377eef08dbccb3c-29abdd56a2dbbf3a2a0715210d441d06/obelisk-handoffdeleted
No changes to the content.
migration/1c1c3f2b4426d5d26377eef08dbccb3c-29abdd56a2dbbf3a2a0715210d441d06/obelisk-upgradedeleted
No changes to the content.
migration/1c2c93819c07f33ad899e39ec6769c3c-909b6b2066cbdc991e6c16455f13637c/obelisk-handoffdeleted
No changes to the content.
migration/1c2c93819c07f33ad899e39ec6769c3c-909b6b2066cbdc991e6c16455f13637c/obelisk-upgradedeleted
No changes to the content.
migration/1c4fc23cbf5653613c6060668e065f37-5b252c24612c2ba868580add9d9c19e3/obelisk-handoffdeleted
No changes to the content.
migration/1c4fc23cbf5653613c6060668e065f37-5b252c24612c2ba868580add9d9c19e3/obelisk-upgradedeleted
No changes to the content.
migration/1c9bdb5c544f2e5432f549653a61dabe-20926beb4c30e2efa819d23e5694645e/obelisk-handoffdeleted
No changes to the content.
migration/1c9bdb5c544f2e5432f549653a61dabe-20926beb4c30e2efa819d23e5694645e/obelisk-upgradedeleted
No changes to the content.
migration/1cc8d98f6f61441570fdde2d697e6e3c-69fafe6ab155ff215b6d9d330f700ba1/obelisk-handoffdeleted
No changes to the content.
migration/1cc8d98f6f61441570fdde2d697e6e3c-69fafe6ab155ff215b6d9d330f700ba1/obelisk-upgradedeleted
No changes to the content.
migration/1d084e187591225f0e8fa6fa824f8863-02f532fd8bb64a167a5349c2ba8e3331/obelisk-handoffdeleted
No changes to the content.
migration/1d084e187591225f0e8fa6fa824f8863-02f532fd8bb64a167a5349c2ba8e3331/obelisk-upgradedeleted
No changes to the content.
migration/1df871cede0758cabe43971d9091279d-0b2cab546a1526414096980fca85d0d3/obelisk-handoffdeleted
No changes to the content.
migration/1df871cede0758cabe43971d9091279d-0b2cab546a1526414096980fca85d0d3/obelisk-upgradedeleted
No changes to the content.
migration/1e36dc8817e2784df36d643b7499092d-ba0ccd5ef6110f6c5133d9d6ea6277f0/obelisk-handoffdeleted
No changes to the content.
migration/1e36dc8817e2784df36d643b7499092d-ba0ccd5ef6110f6c5133d9d6ea6277f0/obelisk-upgradedeleted
No changes to the content.
migration/1e376437f069662df26178e4a7873190-ca5ee8f372ecb07b09283081f0298733/obelisk-handoffdeleted
No changes to the content.
migration/1e376437f069662df26178e4a7873190-ca5ee8f372ecb07b09283081f0298733/obelisk-upgradedeleted
No changes to the content.
migration/1f09fcf196bfe90ed52f113c38ffbfdb-d16784e9a2d93db7f953941e3003fa8c/obelisk-handoffdeleted
No changes to the content.
migration/1f09fcf196bfe90ed52f113c38ffbfdb-d16784e9a2d93db7f953941e3003fa8c/obelisk-upgradedeleted
No changes to the content.
migration/1f5b6e2a19c87d3820b953f942ab4a27-8b098f49e1fd1aa10ca22b9dc312644e/obelisk-handoffdeleted
No changes to the content.
migration/1f5b6e2a19c87d3820b953f942ab4a27-8b098f49e1fd1aa10ca22b9dc312644e/obelisk-upgradedeleted
No changes to the content.
migration/1f7fb90cb1e558f5285b2d19a25a1078-5a98cdb6c195e88beac878a3f311c5b5/obelisk-handoffdeleted
No changes to the content.
migration/1f7fb90cb1e558f5285b2d19a25a1078-5a98cdb6c195e88beac878a3f311c5b5/obelisk-upgradedeleted
No changes to the content.
migration/1fe00204f9d2cd653ff2894eae3d9356-4b3f45ce8aeb17ef18d1d9502b74bb7e/obelisk-handoffdeleted
No changes to the content.
migration/1fe00204f9d2cd653ff2894eae3d9356-4b3f45ce8aeb17ef18d1d9502b74bb7e/obelisk-upgradedeleted
No changes to the content.
migration/20926beb4c30e2efa819d23e5694645e-212ead9571b83b8164b3f18d2537d52b/obelisk-handoffdeleted
No changes to the content.
migration/20926beb4c30e2efa819d23e5694645e-212ead9571b83b8164b3f18d2537d52b/obelisk-upgradedeleted
No changes to the content.
migration/212ead9571b83b8164b3f18d2537d52b-3bf8e28473fb05791c5790f8906e2609/obelisk-handoffdeleted
No changes to the content.
migration/212ead9571b83b8164b3f18d2537d52b-3bf8e28473fb05791c5790f8906e2609/obelisk-upgradedeleted
No changes to the content.
migration/214979923f2d7e6278856493c1978fdc-13f6767460e94079cdfa6d5e1df79ecb/obelisk-handoffdeleted
No changes to the content.
migration/214979923f2d7e6278856493c1978fdc-13f6767460e94079cdfa6d5e1df79ecb/obelisk-upgradedeleted
No changes to the content.
migration/215b6810b09f219a5cb3842aacc88432-2ef4f9cce6d15ae62d5112d3c224eb7a/obelisk-handoffdeleted
No changes to the content.
migration/215b6810b09f219a5cb3842aacc88432-2ef4f9cce6d15ae62d5112d3c224eb7a/obelisk-upgradedeleted
No changes to the content.
migration/2164344be67da5d0e57052c15f30646d-0c9826e42d5d4fa9988c7db53722826e/obelisk-handoffdeleted
No changes to the content.
migration/2164344be67da5d0e57052c15f30646d-0c9826e42d5d4fa9988c7db53722826e/obelisk-upgradedeleted
No changes to the content.
migration/237aeb7eee0ffed230234ee04e49569f-55cf43fb0d3868040c9efbf2f92d538a/obelisk-handoffdeleted
No changes to the content.
migration/237aeb7eee0ffed230234ee04e49569f-55cf43fb0d3868040c9efbf2f92d538a/obelisk-upgradedeleted
No changes to the content.
migration/23af4d9671962484de53f537a0626d83-7ce32302cfbba8b7567a05144057f8a3/obelisk-handoffdeleted
No changes to the content.
migration/23af4d9671962484de53f537a0626d83-7ce32302cfbba8b7567a05144057f8a3/obelisk-upgradedeleted
No changes to the content.
migration/24e0d027f4160a6478c1356e51f419cf-4e3e6e8b9d0f4194842e530438ff686f/obelisk-handoffdeleted
No changes to the content.
migration/24e0d027f4160a6478c1356e51f419cf-4e3e6e8b9d0f4194842e530438ff686f/obelisk-upgradedeleted
No changes to the content.
migration/24f151a674662ac47845237d7a9f6a4f-4fe321cf196b9cd25210c35e09e09d8f/obelisk-handoffdeleted
No changes to the content.
migration/24f151a674662ac47845237d7a9f6a4f-4fe321cf196b9cd25210c35e09e09d8f/obelisk-upgradedeleted
No changes to the content.
migration/2543866165016a449562ea7a1ee36f6f-1a08b154ae5f898992128e229090c4d8/obelisk-handoffdeleted
No changes to the content.
migration/2543866165016a449562ea7a1ee36f6f-1a08b154ae5f898992128e229090c4d8/obelisk-upgradedeleted
No changes to the content.
migration/25615a274650370633e8083ed19fbdd0-80cb6b08443d55bb512e4a35b4768b72/obelisk-handoffdeleted
No changes to the content.
migration/25615a274650370633e8083ed19fbdd0-80cb6b08443d55bb512e4a35b4768b72/obelisk-upgradedeleted
No changes to the content.
migration/2600ab2ec96d3177d2a6b3462e09862d-e2b2d878b0ba6eb653b194523bf0a0e0/obelisk-handoffdeleted
No changes to the content.
migration/2600ab2ec96d3177d2a6b3462e09862d-e2b2d878b0ba6eb653b194523bf0a0e0/obelisk-upgradedeleted
No changes to the content.
migration/2619464637b85cb35376393fe612ddae-a8ebe201ab7a7b0211de41b14a95192e/obelisk-handoffdeleted
No changes to the content.
migration/2619464637b85cb35376393fe612ddae-a8ebe201ab7a7b0211de41b14a95192e/obelisk-upgradedeleted
No changes to the content.
migration/26a2491fc8a9658751c1511c777a67bd-470df6504156dc940b8e7f89c148e619/obelisk-handoffdeleted
No changes to the content.
migration/26a2491fc8a9658751c1511c777a67bd-470df6504156dc940b8e7f89c148e619/obelisk-upgradedeleted
No changes to the content.
migration/270b3b3f7bc510c692e3253a895f122a-c2d4eeb20f2b319a2d9dc5b6b0762f83/obelisk-handoffdeleted
No changes to the content.
migration/270b3b3f7bc510c692e3253a895f122a-c2d4eeb20f2b319a2d9dc5b6b0762f83/obelisk-upgradedeleted
No changes to the content.
migration/2773d4a82ca59b48faf036755e163a5f-71c6959cf98e05d356ff798ada6db2b8/obelisk-handoffdeleted
No changes to the content.
migration/2773d4a82ca59b48faf036755e163a5f-71c6959cf98e05d356ff798ada6db2b8/obelisk-upgradedeleted
No changes to the content.
migration/28a6ada033c86e5ae914cc31cecb6239-90b4e20464e08ade5f215f2a4ea28cc6/obelisk-handoffdeleted
No changes to the content.
migration/28a6ada033c86e5ae914cc31cecb6239-90b4e20464e08ade5f215f2a4ea28cc6/obelisk-upgradedeleted
No changes to the content.
migration/28c5fec3b7b0b14b3625d5c8f60bcf68-4509e2a908da9e497fa67acacdd107b6/obelisk-handoffdeleted
No changes to the content.
migration/28c5fec3b7b0b14b3625d5c8f60bcf68-4509e2a908da9e497fa67acacdd107b6/obelisk-upgradedeleted
No changes to the content.
migration/28e25b7a8812869a709579cd34e7bcb4-2543866165016a449562ea7a1ee36f6f/obelisk-handoffdeleted
No changes to the content.
migration/28e25b7a8812869a709579cd34e7bcb4-2543866165016a449562ea7a1ee36f6f/obelisk-upgradedeleted
No changes to the content.
migration/2913c440c7ad7731aae96e60a86bf7a8-a08aebb6f40fb45d174b229532314ac4/obelisk-handoffdeleted
No changes to the content.
migration/2913c440c7ad7731aae96e60a86bf7a8-a08aebb6f40fb45d174b229532314ac4/obelisk-upgradedeleted
No changes to the content.
migration/29abdd56a2dbbf3a2a0715210d441d06-51c7d001730ddd3d76e0c8bb57038773/obelisk-handoffdeleted
No changes to the content.
migration/29abdd56a2dbbf3a2a0715210d441d06-51c7d001730ddd3d76e0c8bb57038773/obelisk-upgradedeleted
No changes to the content.
migration/29d9b8b8ae9698888f3ea90b10ff5e92-1ada2d50d7847a12dbe29df4097b5bdc/obelisk-handoffdeleted
No changes to the content.
migration/29d9b8b8ae9698888f3ea90b10ff5e92-1ada2d50d7847a12dbe29df4097b5bdc/obelisk-upgradedeleted
No changes to the content.
migration/29fd07af89cc31526fca00226ff52a82-50b85e79010ad50ee275eaeba0df6f8d/obelisk-handoffdeleted
No changes to the content.
migration/29fd07af89cc31526fca00226ff52a82-50b85e79010ad50ee275eaeba0df6f8d/obelisk-upgradedeleted
No changes to the content.
migration/2ba356b187db8db13b8aa40f43ca025f-3c1fc501da00f467c9a48a1ddee2c2b0/obelisk-handoffdeleted
No changes to the content.
migration/2ba356b187db8db13b8aa40f43ca025f-3c1fc501da00f467c9a48a1ddee2c2b0/obelisk-upgradedeleted
No changes to the content.
migration/2bdd4221307cafa3e98c4d3017cdc912-5f6fe243beb9fcc0c4117536022fc14c/obelisk-handoffdeleted
No changes to the content.
migration/2bdd4221307cafa3e98c4d3017cdc912-5f6fe243beb9fcc0c4117536022fc14c/obelisk-upgradedeleted
No changes to the content.
migration/2c1521e5a5be64e6d28a9fdae950cd76-92ab733e8991f12cc12148f8d4e1b35d/obelisk-handoffdeleted
No changes to the content.
migration/2c1521e5a5be64e6d28a9fdae950cd76-92ab733e8991f12cc12148f8d4e1b35d/obelisk-upgradedeleted
No changes to the content.
migration/2ccf977797628dc3b1c002927fedc7a8-46f9c6c66e2bd8980402b6117ca40965/obelisk-handoffdeleted
No changes to the content.
migration/2ccf977797628dc3b1c002927fedc7a8-46f9c6c66e2bd8980402b6117ca40965/obelisk-upgradedeleted
No changes to the content.
migration/2df092178e167b474dd08dfa46ec3a49-9c94cd459a25b5c2de56067c8fdac620/obelisk-handoffdeleted
No changes to the content.
migration/2df092178e167b474dd08dfa46ec3a49-9c94cd459a25b5c2de56067c8fdac620/obelisk-upgradedeleted
No changes to the content.
migration/2e3e85cc59aa31f24f18c027542c0510-47357c6c23f049241902bf2e2e686ac8/obelisk-handoffdeleted
No changes to the content.
migration/2e3e85cc59aa31f24f18c027542c0510-47357c6c23f049241902bf2e2e686ac8/obelisk-upgradedeleted
No changes to the content.
migration/2e7cdc2bea08bb2358219ddefef372e0-a00870cfca85ff8dae5db3a78f5a227d/obelisk-handoffdeleted
No changes to the content.
migration/2e7cdc2bea08bb2358219ddefef372e0-a00870cfca85ff8dae5db3a78f5a227d/obelisk-upgradedeleted
No changes to the content.
migration/2e9a04a228106f62128ea5bd19d6b25e-947784563e3a27cf6486bed9a3c52f15/obelisk-handoffdeleted
No changes to the content.
migration/2e9a04a228106f62128ea5bd19d6b25e-947784563e3a27cf6486bed9a3c52f15/obelisk-upgradedeleted
No changes to the content.
migration/2eb907820012f77e60350430d89631fe-494be5819cd601fd2f0c20e1b23b84a3/obelisk-handoffdeleted
No changes to the content.
migration/2eb907820012f77e60350430d89631fe-494be5819cd601fd2f0c20e1b23b84a3/obelisk-upgradedeleted
No changes to the content.
migration/2ef4f9cce6d15ae62d5112d3c224eb7a-a080b8549e32f21fec11084f4ab1e052/obelisk-handoffdeleted
No changes to the content.
migration/2ef4f9cce6d15ae62d5112d3c224eb7a-a080b8549e32f21fec11084f4ab1e052/obelisk-upgradedeleted
No changes to the content.
migration/2f3ecb5cdb0ab839a49271d91dd7852a-f9ad863c0bebc103f8b81afdf82e6293/obelisk-handoffdeleted
No changes to the content.
migration/2f3ecb5cdb0ab839a49271d91dd7852a-f9ad863c0bebc103f8b81afdf82e6293/obelisk-upgradedeleted
No changes to the content.
migration/2f928f9c4a137186f808a231c9e3c141-9e61f37dd79310b71c80ee166aeb4e80/obelisk-handoffdeleted
No changes to the content.
migration/2f928f9c4a137186f808a231c9e3c141-9e61f37dd79310b71c80ee166aeb4e80/obelisk-upgradedeleted
No changes to the content.
migration/315cd79f97dae2f3669551dc03e0fd27-c801cbcf925c0a7b084ef152e3c08f8e/obelisk-handoffdeleted
No changes to the content.
migration/315cd79f97dae2f3669551dc03e0fd27-c801cbcf925c0a7b084ef152e3c08f8e/obelisk-upgradedeleted
No changes to the content.
migration/31a676fd9e1f69bd07380480ec879da0-9223532a537f698ef36f4dce6e922a6b/obelisk-handoffdeleted
No changes to the content.
migration/31a676fd9e1f69bd07380480ec879da0-9223532a537f698ef36f4dce6e922a6b/obelisk-upgradedeleted
No changes to the content.
migration/338b92f88c49c7c3a1d8ec231d9f7189-a4477746ae1a7024bc3cd0807180d418/obelisk-handoffdeleted
No changes to the content.
migration/338b92f88c49c7c3a1d8ec231d9f7189-a4477746ae1a7024bc3cd0807180d418/obelisk-upgradedeleted
No changes to the content.
migration/33da5c0e6705843afa6e39e65bfa0564-3ec562b7333839d48e9523aec595f3ab/obelisk-handoffdeleted
No changes to the content.
migration/33da5c0e6705843afa6e39e65bfa0564-3ec562b7333839d48e9523aec595f3ab/obelisk-upgradedeleted
No changes to the content.
migration/34d14d4a444d3bf1487ada6129815df4-afbd010add526d309dccee6895e42d0d/obelisk-handoffdeleted
No changes to the content.
migration/34d14d4a444d3bf1487ada6129815df4-afbd010add526d309dccee6895e42d0d/obelisk-upgradedeleted
No changes to the content.
migration/35acc1e0c4d9c02d60abd116f3df84ee-ffa62158ed6fdece012980e4ad25e6ac/obelisk-handoffdeleted
No changes to the content.
migration/35acc1e0c4d9c02d60abd116f3df84ee-ffa62158ed6fdece012980e4ad25e6ac/obelisk-upgradedeleted
No changes to the content.
migration/367616bd36eda757f251a5e8e9096acc-ddaa8e0e42a1ef00154d580a390c9f17/obelisk-handoffdeleted
No changes to the content.
migration/367616bd36eda757f251a5e8e9096acc-ddaa8e0e42a1ef00154d580a390c9f17/obelisk-upgradedeleted
No changes to the content.
migration/36cdb1c744c3036c2932f01d5fadd9f5-e7b566495114e160f1f4d722b7ed8174/obelisk-handoffdeleted
No changes to the content.
migration/36cdb1c744c3036c2932f01d5fadd9f5-e7b566495114e160f1f4d722b7ed8174/obelisk-upgradedeleted
No changes to the content.
migration/375acf7f2a3b3c487da2a6b30735d74d-3b614d291e262d0f281b54ff42a6bb66/obelisk-handoffdeleted
No changes to the content.
migration/375acf7f2a3b3c487da2a6b30735d74d-3b614d291e262d0f281b54ff42a6bb66/obelisk-upgradedeleted
No changes to the content.
migration/37c2ed0ba2cd54c0ec29eae9043bc4c8-190460dabd2b9773c3fe81902d0c8a62/obelisk-handoffdeleted
No changes to the content.
migration/37c2ed0ba2cd54c0ec29eae9043bc4c8-190460dabd2b9773c3fe81902d0c8a62/obelisk-upgradedeleted
No changes to the content.
migration/388d7d29a65c1713e07a654e91eb9caf-b6ffce85249f30616da76334c7bbec6e/obelisk-handoffdeleted
No changes to the content.
migration/388d7d29a65c1713e07a654e91eb9caf-b6ffce85249f30616da76334c7bbec6e/obelisk-upgradedeleted
No changes to the content.
migration/39df6544d6b035d4c77cc829729f9c19-9f6c8fd80ab3ff2dcc48bfd211c8b761/obelisk-handoffdeleted
No changes to the content.
migration/39df6544d6b035d4c77cc829729f9c19-9f6c8fd80ab3ff2dcc48bfd211c8b761/obelisk-upgradedeleted
No changes to the content.
migration/3a207630aa67e5df48d2b87d34db616b-8adb921f4dbb9d363bf6647d304e02fe/obelisk-handoffdeleted
No changes to the content.
migration/3a207630aa67e5df48d2b87d34db616b-8adb921f4dbb9d363bf6647d304e02fe/obelisk-upgradedeleted
No changes to the content.
migration/3b614d291e262d0f281b54ff42a6bb66-2e9a04a228106f62128ea5bd19d6b25e/obelisk-handoffdeleted
No changes to the content.
migration/3b614d291e262d0f281b54ff42a6bb66-2e9a04a228106f62128ea5bd19d6b25e/obelisk-upgradedeleted
No changes to the content.
migration/3bc53f3a28cb8f403cc41c11a37eec5d-cd86427cc2d5b2e931d7ab03deb19d20/obelisk-handoffdeleted
No changes to the content.
migration/3bc53f3a28cb8f403cc41c11a37eec5d-cd86427cc2d5b2e931d7ab03deb19d20/obelisk-upgradedeleted
No changes to the content.
migration/3bf8e28473fb05791c5790f8906e2609-45185a6f053557f93a13cb8cd03963a7/obelisk-handoffdeleted
No changes to the content.
migration/3bf8e28473fb05791c5790f8906e2609-45185a6f053557f93a13cb8cd03963a7/obelisk-upgradedeleted
No changes to the content.
migration/3c1fc501da00f467c9a48a1ddee2c2b0-cd5b54d21dd0fb868f48624d41021f47/obelisk-handoffdeleted
No changes to the content.
migration/3c1fc501da00f467c9a48a1ddee2c2b0-cd5b54d21dd0fb868f48624d41021f47/obelisk-upgradedeleted
No changes to the content.
migration/3c4b3152f0608d23d07240e2df3ff8da-c6baede3962454713b73acefcc92fe75/obelisk-handoffdeleted
No changes to the content.
migration/3c4b3152f0608d23d07240e2df3ff8da-c6baede3962454713b73acefcc92fe75/obelisk-upgradedeleted
No changes to the content.
migration/3c7755e495f20cfac5e4dabe78644c5a-51e25cf740f064faa0a29b8e2afcc109/obelisk-handoffdeleted
No changes to the content.
migration/3c7755e495f20cfac5e4dabe78644c5a-51e25cf740f064faa0a29b8e2afcc109/obelisk-upgradedeleted
No changes to the content.
migration/3c80eccfe80d0abd36b07bb11e69fc7a-b4f6596f2c16811442d8bb2961fbb721/obelisk-handoffdeleted
No changes to the content.
migration/3c80eccfe80d0abd36b07bb11e69fc7a-b4f6596f2c16811442d8bb2961fbb721/obelisk-upgradedeleted
No changes to the content.
migration/3cb52c2838303a362e9efb7c7eea37bd-aeafaa5d20bab4439a5d31f29023a839/obelisk-handoffdeleted
No changes to the content.
migration/3cb52c2838303a362e9efb7c7eea37bd-aeafaa5d20bab4439a5d31f29023a839/obelisk-upgradedeleted
No changes to the content.
migration/3da702ef7f531ad6db874ac3f85e9c06-73bcf3ed6593d074bd097cd43f5145d1/obelisk-handoffdeleted
No changes to the content.
migration/3da702ef7f531ad6db874ac3f85e9c06-73bcf3ed6593d074bd097cd43f5145d1/obelisk-upgradedeleted
No changes to the content.
migration/3da7d4a3b507d18097a90becf4dde9aa-e1ef432db54d9a6daa9bdeeb543262ae/obelisk-handoffdeleted
No changes to the content.
migration/3da7d4a3b507d18097a90becf4dde9aa-e1ef432db54d9a6daa9bdeeb543262ae/obelisk-upgradedeleted
No changes to the content.
migration/3daecb03985f83d8af466a9e0541782b-a2665cfd303a4a34a7bfa3b7d0d264bb/obelisk-handoffdeleted
No changes to the content.
migration/3daecb03985f83d8af466a9e0541782b-a2665cfd303a4a34a7bfa3b7d0d264bb/obelisk-upgradedeleted
No changes to the content.
migration/3e253c6beb567ba8f4c8086a76b70645-d6cacd7f4fab95c4b6aa2d6c1a4ad2a0/obelisk-handoffdeleted
No changes to the content.
migration/3e253c6beb567ba8f4c8086a76b70645-d6cacd7f4fab95c4b6aa2d6c1a4ad2a0/obelisk-upgradedeleted
No changes to the content.
migration/3e763ebe16cc3a261f5776ab1f1f6d9a-583ec22b9af66e8f629ee404307eb2dc/obelisk-handoffdeleted
No changes to the content.
migration/3e763ebe16cc3a261f5776ab1f1f6d9a-583ec22b9af66e8f629ee404307eb2dc/obelisk-upgradedeleted
No changes to the content.
migration/3e8a6968585d3d60f3b13652a386aec0-c118e1ee09ec8d9aa3edf04e211ae035/obelisk-handoffdeleted
No changes to the content.
migration/3e8a6968585d3d60f3b13652a386aec0-c118e1ee09ec8d9aa3edf04e211ae035/obelisk-upgradedeleted
No changes to the content.
migration/3ec562b7333839d48e9523aec595f3ab-7b9c28d09bd962e89b9715500f9e184c/obelisk-handoffdeleted
No changes to the content.
migration/3ec562b7333839d48e9523aec595f3ab-7b9c28d09bd962e89b9715500f9e184c/obelisk-upgradedeleted
No changes to the content.
migration/3f0687592a77c0c66193652e9cd981fd-fb81153791e49cd00850e91ff7418018/obelisk-handoffdeleted
No changes to the content.
migration/3f0687592a77c0c66193652e9cd981fd-fb81153791e49cd00850e91ff7418018/obelisk-upgradedeleted
No changes to the content.
migration/3f23549fba6f8e67ba36b4405e8680b3-a6633fc9687566aa84c3d5d5e2bff4fd/obelisk-handoffdeleted
No changes to the content.
migration/3f23549fba6f8e67ba36b4405e8680b3-a6633fc9687566aa84c3d5d5e2bff4fd/obelisk-upgradedeleted
No changes to the content.
migration/41e3ba178b727517aa1cedc8815abe86-1d084e187591225f0e8fa6fa824f8863/obelisk-handoffdeleted
No changes to the content.
migration/41e3ba178b727517aa1cedc8815abe86-1d084e187591225f0e8fa6fa824f8863/obelisk-upgradedeleted
No changes to the content.
migration/4205857df2e234a476ad56f84a33e6ed-db327f87e60d4e59bdbfd482e5abe985/obelisk-handoffdeleted
No changes to the content.
migration/4205857df2e234a476ad56f84a33e6ed-db327f87e60d4e59bdbfd482e5abe985/obelisk-upgradedeleted
No changes to the content.
migration/423088b98df50b986c9197af83c42a25-3a207630aa67e5df48d2b87d34db616b/obelisk-handoffdeleted
No changes to the content.
migration/423088b98df50b986c9197af83c42a25-3a207630aa67e5df48d2b87d34db616b/obelisk-upgradedeleted
No changes to the content.
migration/42357310c09e345f9360259c6c4102f2-ae8862f8b7292690c852111ca5659ce9/obelisk-handoffdeleted
No changes to the content.
migration/42357310c09e345f9360259c6c4102f2-ae8862f8b7292690c852111ca5659ce9/obelisk-upgradedeleted
No changes to the content.
migration/4344c1bd0ef04ebc055d5252f58b0bef-2f3ecb5cdb0ab839a49271d91dd7852a/obelisk-handoffdeleted
No changes to the content.
migration/4344c1bd0ef04ebc055d5252f58b0bef-2f3ecb5cdb0ab839a49271d91dd7852a/obelisk-upgradedeleted
No changes to the content.
migration/4509e2a908da9e497fa67acacdd107b6-1fe00204f9d2cd653ff2894eae3d9356/obelisk-handoffdeleted
No changes to the content.
migration/4509e2a908da9e497fa67acacdd107b6-1fe00204f9d2cd653ff2894eae3d9356/obelisk-upgradedeleted
No changes to the content.
migration/45185a6f053557f93a13cb8cd03963a7-cffcc6cab6080a35b7bf7c5c7facd6bc/obelisk-handoffdeleted
No changes to the content.
migration/45185a6f053557f93a13cb8cd03963a7-cffcc6cab6080a35b7bf7c5c7facd6bc/obelisk-upgradedeleted
No changes to the content.
migration/455279b6974b96a673613cd0ccc8ed54-b3ff195b0a90ef5900f9cef2ba75f2fe/obelisk-handoffdeleted
No changes to the content.
migration/455279b6974b96a673613cd0ccc8ed54-b3ff195b0a90ef5900f9cef2ba75f2fe/obelisk-upgradedeleted
No changes to the content.
migration/463646ba21b356f612539ea34178adf9-b3b107d406a6a7675cd5b9f52e5f7d8e/obelisk-handoffdeleted
No changes to the content.
migration/463646ba21b356f612539ea34178adf9-b3b107d406a6a7675cd5b9f52e5f7d8e/obelisk-upgradedeleted
No changes to the content.
migration/466a19f9cfa2a103467fe6627225d27f-c67f206b6d2626eb6d36b00122b52784/obelisk-handoffdeleted
No changes to the content.
migration/466a19f9cfa2a103467fe6627225d27f-c67f206b6d2626eb6d36b00122b52784/obelisk-upgradedeleted
No changes to the content.
migration/469a31d20d69da72e6a3a3ea2bb02f9d-75c9cd9763d0ed89c17d455f49d66a4f/obelisk-handoffdeleted
No changes to the content.
migration/469a31d20d69da72e6a3a3ea2bb02f9d-75c9cd9763d0ed89c17d455f49d66a4f/obelisk-upgradedeleted
No changes to the content.
migration/46aed07c1a61476dd245ff8e74c0559f-73e2573d9074884d7ae83106d55ad229/obelisk-handoffdeleted
No changes to the content.
migration/46aed07c1a61476dd245ff8e74c0559f-73e2573d9074884d7ae83106d55ad229/obelisk-upgradedeleted
No changes to the content.
migration/46f9c6c66e2bd8980402b6117ca40965-463646ba21b356f612539ea34178adf9/obelisk-handoffdeleted
No changes to the content.
migration/46f9c6c66e2bd8980402b6117ca40965-463646ba21b356f612539ea34178adf9/obelisk-upgradedeleted
No changes to the content.
migration/470df6504156dc940b8e7f89c148e619-a5297d8457aa4c327f35d4697f6cb66f/obelisk-handoffdeleted
No changes to the content.
migration/470df6504156dc940b8e7f89c148e619-a5297d8457aa4c327f35d4697f6cb66f/obelisk-upgradedeleted
No changes to the content.
migration/47357c6c23f049241902bf2e2e686ac8-d62d6d443d9c2261b7e09664398aa005/obelisk-handoffdeleted
No changes to the content.
migration/47357c6c23f049241902bf2e2e686ac8-d62d6d443d9c2261b7e09664398aa005/obelisk-upgradedeleted
No changes to the content.
migration/475f9a0d63e84e9cf13b8be3986cb603-b95c8d049256fb7360ca14b12acd8544/obelisk-handoffdeleted
No changes to the content.
migration/475f9a0d63e84e9cf13b8be3986cb603-b95c8d049256fb7360ca14b12acd8544/obelisk-upgradedeleted
No changes to the content.
migration/477a0bb12b48357d1e2b415c91d904e3-486d5218951605d14ec4a1046d3fe83e/obelisk-handoffdeleted
No changes to the content.
migration/477a0bb12b48357d1e2b415c91d904e3-486d5218951605d14ec4a1046d3fe83e/obelisk-upgradedeleted
No changes to the content.
migration/486d5218951605d14ec4a1046d3fe83e-90489c1a9f7edd46a070d6474dceac86/obelisk-handoffdeleted
No changes to the content.
migration/486d5218951605d14ec4a1046d3fe83e-90489c1a9f7edd46a070d6474dceac86/obelisk-upgradedeleted
No changes to the content.
migration/48c027da19d895ba03e7b9120f771291-29fd07af89cc31526fca00226ff52a82/obelisk-handoffdeleted
No changes to the content.
migration/48c027da19d895ba03e7b9120f771291-29fd07af89cc31526fca00226ff52a82/obelisk-upgradedeleted
No changes to the content.
migration/494be5819cd601fd2f0c20e1b23b84a3-c66bc5ba27dec52d144ceb0aa429e449/obelisk-handoffdeleted
No changes to the content.
migration/494be5819cd601fd2f0c20e1b23b84a3-c66bc5ba27dec52d144ceb0aa429e449/obelisk-upgradedeleted
No changes to the content.
migration/4a037879b8a542f1590cbb87b0242331-4344c1bd0ef04ebc055d5252f58b0bef/obelisk-handoffdeleted
No changes to the content.
migration/4a037879b8a542f1590cbb87b0242331-4344c1bd0ef04ebc055d5252f58b0bef/obelisk-upgradedeleted
No changes to the content.
migration/4ab915b764f38a1b0b4ae6f619f5c3fa-59e4a192c611a2a9f6736afde9fe1a0e/obelisk-handoffdeleted
No changes to the content.
migration/4ab915b764f38a1b0b4ae6f619f5c3fa-59e4a192c611a2a9f6736afde9fe1a0e/obelisk-upgradedeleted
No changes to the content.
migration/4ace4414d71235a291f7148f80a0b0f5-9705509619667aacf799e91927c16dc8/obelisk-handoffdeleted
No changes to the content.
migration/4ace4414d71235a291f7148f80a0b0f5-9705509619667aacf799e91927c16dc8/obelisk-upgradedeleted
No changes to the content.
migration/4aefa80392582ec03a19f946e752d331-cb98f93880e6dea74014976977d6eb93/obelisk-handoffdeleted
No changes to the content.
migration/4aefa80392582ec03a19f946e752d331-cb98f93880e6dea74014976977d6eb93/obelisk-upgradedeleted
No changes to the content.
migration/4b3f45ce8aeb17ef18d1d9502b74bb7e-4efbe4a73c260cca09fed7169e82a7ff/obelisk-handoffdeleted
No changes to the content.
migration/4b3f45ce8aeb17ef18d1d9502b74bb7e-4efbe4a73c260cca09fed7169e82a7ff/obelisk-upgradedeleted
No changes to the content.
migration/4b7a36dce2c1cf94554e12d8a7903269-dd6ca52a58ea6cda7b3eaa2e87bb13d9/obelisk-handoffdeleted
No changes to the content.
migration/4b7a36dce2c1cf94554e12d8a7903269-dd6ca52a58ea6cda7b3eaa2e87bb13d9/obelisk-upgradedeleted
No changes to the content.
migration/4c9372bf9aa6ebed1ea20abf3dbb0075-b641dd9c5359201200e483a784456cc2/obelisk-handoffdeleted
No changes to the content.
migration/4c9372bf9aa6ebed1ea20abf3dbb0075-b641dd9c5359201200e483a784456cc2/obelisk-upgradedeleted
No changes to the content.
migration/4d6197d8166de78f882376102e36300b-4205857df2e234a476ad56f84a33e6ed/obelisk-handoffdeleted
No changes to the content.
migration/4d6197d8166de78f882376102e36300b-4205857df2e234a476ad56f84a33e6ed/obelisk-upgradedeleted
No changes to the content.
migration/4d85ee8cdb0db20a5662b09567a2bbe7-b6425c7661af2116b912a558e9548013/obelisk-handoffdeleted
No changes to the content.
migration/4d85ee8cdb0db20a5662b09567a2bbe7-b6425c7661af2116b912a558e9548013/obelisk-upgradedeleted
No changes to the content.
migration/4da182e21be35feeee484dc85be7a075-14840816db4b5cfd5580ae099022604a/obelisk-handoffdeleted
No changes to the content.
migration/4da182e21be35feeee484dc85be7a075-14840816db4b5cfd5580ae099022604a/obelisk-upgradedeleted
No changes to the content.
migration/4db97ca86399c557e5ee0d04d0838acc-c203adc5fed9bf79f67df43d72a4631a/obelisk-handoffdeleted
No changes to the content.
migration/4db97ca86399c557e5ee0d04d0838acc-c203adc5fed9bf79f67df43d72a4631a/obelisk-upgradedeleted
No changes to the content.
migration/4e3e6e8b9d0f4194842e530438ff686f-b7e30314f9d0e69efdc84c7eb4e3bcc3/obelisk-handoffdeleted
No changes to the content.
migration/4e3e6e8b9d0f4194842e530438ff686f-b7e30314f9d0e69efdc84c7eb4e3bcc3/obelisk-upgradedeleted
No changes to the content.
migration/4e95e2f8ef50420371b71022c644e25d-8df9e256d8e43fa4e22d953024269b5b/obelisk-handoffdeleted
No changes to the content.
migration/4e95e2f8ef50420371b71022c644e25d-8df9e256d8e43fa4e22d953024269b5b/obelisk-upgradedeleted
No changes to the content.
migration/4efbe4a73c260cca09fed7169e82a7ff-315cd79f97dae2f3669551dc03e0fd27/obelisk-handoffdeleted
No changes to the content.
migration/4efbe4a73c260cca09fed7169e82a7ff-315cd79f97dae2f3669551dc03e0fd27/obelisk-upgradedeleted
No changes to the content.
migration/4fe321cf196b9cd25210c35e09e09d8f-56d7fd24c8a996e49bb26dd797819897/obelisk-handoffdeleted
No changes to the content.
migration/4fe321cf196b9cd25210c35e09e09d8f-56d7fd24c8a996e49bb26dd797819897/obelisk-upgradedeleted
No changes to the content.
migration/4ff5bf819ea43a638abbcfa071bbf3ef-975cd8245d06ad09e4fb176cfc9af5e0/obelisk-handoffdeleted
No changes to the content.
migration/4ff5bf819ea43a638abbcfa071bbf3ef-975cd8245d06ad09e4fb176cfc9af5e0/obelisk-upgradedeleted
No changes to the content.
migration/50b85e79010ad50ee275eaeba0df6f8d-e327773e1525eaa1eb2112dff8f41b26/obelisk-handoffdeleted
No changes to the content.
migration/50b85e79010ad50ee275eaeba0df6f8d-e327773e1525eaa1eb2112dff8f41b26/obelisk-upgradedeleted
No changes to the content.
migration/51c7d001730ddd3d76e0c8bb57038773-423088b98df50b986c9197af83c42a25/obelisk-handoffdeleted
No changes to the content.
migration/51c7d001730ddd3d76e0c8bb57038773-423088b98df50b986c9197af83c42a25/obelisk-upgradedeleted
No changes to the content.
migration/51e25cf740f064faa0a29b8e2afcc109-7bc4c944b24621967a6334f522437cc1/obelisk-handoffdeleted
No changes to the content.
migration/51e25cf740f064faa0a29b8e2afcc109-7bc4c944b24621967a6334f522437cc1/obelisk-upgradedeleted
No changes to the content.
migration/51f3d5068259f596b811450f0bf25419-f9716ad47c84e0b7ac7d426e8ad059f3/obelisk-handoffdeleted
No changes to the content.
migration/51f3d5068259f596b811450f0bf25419-f9716ad47c84e0b7ac7d426e8ad059f3/obelisk-upgradedeleted
No changes to the content.
migration/52330622ae996023b3f80a40991521a4-1df871cede0758cabe43971d9091279d/obelisk-handoffdeleted
No changes to the content.
migration/52330622ae996023b3f80a40991521a4-1df871cede0758cabe43971d9091279d/obelisk-upgradedeleted
No changes to the content.
migration/52df183d0f32d5a1e9ebe276b6d83d37-08dbdf23867a8efa680283ad251d3429/obelisk-handoffdeleted
No changes to the content.
migration/52df183d0f32d5a1e9ebe276b6d83d37-08dbdf23867a8efa680283ad251d3429/obelisk-upgradedeleted
No changes to the content.
migration/53d29061537ddaf7530aef88624ab266-9fe2922674fcee5e840c9f52cf534f88/obelisk-handoffdeleted
No changes to the content.
migration/53d29061537ddaf7530aef88624ab266-9fe2922674fcee5e840c9f52cf534f88/obelisk-upgradedeleted
No changes to the content.
migration/53fdf819333b86dfb485bf16a8f28db2-93fc625d41bae9fcf06b9febeacb686d/obelisk-handoffdeleted
No changes to the content.
migration/53fdf819333b86dfb485bf16a8f28db2-93fc625d41bae9fcf06b9febeacb686d/obelisk-upgradedeleted
No changes to the content.
migration/554c459ff2cced3e1b11241ed403890d-3543ea607791bc2e19419d22918823bd/obelisk-handoffdeleted
No changes to the content.
migration/554c459ff2cced3e1b11241ed403890d-3543ea607791bc2e19419d22918823bd/obelisk-upgradedeleted
No changes to the content.
migration/554c459ff2cced3e1b11241ed403890d-6a18939264224d6ce24c7426249edfea/obelisk-handoffdeleted
No changes to the content.
migration/554c459ff2cced3e1b11241ed403890d-6a18939264224d6ce24c7426249edfea/obelisk-upgradedeleted
No changes to the content.
migration/55cf43fb0d3868040c9efbf2f92d538a-e2706f337218a12a3bdddd18fa3f4cfd/obelisk-handoffdeleted
No changes to the content.
migration/55cf43fb0d3868040c9efbf2f92d538a-e2706f337218a12a3bdddd18fa3f4cfd/obelisk-upgradedeleted
No changes to the content.
migration/55d9c5eb3b86c9cb27966f849b2d32cf-0e4d0f0f0af0925474b0d772be2b145f/obelisk-handoffdeleted
No changes to the content.
migration/55d9c5eb3b86c9cb27966f849b2d32cf-0e4d0f0f0af0925474b0d772be2b145f/obelisk-upgradedeleted
No changes to the content.
migration/5631293b75143d170b8fca5579e15fee-0abd9d31c77be8c9a9e83bf1f73276f6/obelisk-handoffdeleted
No changes to the content.
migration/5631293b75143d170b8fca5579e15fee-0abd9d31c77be8c9a9e83bf1f73276f6/obelisk-upgradedeleted
No changes to the content.
migration/569227e5e7754c1890022850fd552292-ff1105290f89350bc9deb6eb907e0a53/obelisk-handoffdeleted
No changes to the content.
migration/569227e5e7754c1890022850fd552292-ff1105290f89350bc9deb6eb907e0a53/obelisk-upgradedeleted
No changes to the content.
migration/56d7fd24c8a996e49bb26dd797819897-61f734d4c59e46f03e92d2b86299c7c9/obelisk-handoffdeleted
No changes to the content.
migration/56d7fd24c8a996e49bb26dd797819897-61f734d4c59e46f03e92d2b86299c7c9/obelisk-upgradedeleted
No changes to the content.
migration/5734398c41e4eb5bb58d933ed2e12041-fb374b0721716a1e849e64daf6da73c4/obelisk-handoffdeleted
No changes to the content.
migration/5734398c41e4eb5bb58d933ed2e12041-fb374b0721716a1e849e64daf6da73c4/obelisk-upgradedeleted
No changes to the content.
migration/58391ba73c13d922e8a12116b28caad2-215b6810b09f219a5cb3842aacc88432/obelisk-handoffdeleted
No changes to the content.
migration/58391ba73c13d922e8a12116b28caad2-215b6810b09f219a5cb3842aacc88432/obelisk-upgradedeleted
No changes to the content.
migration/583ec22b9af66e8f629ee404307eb2dc-6c7f4af3693c31e1a2c6a2c3f189ddf5/obelisk-handoffdeleted
No changes to the content.
migration/583ec22b9af66e8f629ee404307eb2dc-6c7f4af3693c31e1a2c6a2c3f189ddf5/obelisk-upgradedeleted
No changes to the content.
migration/58479e482d3828ce44f2c8371ed9135a-174fa1072ee767be39b7b01aecea5714/obelisk-handoffdeleted
No changes to the content.
migration/58479e482d3828ce44f2c8371ed9135a-174fa1072ee767be39b7b01aecea5714/obelisk-upgradedeleted
No changes to the content.
migration/589eb89cdb09655c5edde4cd2a4deb80-c5a306045ad998f906f80748fe18487f/obelisk-handoffdeleted
No changes to the content.
migration/589eb89cdb09655c5edde4cd2a4deb80-c5a306045ad998f906f80748fe18487f/obelisk-upgradedeleted
No changes to the content.
migration/58f9d23d2cede2081dc6f6cfa2283f60-41e3ba178b727517aa1cedc8815abe86/obelisk-handoffdeleted
No changes to the content.
migration/58f9d23d2cede2081dc6f6cfa2283f60-41e3ba178b727517aa1cedc8815abe86/obelisk-upgradedeleted
No changes to the content.
migration/59742705e53838ae13066a2239a72040-95955d1dd0981ebb538ee941cde1f963/obelisk-handoffdeleted
No changes to the content.
migration/59742705e53838ae13066a2239a72040-95955d1dd0981ebb538ee941cde1f963/obelisk-upgradedeleted
No changes to the content.
migration/59e4a192c611a2a9f6736afde9fe1a0e-8143888349912db9780231c370ea2060/obelisk-handoffdeleted
No changes to the content.
migration/59e4a192c611a2a9f6736afde9fe1a0e-8143888349912db9780231c370ea2060/obelisk-upgradedeleted
No changes to the content.
migration/5a98cdb6c195e88beac878a3f311c5b5-66d79b4c393877a72aec18f227049207/obelisk-handoffdeleted
No changes to the content.
migration/5a98cdb6c195e88beac878a3f311c5b5-66d79b4c393877a72aec18f227049207/obelisk-upgradedeleted
No changes to the content.
migration/5b252c24612c2ba868580add9d9c19e3-6f104c322bbaff565981739406290402/obelisk-handoffdeleted
No changes to the content.
migration/5b252c24612c2ba868580add9d9c19e3-6f104c322bbaff565981739406290402/obelisk-upgradedeleted
No changes to the content.
migration/5b6770965bbef440db49b0703cd243a3-11f38b38c2d38004bb8a9dbfe2ef3e4a/obelisk-handoffdeleted
No changes to the content.
migration/5b6770965bbef440db49b0703cd243a3-11f38b38c2d38004bb8a9dbfe2ef3e4a/obelisk-upgradedeleted
No changes to the content.
migration/5cb98d0250bf5224b94e544a5140a54c-fa18f7522903a21b615dbee24c26bfbe/obelisk-handoffdeleted
No changes to the content.
migration/5cb98d0250bf5224b94e544a5140a54c-fa18f7522903a21b615dbee24c26bfbe/obelisk-upgradedeleted
No changes to the content.
migration/5d90abd974b4ec53091a8cb3fc2258ce-d40e0e3051a76c4c198cc11c2e8e4b7c/obelisk-handoffdeleted
No changes to the content.
migration/5d90abd974b4ec53091a8cb3fc2258ce-d40e0e3051a76c4c198cc11c2e8e4b7c/obelisk-upgradedeleted
No changes to the content.
migration/5f0d3f7480d67df7deebdb880726b356-4ab915b764f38a1b0b4ae6f619f5c3fa/obelisk-handoffdeleted
No changes to the content.
migration/5f0d3f7480d67df7deebdb880726b356-4ab915b764f38a1b0b4ae6f619f5c3fa/obelisk-upgradedeleted
No changes to the content.
migration/5f307639ccf6a64309166bfe58037397-702c65f35bc47641d60580d636ede330/obelisk-handoffdeleted
No changes to the content.
migration/5f307639ccf6a64309166bfe58037397-702c65f35bc47641d60580d636ede330/obelisk-upgradedeleted
No changes to the content.
migration/5f6fe243beb9fcc0c4117536022fc14c-f41b690c74938e347cf042cee2d4fc72/obelisk-handoffdeleted
No changes to the content.
migration/5f6fe243beb9fcc0c4117536022fc14c-f41b690c74938e347cf042cee2d4fc72/obelisk-upgradedeleted
No changes to the content.
migration/6095bdaccd933d319c84cde7983e2d10-477a0bb12b48357d1e2b415c91d904e3/obelisk-handoffdeleted
No changes to the content.
migration/6095bdaccd933d319c84cde7983e2d10-477a0bb12b48357d1e2b415c91d904e3/obelisk-upgradedeleted
No changes to the content.
migration/610dcf99f7eb8c8b591ff3f5f1722938-131e1d5cc8163ce9a174a8782be23fe7/obelisk-handoffdeleted
No changes to the content.
migration/610dcf99f7eb8c8b591ff3f5f1722938-131e1d5cc8163ce9a174a8782be23fe7/obelisk-upgradedeleted
No changes to the content.
migration/61f734d4c59e46f03e92d2b86299c7c9-02d0f8b5c7472e6f8a99ec2cfcb59807/obelisk-handoffdeleted
No changes to the content.
migration/61f734d4c59e46f03e92d2b86299c7c9-02d0f8b5c7472e6f8a99ec2cfcb59807/obelisk-upgradedeleted
No changes to the content.
migration/63422a9bade5c703461b600e03e227f0-01ddc6354698efa1ae5822da3be562dc/obelisk-handoffdeleted
No changes to the content.
migration/63422a9bade5c703461b600e03e227f0-01ddc6354698efa1ae5822da3be562dc/obelisk-upgradedeleted
No changes to the content.
migration/63ff9426130baa080f37400a86c55fdd-569227e5e7754c1890022850fd552292/obelisk-handoffdeleted
No changes to the content.
migration/63ff9426130baa080f37400a86c55fdd-569227e5e7754c1890022850fd552292/obelisk-upgradedeleted
No changes to the content.
migration/64ee9e40f4943e0122398e48019f5616-cd38e239c47fb92fabd867b7f86fc99a/obelisk-handoffdeleted
No changes to the content.
migration/64ee9e40f4943e0122398e48019f5616-cd38e239c47fb92fabd867b7f86fc99a/obelisk-upgradedeleted
No changes to the content.
migration/65071e255719af6389857646bc087d37-02fb88dab35884e09deef1721c1cfc13/obelisk-handoffdeleted
No changes to the content.
migration/65071e255719af6389857646bc087d37-02fb88dab35884e09deef1721c1cfc13/obelisk-upgradedeleted
No changes to the content.
migration/6558f8bda2aa17d76c509dde0a3dea56-2ccf977797628dc3b1c002927fedc7a8/obelisk-handoffdeleted
No changes to the content.
migration/6558f8bda2aa17d76c509dde0a3dea56-2ccf977797628dc3b1c002927fedc7a8/obelisk-upgradedeleted
No changes to the content.
migration/6566f0555737425bae9106d1a4a0a2dd-1f7fb90cb1e558f5285b2d19a25a1078/obelisk-handoffdeleted
No changes to the content.
migration/6566f0555737425bae9106d1a4a0a2dd-1f7fb90cb1e558f5285b2d19a25a1078/obelisk-upgradedeleted
No changes to the content.
migration/6620e6dc5622593e5f671127af9ade05-4ff5bf819ea43a638abbcfa071bbf3ef/obelisk-handoffdeleted
No changes to the content.
migration/6620e6dc5622593e5f671127af9ade05-4ff5bf819ea43a638abbcfa071bbf3ef/obelisk-upgradedeleted
No changes to the content.
migration/662eb30d6e4612f130edc3f6d37d92a2-94dd4eb45a4e7eb945027d5fd8eb4fa6/obelisk-handoffdeleted
No changes to the content.
migration/662eb30d6e4612f130edc3f6d37d92a2-94dd4eb45a4e7eb945027d5fd8eb4fa6/obelisk-upgradedeleted
No changes to the content.
migration/66a9b6b9e9bc4a5b0cfa78127479b231-88765caf54c2bf9f23ea4d05816a9f65/obelisk-handoffdeleted
No changes to the content.
migration/66a9b6b9e9bc4a5b0cfa78127479b231-88765caf54c2bf9f23ea4d05816a9f65/obelisk-upgradedeleted
No changes to the content.
migration/66d79b4c393877a72aec18f227049207-04dd95ecb889ac1b0a616ddfeec781c4/obelisk-handoffdeleted
No changes to the content.
migration/66d79b4c393877a72aec18f227049207-04dd95ecb889ac1b0a616ddfeec781c4/obelisk-upgradedeleted
No changes to the content.
migration/66f7a274206ad9f6d3c5701e4bcffc9d-2e7cdc2bea08bb2358219ddefef372e0/obelisk-handoffdeleted
No changes to the content.
migration/66f7a274206ad9f6d3c5701e4bcffc9d-2e7cdc2bea08bb2358219ddefef372e0/obelisk-upgradedeleted
No changes to the content.
migration/6708d14c71c475ac494808e75660a385-6095bdaccd933d319c84cde7983e2d10/obelisk-handoffdeleted
No changes to the content.
migration/6708d14c71c475ac494808e75660a385-6095bdaccd933d319c84cde7983e2d10/obelisk-upgradedeleted
No changes to the content.
migration/67173f110f2c54d135e6943b65118303-17089ea0edc0cf4b6f616936f8a06174/obelisk-handoffdeleted
No changes to the content.
migration/67173f110f2c54d135e6943b65118303-17089ea0edc0cf4b6f616936f8a06174/obelisk-upgradedeleted
No changes to the content.
migration/67bfa5b784a35e66875fb74ad84a38c0-f3ec62d09836804e39fad9d814137845/obelisk-handoffdeleted
No changes to the content.
migration/67bfa5b784a35e66875fb74ad84a38c0-f3ec62d09836804e39fad9d814137845/obelisk-upgradedeleted
No changes to the content.
migration/68cca18f813a16eb0cc2c3ed7fa08044-ee3dccc89ea6fdaaf9c1146b92861e90/obelisk-handoffdeleted
No changes to the content.
migration/68cca18f813a16eb0cc2c3ed7fa08044-ee3dccc89ea6fdaaf9c1146b92861e90/obelisk-upgradedeleted
No changes to the content.
migration/69537089a0e97845ffe05c73c3cc1536-e92786eaf56c32fd6b452c4a841d6317/obelisk-handoffdeleted
No changes to the content.
migration/69537089a0e97845ffe05c73c3cc1536-e92786eaf56c32fd6b452c4a841d6317/obelisk-upgradedeleted
No changes to the content.
migration/69cd775958e25e3b2cff7e4897f2a9bb-fca48edfdaa31b036176b97b04384682/obelisk-handoffdeleted
No changes to the content.
migration/69cd775958e25e3b2cff7e4897f2a9bb-fca48edfdaa31b036176b97b04384682/obelisk-upgradedeleted
No changes to the content.
migration/69fafe6ab155ff215b6d9d330f700ba1-6558f8bda2aa17d76c509dde0a3dea56/obelisk-handoffdeleted
No changes to the content.
migration/69fafe6ab155ff215b6d9d330f700ba1-6558f8bda2aa17d76c509dde0a3dea56/obelisk-upgradedeleted
No changes to the content.
migration/6a18939264224d6ce24c7426249edfea-e66afc8befac4d76b5780a960f768c31/obelisk-handoffdeleted
No changes to the content.
migration/6a18939264224d6ce24c7426249edfea-e66afc8befac4d76b5780a960f768c31/obelisk-upgradedeleted−15
@@ -1,15 +0,0 @@
1−# ob deploy: HTTPs support
3−Obelisk deployments now support HTTPs. You must upgrade the deployment repo
4−associated with the obelisk project as follows:
7−cd /your/project's/deployment/repo
8−echo True > enable_https
9−echo admin@yoursite.com > admin_email
10−echo https://yoursite.com/ > config/common/route
11−git add ... && git commit ...
15−If you do not wish to enable HTTPs, write `False` to `enable_https` instead.
migration/6c7f4af3693c31e1a2c6a2c3f189ddf5-388d7d29a65c1713e07a654e91eb9caf/obelisk-handoffdeleted
No changes to the content.
migration/6c7f4af3693c31e1a2c6a2c3f189ddf5-388d7d29a65c1713e07a654e91eb9caf/obelisk-upgradedeleted
No changes to the content.
migration/6da2e5b02ab780d12527640722d2b511-ca88f98cf9fb63d2feaef7fc19b30eca/obelisk-handoffdeleted
No changes to the content.
migration/6da2e5b02ab780d12527640722d2b511-ca88f98cf9fb63d2feaef7fc19b30eca/obelisk-upgradedeleted
No changes to the content.
migration/6dc299cb41f8977785a5d676cbcd32d7-237aeb7eee0ffed230234ee04e49569f/obelisk-handoffdeleted
No changes to the content.
migration/6dc299cb41f8977785a5d676cbcd32d7-237aeb7eee0ffed230234ee04e49569f/obelisk-upgradedeleted
No changes to the content.
migration/6f104c322bbaff565981739406290402-f98b82f5d142ce83733a3f18bdacb138/obelisk-handoffdeleted
No changes to the content.
migration/6f104c322bbaff565981739406290402-f98b82f5d142ce83733a3f18bdacb138/obelisk-upgradedeleted
No changes to the content.
migration/6f3a0f756847ee5aa208a1dc79404779-00c627540326314c7154cc209e8a71e9/obelisk-handoffdeleted
No changes to the content.
migration/6f3a0f756847ee5aa208a1dc79404779-00c627540326314c7154cc209e8a71e9/obelisk-upgradedeleted
No changes to the content.
migration/6fc44f180bb825d5b372444339681135-6dc299cb41f8977785a5d676cbcd32d7/obelisk-handoffdeleted
No changes to the content.
migration/6fc44f180bb825d5b372444339681135-6dc299cb41f8977785a5d676cbcd32d7/obelisk-upgradedeleted
No changes to the content.
migration/702c65f35bc47641d60580d636ede330-9217718d2b3b217dbba72e7091459548/obelisk-handoffdeleted
No changes to the content.
migration/702c65f35bc47641d60580d636ede330-9217718d2b3b217dbba72e7091459548/obelisk-upgradedeleted
No changes to the content.
migration/71a47d4d6856c1956c0d1c9de9af231f-bb9a87fc325204313d89dbfb689dba2f/obelisk-handoffdeleted
No changes to the content.
migration/71a47d4d6856c1956c0d1c9de9af231f-bb9a87fc325204313d89dbfb689dba2f/obelisk-upgradedeleted
No changes to the content.
migration/71c6959cf98e05d356ff798ada6db2b8-55d9c5eb3b86c9cb27966f849b2d32cf/obelisk-handoffdeleted
No changes to the content.
migration/71c6959cf98e05d356ff798ada6db2b8-55d9c5eb3b86c9cb27966f849b2d32cf/obelisk-upgradedeleted
No changes to the content.
migration/71da39c91abb23488021a1e9142507d5-16b24e1a12b93ea83d7656a09d5e3338/obelisk-handoffdeleted
No changes to the content.
migration/71da39c91abb23488021a1e9142507d5-16b24e1a12b93ea83d7656a09d5e3338/obelisk-upgradedeleted
No changes to the content.
migration/721a02f3a7549e7d6efeaed087bfacb5-52df183d0f32d5a1e9ebe276b6d83d37/obelisk-handoffdeleted
No changes to the content.
migration/721a02f3a7549e7d6efeaed087bfacb5-52df183d0f32d5a1e9ebe276b6d83d37/obelisk-upgradedeleted
No changes to the content.
migration/729aaf942e685bb37fdbd5e97293bbcb-7b2b9cefa7dd57d51b587c3501a1b9ef/obelisk-handoffdeleted
No changes to the content.
migration/729aaf942e685bb37fdbd5e97293bbcb-7b2b9cefa7dd57d51b587c3501a1b9ef/obelisk-upgradedeleted
No changes to the content.
migration/73bcf3ed6593d074bd097cd43f5145d1-375acf7f2a3b3c487da2a6b30735d74d/obelisk-handoffdeleted
No changes to the content.
migration/73bcf3ed6593d074bd097cd43f5145d1-375acf7f2a3b3c487da2a6b30735d74d/obelisk-upgradedeleted
No changes to the content.
migration/73e2573d9074884d7ae83106d55ad229-729aaf942e685bb37fdbd5e97293bbcb/obelisk-handoffdeleted
No changes to the content.
migration/73e2573d9074884d7ae83106d55ad229-729aaf942e685bb37fdbd5e97293bbcb/obelisk-upgradedeleted
No changes to the content.
migration/7447d29f4712c72458c049cdb9380753-e24a771ee59f24e45afc0a27307f2070/obelisk-handoffdeleted
No changes to the content.
migration/7447d29f4712c72458c049cdb9380753-e24a771ee59f24e45afc0a27307f2070/obelisk-upgradedeleted
No changes to the content.
migration/749df832c9305e1c6309a794b0c1b201-2619464637b85cb35376393fe612ddae/obelisk-handoffdeleted
No changes to the content.
migration/749df832c9305e1c6309a794b0c1b201-2619464637b85cb35376393fe612ddae/obelisk-upgradedeleted
No changes to the content.
migration/75c9cd9763d0ed89c17d455f49d66a4f-94372bb14f8afd19bce24f8402c7564c/obelisk-handoffdeleted
No changes to the content.
migration/75c9cd9763d0ed89c17d455f49d66a4f-94372bb14f8afd19bce24f8402c7564c/obelisk-upgradedeleted
No changes to the content.
migration/77a721a8fa97d1f84dd2af622089871b-cb2d040cc16752b1dc89eecf200ea798/obelisk-handoffdeleted
No changes to the content.
migration/77a721a8fa97d1f84dd2af622089871b-cb2d040cc16752b1dc89eecf200ea798/obelisk-upgradedeleted
No changes to the content.
migration/79357758056556793db0472562d62ff9-f15c9c2f894c8cc4fac07e2cdef47180/obelisk-handoffdeleted
No changes to the content.
migration/79357758056556793db0472562d62ff9-f15c9c2f894c8cc4fac07e2cdef47180/obelisk-upgradedeleted
No changes to the content.
migration/7adece557941a7d7ac7c150f77f758be-67173f110f2c54d135e6943b65118303/obelisk-handoffdeleted
No changes to the content.
migration/7adece557941a7d7ac7c150f77f758be-67173f110f2c54d135e6943b65118303/obelisk-upgradedeleted
No changes to the content.
migration/7b2b9cefa7dd57d51b587c3501a1b9ef-1269155fffe21926f3704d5077e04332/obelisk-handoffdeleted
No changes to the content.
migration/7b2b9cefa7dd57d51b587c3501a1b9ef-1269155fffe21926f3704d5077e04332/obelisk-upgradedeleted
No changes to the content.
migration/7b75ffdcd86b5a330d9c325ad5767393-97873167212295a0fdc1219102b6b600/obelisk-handoffdeleted
No changes to the content.
migration/7b75ffdcd86b5a330d9c325ad5767393-97873167212295a0fdc1219102b6b600/obelisk-upgradedeleted
No changes to the content.
migration/7b9c28d09bd962e89b9715500f9e184c-df71cd82e801ca701bf4bc44b80b6d50/obelisk-handoffdeleted
No changes to the content.
migration/7b9c28d09bd962e89b9715500f9e184c-df71cd82e801ca701bf4bc44b80b6d50/obelisk-upgradedeleted
No changes to the content.
migration/7bc4c944b24621967a6334f522437cc1-3e8a6968585d3d60f3b13652a386aec0/obelisk-handoffdeleted
No changes to the content.
migration/7bc4c944b24621967a6334f522437cc1-3e8a6968585d3d60f3b13652a386aec0/obelisk-upgradedeleted
No changes to the content.
migration/7c0ab1210424b615251ef57036d316c3-b8aa42d4f2e5ef7db9ba34ecf6c42079/obelisk-handoffdeleted
No changes to the content.
migration/7c0ab1210424b615251ef57036d316c3-b8aa42d4f2e5ef7db9ba34ecf6c42079/obelisk-upgradedeleted
No changes to the content.
migration/7c98ef4a123c1a580d368d14e54961b7-adad34a1075a2fd51e1a1c06ec9d002d/obelisk-handoffdeleted
No changes to the content.
migration/7c98ef4a123c1a580d368d14e54961b7-adad34a1075a2fd51e1a1c06ec9d002d/obelisk-upgradedeleted
No changes to the content.
migration/7ce32302cfbba8b7567a05144057f8a3-28c5fec3b7b0b14b3625d5c8f60bcf68/obelisk-handoffdeleted
No changes to the content.
migration/7ce32302cfbba8b7567a05144057f8a3-28c5fec3b7b0b14b3625d5c8f60bcf68/obelisk-upgradedeleted
No changes to the content.
migration/7cf814f7404638f1c1be662a24d7cfea-e609d945b642fd9d4ce99931e3699db7/obelisk-handoffdeleted
No changes to the content.
migration/7cf814f7404638f1c1be662a24d7cfea-e609d945b642fd9d4ce99931e3699db7/obelisk-upgradedeleted
No changes to the content.
migration/7dd60550d7d79bd3923d91d67ecb433a-46aed07c1a61476dd245ff8e74c0559f/obelisk-handoffdeleted
No changes to the content.
migration/7dd60550d7d79bd3923d91d67ecb433a-46aed07c1a61476dd245ff8e74c0559f/obelisk-upgradedeleted
No changes to the content.
migration/7f46d84c4d303f30602b920f96acf871-97c7e1ea2c1ddb0ef23d2e4a9279f65c/obelisk-handoffdeleted
No changes to the content.
migration/7f46d84c4d303f30602b920f96acf871-97c7e1ea2c1ddb0ef23d2e4a9279f65c/obelisk-upgradedeleted
No changes to the content.
migration/7fac40a2398039b364746989bb78798b-68cca18f813a16eb0cc2c3ed7fa08044/obelisk-handoffdeleted
No changes to the content.
migration/7fac40a2398039b364746989bb78798b-68cca18f813a16eb0cc2c3ed7fa08044/obelisk-upgradedeleted
No changes to the content.
migration/7fc381538805adac19c54b73ea118601-982c57eada4652019d0b0cf6ad355d25/obelisk-handoffdeleted
No changes to the content.
migration/7fc381538805adac19c54b73ea118601-982c57eada4652019d0b0cf6ad355d25/obelisk-upgradedeleted
No changes to the content.
migration/80cb6b08443d55bb512e4a35b4768b72-59742705e53838ae13066a2239a72040/obelisk-handoffdeleted
No changes to the content.
migration/80cb6b08443d55bb512e4a35b4768b72-59742705e53838ae13066a2239a72040/obelisk-upgradedeleted
No changes to the content.
migration/81223455459db28cdbc990c3d4e6eedd-71da39c91abb23488021a1e9142507d5/obelisk-handoffdeleted
No changes to the content.
migration/81223455459db28cdbc990c3d4e6eedd-71da39c91abb23488021a1e9142507d5/obelisk-upgradedeleted
No changes to the content.
migration/8143888349912db9780231c370ea2060-beaa30317dadbef830531237279cbca4/obelisk-handoffdeleted
No changes to the content.
migration/8143888349912db9780231c370ea2060-beaa30317dadbef830531237279cbca4/obelisk-upgradedeleted
No changes to the content.
migration/81f3dbeef0d78bfb523cd2ac113b8ad8-4ace4414d71235a291f7148f80a0b0f5/obelisk-handoffdeleted
No changes to the content.
migration/81f3dbeef0d78bfb523cd2ac113b8ad8-4ace4414d71235a291f7148f80a0b0f5/obelisk-upgradedeleted
No changes to the content.
migration/84f4d5c5491abb855d8dbe3acf3bc8e6-01fb7610e4184ad1b491267fcb0c7f43/obelisk-handoffdeleted
No changes to the content.
migration/84f4d5c5491abb855d8dbe3acf3bc8e6-01fb7610e4184ad1b491267fcb0c7f43/obelisk-upgradedeleted
No changes to the content.
migration/85c2c4fb8472d50eaa97aed0bdc9b142-3e253c6beb567ba8f4c8086a76b70645/obelisk-handoffdeleted
No changes to the content.
migration/85c2c4fb8472d50eaa97aed0bdc9b142-3e253c6beb567ba8f4c8086a76b70645/obelisk-upgradedeleted
No changes to the content.
migration/8746b8f08b75b2bb7c22d8f17f22d72d-e3b3014d7e0dc983fe118d32546654e5/obelisk-handoffdeleted
No changes to the content.
migration/8746b8f08b75b2bb7c22d8f17f22d72d-e3b3014d7e0dc983fe118d32546654e5/obelisk-upgradedeleted
No changes to the content.
migration/88046de6fbbdad3f6a8a5d311948ff9b-4a037879b8a542f1590cbb87b0242331/obelisk-handoffdeleted
No changes to the content.
migration/88046de6fbbdad3f6a8a5d311948ff9b-4a037879b8a542f1590cbb87b0242331/obelisk-upgradedeleted
No changes to the content.
migration/88439725720c7ba784750cda91157dfd-69cd775958e25e3b2cff7e4897f2a9bb/obelisk-handoffdeleted
No changes to the content.
migration/88439725720c7ba784750cda91157dfd-69cd775958e25e3b2cff7e4897f2a9bb/obelisk-upgradedeleted
No changes to the content.
migration/88765caf54c2bf9f23ea4d05816a9f65-52330622ae996023b3f80a40991521a4/obelisk-handoffdeleted
No changes to the content.
migration/88765caf54c2bf9f23ea4d05816a9f65-52330622ae996023b3f80a40991521a4/obelisk-upgradedeleted
No changes to the content.
migration/8911be694899014078c8e79fc858be45-33da5c0e6705843afa6e39e65bfa0564/obelisk-handoffdeleted
No changes to the content.
migration/8911be694899014078c8e79fc858be45-33da5c0e6705843afa6e39e65bfa0564/obelisk-upgradedeleted
No changes to the content.
migration/8a64ec5f2ee43d69607499f085560857-cba28ee4b736cf8ed43cb342ccaef12e/obelisk-handoffdeleted
No changes to the content.
migration/8a64ec5f2ee43d69607499f085560857-cba28ee4b736cf8ed43cb342ccaef12e/obelisk-upgradedeleted
No changes to the content.
migration/8adb921f4dbb9d363bf6647d304e02fe-bb2f504aa4f6f1ab8ed75697dc773efb/obelisk-handoffdeleted
No changes to the content.
migration/8adb921f4dbb9d363bf6647d304e02fe-bb2f504aa4f6f1ab8ed75697dc773efb/obelisk-upgradedeleted
No changes to the content.
migration/8b098f49e1fd1aa10ca22b9dc312644e-0ec6f67d94d3913cf3243d813238ec39/obelisk-handoffdeleted
No changes to the content.
migration/8b098f49e1fd1aa10ca22b9dc312644e-0ec6f67d94d3913cf3243d813238ec39/obelisk-upgradedeleted
No changes to the content.
migration/8c7718f94e2676c957fe844b7dc2637c-96c3d49b08a9d2cfb059197c60f49c05/obelisk-handoffdeleted
No changes to the content.
migration/8c7718f94e2676c957fe844b7dc2637c-96c3d49b08a9d2cfb059197c60f49c05/obelisk-upgradedeleted
No changes to the content.
migration/8c9599be2461288eee7e78d7a34643d8-053c0b2f84a7a2eadeb5c3f9575ffa0d/obelisk-handoffdeleted
No changes to the content.
migration/8c9599be2461288eee7e78d7a34643d8-053c0b2f84a7a2eadeb5c3f9575ffa0d/obelisk-upgradedeleted
No changes to the content.
migration/8d5dba70e93ae7e784ea238281842408-c93529e579e64263fd91663216fd3fe7/obelisk-handoffdeleted
No changes to the content.
migration/8d5dba70e93ae7e784ea238281842408-c93529e579e64263fd91663216fd3fe7/obelisk-upgradedeleted
No changes to the content.
migration/8dcf46725e839f4a5dcb7a9f0235e01b-0da1150f0e9fe57d1fafbb6cabe24fa1/obelisk-handoffdeleted
No changes to the content.
migration/8dcf46725e839f4a5dcb7a9f0235e01b-0da1150f0e9fe57d1fafbb6cabe24fa1/obelisk-upgradedeleted
No changes to the content.
migration/8df9e256d8e43fa4e22d953024269b5b-9d86cedf551a6ee24c5ae6779021b925/obelisk-handoffdeleted
No changes to the content.
migration/8df9e256d8e43fa4e22d953024269b5b-9d86cedf551a6ee24c5ae6779021b925/obelisk-upgradedeleted
No changes to the content.
migration/8e01c7fee83aa74229a77772d8c928f3-8911be694899014078c8e79fc858be45/obelisk-handoffdeleted
No changes to the content.
migration/8e01c7fee83aa74229a77772d8c928f3-8911be694899014078c8e79fc858be45/obelisk-upgradedeleted
No changes to the content.
migration/8e1e426afe242ea3079f160bccd94cf0-610dcf99f7eb8c8b591ff3f5f1722938/obelisk-handoffdeleted
No changes to the content.
migration/8e1e426afe242ea3079f160bccd94cf0-610dcf99f7eb8c8b591ff3f5f1722938/obelisk-upgradedeleted
No changes to the content.
migration/8fca2c4d6478ed8628925852b2af45bf-03b845f308e73a1567eb843dfca182d2/obelisk-handoffdeleted
No changes to the content.
migration/8fca2c4d6478ed8628925852b2af45bf-03b845f308e73a1567eb843dfca182d2/obelisk-upgradedeleted
No changes to the content.
migration/90489c1a9f7edd46a070d6474dceac86-7fac40a2398039b364746989bb78798b/obelisk-handoffdeleted
No changes to the content.
migration/90489c1a9f7edd46a070d6474dceac86-7fac40a2398039b364746989bb78798b/obelisk-upgradedeleted
No changes to the content.
migration/909b6b2066cbdc991e6c16455f13637c-1e36dc8817e2784df36d643b7499092d/obelisk-handoffdeleted
No changes to the content.
migration/909b6b2066cbdc991e6c16455f13637c-1e36dc8817e2784df36d643b7499092d/obelisk-upgradedeleted
No changes to the content.
migration/90b4e20464e08ade5f215f2a4ea28cc6-b7630e5f30252987bf899c74de3953ad/obelisk-handoffdeleted
No changes to the content.
migration/90b4e20464e08ade5f215f2a4ea28cc6-b7630e5f30252987bf899c74de3953ad/obelisk-upgradedeleted
No changes to the content.
migration/9217718d2b3b217dbba72e7091459548-88046de6fbbdad3f6a8a5d311948ff9b/obelisk-handoffdeleted
No changes to the content.
migration/9217718d2b3b217dbba72e7091459548-88046de6fbbdad3f6a8a5d311948ff9b/obelisk-upgradedeleted
No changes to the content.
migration/9223532a537f698ef36f4dce6e922a6b-d327ceb69d24e40dc11792840454cff9/obelisk-handoffdeleted
No changes to the content.
migration/9223532a537f698ef36f4dce6e922a6b-d327ceb69d24e40dc11792840454cff9/obelisk-upgradedeleted
No changes to the content.
migration/92ab733e8991f12cc12148f8d4e1b35d-e4b89dd259f3831bc60b56147b3586a6/obelisk-handoffdeleted
No changes to the content.
migration/92ab733e8991f12cc12148f8d4e1b35d-e4b89dd259f3831bc60b56147b3586a6/obelisk-upgradedeleted
No changes to the content.
migration/930e9213e072e87c207f93461bd3c96c-7f46d84c4d303f30602b920f96acf871/obelisk-handoffdeleted
No changes to the content.
migration/930e9213e072e87c207f93461bd3c96c-7f46d84c4d303f30602b920f96acf871/obelisk-upgradedeleted
No changes to the content.
migration/93f164bbd887f688fd49bb80afffccd6-f8eee9431c8b7a767d96da0a8cfae95d/obelisk-handoffdeleted
No changes to the content.
migration/93f164bbd887f688fd49bb80afffccd6-f8eee9431c8b7a767d96da0a8cfae95d/obelisk-upgradedeleted
No changes to the content.
migration/93fc625d41bae9fcf06b9febeacb686d-662eb30d6e4612f130edc3f6d37d92a2/obelisk-handoffdeleted
No changes to the content.
migration/93fc625d41bae9fcf06b9febeacb686d-662eb30d6e4612f130edc3f6d37d92a2/obelisk-upgradedeleted
No changes to the content.
migration/94252585266fa745a91733888e2f50b7-d207ab99328b8ece5fb27fa1f4dbf9f6/obelisk-handoffdeleted
No changes to the content.
migration/94252585266fa745a91733888e2f50b7-d207ab99328b8ece5fb27fa1f4dbf9f6/obelisk-upgradedeleted
No changes to the content.
migration/94372bb14f8afd19bce24f8402c7564c-7dd60550d7d79bd3923d91d67ecb433a/obelisk-handoffdeleted
No changes to the content.
migration/94372bb14f8afd19bce24f8402c7564c-7dd60550d7d79bd3923d91d67ecb433a/obelisk-upgradedeleted
No changes to the content.
migration/947784563e3a27cf6486bed9a3c52f15-25615a274650370633e8083ed19fbdd0/obelisk-handoffdeleted
No changes to the content.
migration/947784563e3a27cf6486bed9a3c52f15-25615a274650370633e8083ed19fbdd0/obelisk-upgradedeleted
No changes to the content.
migration/94dd4eb45a4e7eb945027d5fd8eb4fa6-e22c51145e08d4a089003460ae80a7f9/obelisk-handoffdeleted
No changes to the content.
migration/94dd4eb45a4e7eb945027d5fd8eb4fa6-e22c51145e08d4a089003460ae80a7f9/obelisk-upgradedeleted
No changes to the content.
migration/95955d1dd0981ebb538ee941cde1f963-07900e6c41ab9a78917f66fcf7e0d9b8/obelisk-handoffdeleted
No changes to the content.
migration/95955d1dd0981ebb538ee941cde1f963-07900e6c41ab9a78917f66fcf7e0d9b8/obelisk-upgradedeleted
No changes to the content.
migration/959ae2925bcd2b5beff631a8e7aeaf00-071f5b3326b8886de3eddc927b80eb10/obelisk-handoffdeleted
No changes to the content.
migration/959ae2925bcd2b5beff631a8e7aeaf00-071f5b3326b8886de3eddc927b80eb10/obelisk-upgradedeleted
No changes to the content.
migration/962e2bd1ae8d0c233f8da89ecebffe50-d6c090699acd25fc60213ff4bd9eebcf/obelisk-handoffdeleted
No changes to the content.
migration/962e2bd1ae8d0c233f8da89ecebffe50-d6c090699acd25fc60213ff4bd9eebcf/obelisk-upgradedeleted
No changes to the content.
migration/96c3d49b08a9d2cfb059197c60f49c05-6da2e5b02ab780d12527640722d2b511/obelisk-handoffdeleted
No changes to the content.
migration/96c3d49b08a9d2cfb059197c60f49c05-6da2e5b02ab780d12527640722d2b511/obelisk-upgradedeleted
No changes to the content.
migration/9705509619667aacf799e91927c16dc8-2773d4a82ca59b48faf036755e163a5f/obelisk-handoffdeleted
No changes to the content.
migration/9705509619667aacf799e91927c16dc8-2773d4a82ca59b48faf036755e163a5f/obelisk-upgradedeleted
No changes to the content.
migration/9715967793be68dfd8c9a7d631f8d589-d532356dfb65a4c8a39452d2ebca2516/obelisk-handoffdeleted
No changes to the content.
migration/9715967793be68dfd8c9a7d631f8d589-d532356dfb65a4c8a39452d2ebca2516/obelisk-upgradedeleted
No changes to the content.
migration/975cd8245d06ad09e4fb176cfc9af5e0-3f23549fba6f8e67ba36b4405e8680b3/obelisk-handoffdeleted
No changes to the content.
migration/975cd8245d06ad09e4fb176cfc9af5e0-3f23549fba6f8e67ba36b4405e8680b3/obelisk-upgradedeleted
No changes to the content.
migration/97873167212295a0fdc1219102b6b600-88439725720c7ba784750cda91157dfd/obelisk-handoffdeleted
No changes to the content.
migration/97873167212295a0fdc1219102b6b600-88439725720c7ba784750cda91157dfd/obelisk-upgradedeleted
No changes to the content.
migration/97c7e1ea2c1ddb0ef23d2e4a9279f65c-d747c3d0620b2034aca44265dd1c8c86/obelisk-handoffdeleted
No changes to the content.
migration/97c7e1ea2c1ddb0ef23d2e4a9279f65c-d747c3d0620b2034aca44265dd1c8c86/obelisk-upgradedeleted
No changes to the content.
migration/982c57eada4652019d0b0cf6ad355d25-6708d14c71c475ac494808e75660a385/obelisk-handoffdeleted
No changes to the content.
migration/982c57eada4652019d0b0cf6ad355d25-6708d14c71c475ac494808e75660a385/obelisk-upgradedeleted
No changes to the content.
migration/98629a336dcd5fa3524a09f8ea6ad636-8c9599be2461288eee7e78d7a34643d8/obelisk-handoffdeleted
No changes to the content.
migration/98629a336dcd5fa3524a09f8ea6ad636-8c9599be2461288eee7e78d7a34643d8/obelisk-upgradedeleted
No changes to the content.
migration/98da197f133bca81e533ab5ffbf4c82d-a0b418c582d5c6ef9e0cd9a19abe046e/obelisk-handoffdeleted
No changes to the content.
migration/98da197f133bca81e533ab5ffbf4c82d-a0b418c582d5c6ef9e0cd9a19abe046e/obelisk-upgradedeleted
No changes to the content.
migration/98f9e0bbd21e36b0f4daa440d11e7177-bab3871bcfbfcb3d2bad4495d44ae4f8/obelisk-handoffdeleted
No changes to the content.
migration/98f9e0bbd21e36b0f4daa440d11e7177-bab3871bcfbfcb3d2bad4495d44ae4f8/obelisk-upgradedeleted
No changes to the content.
migration/99aebbfcac51725464bc59571b7d71b8-34d14d4a444d3bf1487ada6129815df4/obelisk-handoffdeleted
No changes to the content.
migration/99aebbfcac51725464bc59571b7d71b8-34d14d4a444d3bf1487ada6129815df4/obelisk-upgradedeleted
No changes to the content.
migration/9b33a49f0c978e27b752fa457aca97cc-51f3d5068259f596b811450f0bf25419/obelisk-handoffdeleted
No changes to the content.
migration/9b33a49f0c978e27b752fa457aca97cc-51f3d5068259f596b811450f0bf25419/obelisk-upgradedeleted
No changes to the content.
migration/9b9d73736773550dde7d36de2498b029-69537089a0e97845ffe05c73c3cc1536/obelisk-handoffdeleted
No changes to the content.
migration/9b9d73736773550dde7d36de2498b029-69537089a0e97845ffe05c73c3cc1536/obelisk-upgradedeleted
No changes to the content.
migration/9c94cd459a25b5c2de56067c8fdac620-721a02f3a7549e7d6efeaed087bfacb5/obelisk-handoffdeleted
No changes to the content.
migration/9c94cd459a25b5c2de56067c8fdac620-721a02f3a7549e7d6efeaed087bfacb5/obelisk-upgradedeleted
No changes to the content.
migration/9cef2dd1885f16455ff9b6801ec99454-63ff9426130baa080f37400a86c55fdd/obelisk-handoffdeleted
No changes to the content.
migration/9cef2dd1885f16455ff9b6801ec99454-63ff9426130baa080f37400a86c55fdd/obelisk-upgradedeleted
No changes to the content.
migration/9d86cedf551a6ee24c5ae6779021b925-1c9bdb5c544f2e5432f549653a61dabe/obelisk-handoffdeleted
No changes to the content.
migration/9d86cedf551a6ee24c5ae6779021b925-1c9bdb5c544f2e5432f549653a61dabe/obelisk-upgradedeleted
No changes to the content.
migration/9e05cc6b81c6380ba0ac59bad1021cac-ce7f0d15d71d36d4bcf4fbadcdfa1b58/obelisk-handoffdeleted
No changes to the content.
migration/9e05cc6b81c6380ba0ac59bad1021cac-ce7f0d15d71d36d4bcf4fbadcdfa1b58/obelisk-upgradedeleted
No changes to the content.
migration/9e61f37dd79310b71c80ee166aeb4e80-466a19f9cfa2a103467fe6627225d27f/obelisk-handoffdeleted
No changes to the content.
migration/9e61f37dd79310b71c80ee166aeb4e80-466a19f9cfa2a103467fe6627225d27f/obelisk-upgradedeleted
No changes to the content.
migration/9f6c8fd80ab3ff2dcc48bfd211c8b761-24f151a674662ac47845237d7a9f6a4f/obelisk-handoffdeleted
No changes to the content.
migration/9f6c8fd80ab3ff2dcc48bfd211c8b761-24f151a674662ac47845237d7a9f6a4f/obelisk-upgradedeleted
No changes to the content.
migration/9f71fc9d2ed805fecbc8c4a3aae5685b-cb2197d0267b52385ee39bf4adcfe475/obelisk-handoffdeleted
No changes to the content.
migration/9f71fc9d2ed805fecbc8c4a3aae5685b-cb2197d0267b52385ee39bf4adcfe475/obelisk-upgradedeleted
No changes to the content.
migration/9fb504b182cbd8dfb666175b651e0b49-338b92f88c49c7c3a1d8ec231d9f7189/obelisk-handoffdeleted
No changes to the content.
migration/9fb504b182cbd8dfb666175b651e0b49-338b92f88c49c7c3a1d8ec231d9f7189/obelisk-upgradedeleted
No changes to the content.
migration/9fe2922674fcee5e840c9f52cf534f88-ac92878eb85c5283bcc5f3f34cd35aa6/obelisk-handoffdeleted
No changes to the content.
migration/9fe2922674fcee5e840c9f52cf534f88-ac92878eb85c5283bcc5f3f34cd35aa6/obelisk-upgradedeleted
No changes to the content.
migration/a00870cfca85ff8dae5db3a78f5a227d-c2502429502b46133a749f021d188cf0/obelisk-handoffdeleted
No changes to the content.
migration/a00870cfca85ff8dae5db3a78f5a227d-c2502429502b46133a749f021d188cf0/obelisk-upgradedeleted
No changes to the content.
migration/a080b8549e32f21fec11084f4ab1e052-bd7c24fc03bf82e5a990515531a69147/obelisk-handoffdeleted
No changes to the content.
migration/a080b8549e32f21fec11084f4ab1e052-bd7c24fc03bf82e5a990515531a69147/obelisk-upgradedeleted
No changes to the content.
migration/a08aebb6f40fb45d174b229532314ac4-1c1c3f2b4426d5d26377eef08dbccb3c/obelisk-handoffdeleted
No changes to the content.
migration/a08aebb6f40fb45d174b229532314ac4-1c1c3f2b4426d5d26377eef08dbccb3c/obelisk-upgradedeleted
No changes to the content.
migration/a0b418c582d5c6ef9e0cd9a19abe046e-63422a9bade5c703461b600e03e227f0/obelisk-handoffdeleted
No changes to the content.
migration/a0b418c582d5c6ef9e0cd9a19abe046e-63422a9bade5c703461b600e03e227f0/obelisk-upgradedeleted
No changes to the content.
migration/a0f5ac2ff5c6a957e565f898a9fc8bfb-bf3fbc8db3d6fd42a37982dfb5a30b5c/obelisk-handoffdeleted
No changes to the content.
migration/a0f5ac2ff5c6a957e565f898a9fc8bfb-bf3fbc8db3d6fd42a37982dfb5a30b5c/obelisk-upgradedeleted
No changes to the content.
migration/a262678b7d849de5a9732d06199666ae-ebb95c5864d1d1d2f78fbf7cc8235dac/obelisk-handoffdeleted
No changes to the content.
migration/a262678b7d849de5a9732d06199666ae-ebb95c5864d1d1d2f78fbf7cc8235dac/obelisk-upgradedeleted
No changes to the content.
migration/a2665cfd303a4a34a7bfa3b7d0d264bb-aff3f143ddaa4ed3ffad873d6638e277/obelisk-handoffdeleted
No changes to the content.
migration/a2665cfd303a4a34a7bfa3b7d0d264bb-aff3f143ddaa4ed3ffad873d6638e277/obelisk-upgradedeleted
No changes to the content.
migration/a2b33f8dc1f90b8dddce942b174be5b8-00a480749e96ef7e21fbe8f4943152b1/obelisk-handoffdeleted
No changes to the content.
migration/a2b33f8dc1f90b8dddce942b174be5b8-00a480749e96ef7e21fbe8f4943152b1/obelisk-upgradedeleted
No changes to the content.
migration/a2bdbf1985b75442e78e84523c4ced5f-48c027da19d895ba03e7b9120f771291/obelisk-handoffdeleted
No changes to the content.
migration/a2bdbf1985b75442e78e84523c4ced5f-48c027da19d895ba03e7b9120f771291/obelisk-upgradedeleted
No changes to the content.
migration/a34d758508a0a5d08bc10e76482c4d11-8fca2c4d6478ed8628925852b2af45bf/obelisk-handoffdeleted
No changes to the content.
migration/a34d758508a0a5d08bc10e76482c4d11-8fca2c4d6478ed8628925852b2af45bf/obelisk-upgradedeleted
No changes to the content.
migration/a4477746ae1a7024bc3cd0807180d418-fb5110e527cf77c568bcae7d435ee035/obelisk-handoffdeleted
No changes to the content.
migration/a4477746ae1a7024bc3cd0807180d418-fb5110e527cf77c568bcae7d435ee035/obelisk-upgradedeleted
No changes to the content.
migration/a5297d8457aa4c327f35d4697f6cb66f-2f928f9c4a137186f808a231c9e3c141/obelisk-handoffdeleted
No changes to the content.
migration/a5297d8457aa4c327f35d4697f6cb66f-2f928f9c4a137186f808a231c9e3c141/obelisk-upgradedeleted
No changes to the content.
migration/a536d01b9c489f5e00e30abf27427da0-b8a8ffc909e5fc350d9f8a6a90e7b3d9/obelisk-handoffdeleted
No changes to the content.
migration/a536d01b9c489f5e00e30abf27427da0-b8a8ffc909e5fc350d9f8a6a90e7b3d9/obelisk-upgradedeleted
No changes to the content.
migration/a5904e3a899e346fe2fe26314f69c075-e4513b485b6ba8b7f4bd34b12458ff0c/obelisk-handoffdeleted
No changes to the content.
migration/a5904e3a899e346fe2fe26314f69c075-e4513b485b6ba8b7f4bd34b12458ff0c/obelisk-upgradedeleted
No changes to the content.
migration/a5bbc0b9ceab9c3f7ca32a7da8c1f685-3c4b3152f0608d23d07240e2df3ff8da/obelisk-handoffdeleted
No changes to the content.
migration/a5bbc0b9ceab9c3f7ca32a7da8c1f685-3c4b3152f0608d23d07240e2df3ff8da/obelisk-upgradedeleted
No changes to the content.
migration/a5e40d67714a1b2daa06e3fb3293216d-04a5ae41e8fcef5f719cb84d01430382/obelisk-handoffdeleted
No changes to the content.
migration/a5e40d67714a1b2daa06e3fb3293216d-04a5ae41e8fcef5f719cb84d01430382/obelisk-upgradedeleted
No changes to the content.
migration/a632452cf9c5956becd1a40512472b43-d6a3ea5f7eb3c95f5e5ea09fb1330270/obelisk-handoffdeleted
No changes to the content.
migration/a632452cf9c5956becd1a40512472b43-d6a3ea5f7eb3c95f5e5ea09fb1330270/obelisk-upgradedeleted
No changes to the content.
migration/a6633fc9687566aa84c3d5d5e2bff4fd-b5cab336f6244293913433101cd0feff/obelisk-handoffdeleted
No changes to the content.
migration/a6633fc9687566aa84c3d5d5e2bff4fd-b5cab336f6244293913433101cd0feff/obelisk-upgradedeleted
No changes to the content.
migration/a6d50c7e756dfd1e3ae891111b81a1ae-270b3b3f7bc510c692e3253a895f122a/obelisk-handoffdeleted
No changes to the content.
migration/a6d50c7e756dfd1e3ae891111b81a1ae-270b3b3f7bc510c692e3253a895f122a/obelisk-upgradedeleted
No changes to the content.
migration/a7c7b80a875d1863f027c97eb433b884-cbe155a3e856fb7eaad0bd18feb408be/obelisk-handoffdeleted
No changes to the content.
migration/a7c7b80a875d1863f027c97eb433b884-cbe155a3e856fb7eaad0bd18feb408be/obelisk-upgradedeleted
No changes to the content.
migration/a808a04519bbf2874e41028ded9c180c-8e1e426afe242ea3079f160bccd94cf0/obelisk-handoffdeleted
No changes to the content.
migration/a808a04519bbf2874e41028ded9c180c-8e1e426afe242ea3079f160bccd94cf0/obelisk-upgradedeleted
No changes to the content.
migration/a825fbb74e8d050a5ce10ec4c62b83f5-c3298d81428117be58196b80853e3c7b/obelisk-handoffdeleted
No changes to the content.
migration/a825fbb74e8d050a5ce10ec4c62b83f5-c3298d81428117be58196b80853e3c7b/obelisk-upgradedeleted
No changes to the content.
migration/a826f01311fe00ef5cf87568832605d3-9fb504b182cbd8dfb666175b651e0b49/obelisk-handoffdeleted
No changes to the content.
migration/a826f01311fe00ef5cf87568832605d3-9fb504b182cbd8dfb666175b651e0b49/obelisk-upgradedeleted
No changes to the content.
migration/a878ad346b9305ad2ae3fd85410a7ed7-0f78d9d6875933336bbf0c1c8888b73f/obelisk-handoffdeleted
No changes to the content.
migration/a878ad346b9305ad2ae3fd85410a7ed7-0f78d9d6875933336bbf0c1c8888b73f/obelisk-upgradedeleted
No changes to the content.
migration/a8ebe201ab7a7b0211de41b14a95192e-65071e255719af6389857646bc087d37/obelisk-handoffdeleted
No changes to the content.
migration/a8ebe201ab7a7b0211de41b14a95192e-65071e255719af6389857646bc087d37/obelisk-upgradedeleted
No changes to the content.
migration/a96d491705acc139315264fd340d228f-be615dc4d60c9d8710fbd120857c2fa1/obelisk-handoffdeleted
No changes to the content.
migration/a96d491705acc139315264fd340d228f-be615dc4d60c9d8710fbd120857c2fa1/obelisk-upgradedeleted
No changes to the content.
migration/aa8e6712fd46824acdea303068634078-dc95f39fb27634ccbca7318ff2065608/obelisk-handoffdeleted
No changes to the content.
migration/aa8e6712fd46824acdea303068634078-dc95f39fb27634ccbca7318ff2065608/obelisk-upgradedeleted
No changes to the content.
migration/aaf979dd0121603a8b48127e1ea47c7d-4b7a36dce2c1cf94554e12d8a7903269/obelisk-handoffdeleted
No changes to the content.
migration/aaf979dd0121603a8b48127e1ea47c7d-4b7a36dce2c1cf94554e12d8a7903269/obelisk-upgradedeleted
No changes to the content.
migration/abdb013baf130e1bd7e7fd04e535c44c-39df6544d6b035d4c77cc829729f9c19/obelisk-handoffdeleted
No changes to the content.
migration/abdb013baf130e1bd7e7fd04e535c44c-39df6544d6b035d4c77cc829729f9c19/obelisk-upgradedeleted
No changes to the content.
migration/ac5e28caddd6832d0bf1f7445a4a6a28-e01cc01684deaf4c75ad5d65270bf3d5/obelisk-handoffdeleted
No changes to the content.
migration/ac5e28caddd6832d0bf1f7445a4a6a28-e01cc01684deaf4c75ad5d65270bf3d5/obelisk-upgradedeleted
No changes to the content.
migration/ac92878eb85c5283bcc5f3f34cd35aa6-145650b66e83adf5bdb8261593076379/obelisk-handoffdeleted
No changes to the content.
migration/ac92878eb85c5283bcc5f3f34cd35aa6-145650b66e83adf5bdb8261593076379/obelisk-upgradedeleted
No changes to the content.
migration/adad34a1075a2fd51e1a1c06ec9d002d-930e9213e072e87c207f93461bd3c96c/obelisk-handoffdeleted
No changes to the content.
migration/adad34a1075a2fd51e1a1c06ec9d002d-930e9213e072e87c207f93461bd3c96c/obelisk-upgradedeleted
No changes to the content.
migration/ae4328daeb7d2c52c534a687fbd184b6-3e763ebe16cc3a261f5776ab1f1f6d9a/obelisk-handoffdeleted
No changes to the content.
migration/ae4328daeb7d2c52c534a687fbd184b6-3e763ebe16cc3a261f5776ab1f1f6d9a/obelisk-upgradedeleted
No changes to the content.
migration/ae824b83b569b3b23b8e198190371ca0-81f3dbeef0d78bfb523cd2ac113b8ad8/obelisk-handoffdeleted
No changes to the content.
migration/ae824b83b569b3b23b8e198190371ca0-81f3dbeef0d78bfb523cd2ac113b8ad8/obelisk-upgradedeleted
No changes to the content.
migration/ae8862f8b7292690c852111ca5659ce9-ae4328daeb7d2c52c534a687fbd184b6/obelisk-handoffdeleted
No changes to the content.
migration/ae8862f8b7292690c852111ca5659ce9-ae4328daeb7d2c52c534a687fbd184b6/obelisk-upgradedeleted
No changes to the content.
migration/aeafaa5d20bab4439a5d31f29023a839-79357758056556793db0472562d62ff9/obelisk-handoffdeleted
No changes to the content.
migration/aeafaa5d20bab4439a5d31f29023a839-79357758056556793db0472562d62ff9/obelisk-upgradedeleted
No changes to the content.
migration/aef6ac052515a869c7d3061d4ccc69dd-15f3f3f517b38664131b85da0594522f/obelisk-handoffdeleted
No changes to the content.
migration/aef6ac052515a869c7d3061d4ccc69dd-15f3f3f517b38664131b85da0594522f/obelisk-upgradedeleted
No changes to the content.
migration/afbd010add526d309dccee6895e42d0d-6f3a0f756847ee5aa208a1dc79404779/obelisk-handoffdeleted
No changes to the content.
migration/afbd010add526d309dccee6895e42d0d-6f3a0f756847ee5aa208a1dc79404779/obelisk-upgradedeleted
No changes to the content.
migration/aff3f143ddaa4ed3ffad873d6638e277-6fc44f180bb825d5b372444339681135/obelisk-handoffdeleted
No changes to the content.
migration/aff3f143ddaa4ed3ffad873d6638e277-6fc44f180bb825d5b372444339681135/obelisk-upgradedeleted
No changes to the content.
migration/b0c1d039514a686529561f186332c91e-a878ad346b9305ad2ae3fd85410a7ed7/obelisk-handoffdeleted
No changes to the content.
migration/b0c1d039514a686529561f186332c91e-a878ad346b9305ad2ae3fd85410a7ed7/obelisk-upgradedeleted
No changes to the content.
migration/b1692927da5ed59af72fac5be8094fa2-d5ba6f13296205e5bd88ca2756107df0/obelisk-handoffdeleted
No changes to the content.
migration/b1692927da5ed59af72fac5be8094fa2-d5ba6f13296205e5bd88ca2756107df0/obelisk-upgradedeleted
No changes to the content.
migration/b2282679f6f63cec89d921c3dd512d1e-1f09fcf196bfe90ed52f113c38ffbfdb/obelisk-handoffdeleted
No changes to the content.
migration/b2282679f6f63cec89d921c3dd512d1e-1f09fcf196bfe90ed52f113c38ffbfdb/obelisk-upgradedeleted
No changes to the content.
migration/b3b107d406a6a7675cd5b9f52e5f7d8e-0d3b4cfe9b4c72b830780a4c44942176/obelisk-handoffdeleted
No changes to the content.
migration/b3b107d406a6a7675cd5b9f52e5f7d8e-0d3b4cfe9b4c72b830780a4c44942176/obelisk-upgradedeleted
No changes to the content.
migration/b3ff195b0a90ef5900f9cef2ba75f2fe-24e0d027f4160a6478c1356e51f419cf/obelisk-handoffdeleted
No changes to the content.
migration/b3ff195b0a90ef5900f9cef2ba75f2fe-24e0d027f4160a6478c1356e51f419cf/obelisk-upgradedeleted
No changes to the content.
migration/b4f6596f2c16811442d8bb2961fbb721-3c7755e495f20cfac5e4dabe78644c5a/obelisk-handoffdeleted
No changes to the content.
migration/b4f6596f2c16811442d8bb2961fbb721-3c7755e495f20cfac5e4dabe78644c5a/obelisk-upgradedeleted
No changes to the content.
migration/b5cab336f6244293913433101cd0feff-8746b8f08b75b2bb7c22d8f17f22d72d/obelisk-handoffdeleted
No changes to the content.
migration/b5cab336f6244293913433101cd0feff-8746b8f08b75b2bb7c22d8f17f22d72d/obelisk-upgradedeleted
No changes to the content.
migration/b641dd9c5359201200e483a784456cc2-cc4307fc88e3486b1c3f9ce07db95808/obelisk-handoffdeleted
No changes to the content.
migration/b641dd9c5359201200e483a784456cc2-cc4307fc88e3486b1c3f9ce07db95808/obelisk-upgradedeleted
No changes to the content.
migration/b6425c7661af2116b912a558e9548013-4aefa80392582ec03a19f946e752d331/obelisk-handoffdeleted
No changes to the content.
migration/b6425c7661af2116b912a558e9548013-4aefa80392582ec03a19f946e752d331/obelisk-upgradedeleted
No changes to the content.
migration/b68a785fbf27a63334ef1d1fe82b2dac-d6b34eba6ed4f89875a6615fe2c41ec2/obelisk-handoffdeleted
No changes to the content.
migration/b68a785fbf27a63334ef1d1fe82b2dac-d6b34eba6ed4f89875a6615fe2c41ec2/obelisk-upgradedeleted
No changes to the content.
migration/b6ffce85249f30616da76334c7bbec6e-66a9b6b9e9bc4a5b0cfa78127479b231/obelisk-handoffdeleted
No changes to the content.
migration/b6ffce85249f30616da76334c7bbec6e-66a9b6b9e9bc4a5b0cfa78127479b231/obelisk-upgradedeleted
No changes to the content.
migration/b7630e5f30252987bf899c74de3953ad-3f0687592a77c0c66193652e9cd981fd/obelisk-handoffdeleted
No changes to the content.
migration/b7630e5f30252987bf899c74de3953ad-3f0687592a77c0c66193652e9cd981fd/obelisk-upgradedeleted
No changes to the content.
migration/b7e30314f9d0e69efdc84c7eb4e3bcc3-e4051219d89b3c9a8350fe824ad96a82/obelisk-handoffdeleted
No changes to the content.
migration/b7e30314f9d0e69efdc84c7eb4e3bcc3-e4051219d89b3c9a8350fe824ad96a82/obelisk-upgradedeleted
No changes to the content.
migration/b82e9c3fe22feff4bb3a6be49943fd6c-fbb3eb3209281031dc5183d289eb4e75/obelisk-handoffdeleted
No changes to the content.
migration/b82e9c3fe22feff4bb3a6be49943fd6c-fbb3eb3209281031dc5183d289eb4e75/obelisk-upgradedeleted
No changes to the content.
migration/b8a8ffc909e5fc350d9f8a6a90e7b3d9-aef6ac052515a869c7d3061d4ccc69dd/obelisk-handoffdeleted
No changes to the content.
migration/b8a8ffc909e5fc350d9f8a6a90e7b3d9-aef6ac052515a869c7d3061d4ccc69dd/obelisk-upgradedeleted
No changes to the content.
migration/b8aa42d4f2e5ef7db9ba34ecf6c42079-37c2ed0ba2cd54c0ec29eae9043bc4c8/obelisk-handoffdeleted
No changes to the content.
migration/b8aa42d4f2e5ef7db9ba34ecf6c42079-37c2ed0ba2cd54c0ec29eae9043bc4c8/obelisk-upgradedeleted
No changes to the content.
migration/b95c8d049256fb7360ca14b12acd8544-e7b17aa124e17c357cead8081a58f089/obelisk-handoffdeleted
No changes to the content.
migration/b95c8d049256fb7360ca14b12acd8544-e7b17aa124e17c357cead8081a58f089/obelisk-upgradedeleted
No changes to the content.
migration/ba0ccd5ef6110f6c5133d9d6ea6277f0-e78ec85bec14f4784faeef4d8d3e4d0a/obelisk-handoffdeleted
No changes to the content.
migration/ba0ccd5ef6110f6c5133d9d6ea6277f0-e78ec85bec14f4784faeef4d8d3e4d0a/obelisk-upgradedeleted
No changes to the content.
migration/ba4829dc61dcc12bcafd8de5fc8a76dc-2164344be67da5d0e57052c15f30646d/obelisk-handoffdeleted
No changes to the content.
migration/ba4829dc61dcc12bcafd8de5fc8a76dc-2164344be67da5d0e57052c15f30646d/obelisk-upgradedeleted
No changes to the content.
migration/bab3871bcfbfcb3d2bad4495d44ae4f8-9cef2dd1885f16455ff9b6801ec99454/obelisk-handoffdeleted
No changes to the content.
migration/bab3871bcfbfcb3d2bad4495d44ae4f8-9cef2dd1885f16455ff9b6801ec99454/obelisk-upgradedeleted
No changes to the content.
migration/bb2f504aa4f6f1ab8ed75697dc773efb-bcd13da3a7fba8514084c1a9dbeabb31/obelisk-handoffdeleted
No changes to the content.
migration/bb2f504aa4f6f1ab8ed75697dc773efb-bcd13da3a7fba8514084c1a9dbeabb31/obelisk-upgradedeleted
No changes to the content.
migration/bb9a87fc325204313d89dbfb689dba2f-d2d86ce0ca16b143b49374302a9e9e2f/obelisk-handoffdeleted
No changes to the content.
migration/bb9a87fc325204313d89dbfb689dba2f-d2d86ce0ca16b143b49374302a9e9e2f/obelisk-upgradedeleted
No changes to the content.
migration/bc7688ff47218c0e13d02d917b03caa0-2bdd4221307cafa3e98c4d3017cdc912/obelisk-handoffdeleted
No changes to the content.
migration/bc7688ff47218c0e13d02d917b03caa0-2bdd4221307cafa3e98c4d3017cdc912/obelisk-upgradedeleted
No changes to the content.
migration/bcd13da3a7fba8514084c1a9dbeabb31-8dcf46725e839f4a5dcb7a9f0235e01b/obelisk-handoffdeleted
No changes to the content.
migration/bcd13da3a7fba8514084c1a9dbeabb31-8dcf46725e839f4a5dcb7a9f0235e01b/obelisk-upgradedeleted
No changes to the content.
migration/bd6728737dffcc3505d30ada344e2f4b-1cc8d98f6f61441570fdde2d697e6e3c/obelisk-handoffdeleted
No changes to the content.
migration/bd6728737dffcc3505d30ada344e2f4b-1cc8d98f6f61441570fdde2d697e6e3c/obelisk-upgradedeleted
No changes to the content.
migration/bd7c24fc03bf82e5a990515531a69147-a5e40d67714a1b2daa06e3fb3293216d/obelisk-handoffdeleted
No changes to the content.
migration/bd7c24fc03bf82e5a990515531a69147-a5e40d67714a1b2daa06e3fb3293216d/obelisk-upgradedeleted
No changes to the content.
migration/bd8f5fa095c3eb19b87d85247b36f1df-5d90abd974b4ec53091a8cb3fc2258ce/obelisk-handoffdeleted
No changes to the content.
migration/bd8f5fa095c3eb19b87d85247b36f1df-5d90abd974b4ec53091a8cb3fc2258ce/obelisk-upgradedeleted
No changes to the content.
migration/be5a7b436cef0ae35cb074700d5f0d00-7c0ab1210424b615251ef57036d316c3/obelisk-handoffdeleted
No changes to the content.
migration/be5a7b436cef0ae35cb074700d5f0d00-7c0ab1210424b615251ef57036d316c3/obelisk-upgradedeleted
No changes to the content.
migration/be615dc4d60c9d8710fbd120857c2fa1-1e376437f069662df26178e4a7873190/obelisk-handoffdeleted
No changes to the content.
migration/be615dc4d60c9d8710fbd120857c2fa1-1e376437f069662df26178e4a7873190/obelisk-upgradedeleted
No changes to the content.
migration/beaa30317dadbef830531237279cbca4-a0f5ac2ff5c6a957e565f898a9fc8bfb/obelisk-handoffdeleted
No changes to the content.
migration/beaa30317dadbef830531237279cbca4-a0f5ac2ff5c6a957e565f898a9fc8bfb/obelisk-upgradedeleted
No changes to the content.
migration/bf22c91488f01ebf503c1786ee805d0c-64ee9e40f4943e0122398e48019f5616/obelisk-handoffdeleted
No changes to the content.
migration/bf22c91488f01ebf503c1786ee805d0c-64ee9e40f4943e0122398e48019f5616/obelisk-upgradedeleted
No changes to the content.
migration/bf3fbc8db3d6fd42a37982dfb5a30b5c-0c6127453069ad707e34ddfedb67e2f9/obelisk-handoffdeleted
No changes to the content.
migration/bf3fbc8db3d6fd42a37982dfb5a30b5c-0c6127453069ad707e34ddfedb67e2f9/obelisk-upgradedeleted
No changes to the content.
migration/bf81caf2a7d528f86acacc1f5d2ffcfa-a5bbc0b9ceab9c3f7ca32a7da8c1f685/obelisk-handoffdeleted
No changes to the content.
migration/bf81caf2a7d528f86acacc1f5d2ffcfa-a5bbc0b9ceab9c3f7ca32a7da8c1f685/obelisk-upgradedeleted
No changes to the content.
migration/c0811b664036c7996fcfd19fee241a10-a2bdbf1985b75442e78e84523c4ced5f/obelisk-handoffdeleted
No changes to the content.
migration/c0811b664036c7996fcfd19fee241a10-a2bdbf1985b75442e78e84523c4ced5f/obelisk-upgradedeleted
No changes to the content.
migration/c0c1452986b8d4c181bb0c6c83c56a2f-bf22c91488f01ebf503c1786ee805d0c/obelisk-handoffdeleted
No changes to the content.
migration/c0c1452986b8d4c181bb0c6c83c56a2f-bf22c91488f01ebf503c1786ee805d0c/obelisk-upgradedeleted
No changes to the content.
migration/c106f9398d5c203a1a296b85c7411bf9-1c2c93819c07f33ad899e39ec6769c3c/obelisk-handoffdeleted
No changes to the content.
migration/c106f9398d5c203a1a296b85c7411bf9-1c2c93819c07f33ad899e39ec6769c3c/obelisk-upgradedeleted
No changes to the content.
migration/c118e1ee09ec8d9aa3edf04e211ae035-749df832c9305e1c6309a794b0c1b201/obelisk-handoffdeleted
No changes to the content.
migration/c118e1ee09ec8d9aa3edf04e211ae035-749df832c9305e1c6309a794b0c1b201/obelisk-upgradedeleted
No changes to the content.
migration/c203adc5fed9bf79f67df43d72a4631a-e6980e47ba847245dfab61fb4d5b8ce5/obelisk-handoffdeleted
No changes to the content.
migration/c203adc5fed9bf79f67df43d72a4631a-e6980e47ba847245dfab61fb4d5b8ce5/obelisk-upgradedeleted
No changes to the content.
migration/c2502429502b46133a749f021d188cf0-93f164bbd887f688fd49bb80afffccd6/obelisk-handoffdeleted
No changes to the content.
migration/c2502429502b46133a749f021d188cf0-93f164bbd887f688fd49bb80afffccd6/obelisk-upgradedeleted
No changes to the content.
migration/c2d4eeb20f2b319a2d9dc5b6b0762f83-01c0ee6c93a3f9f69e097c41169927ac/obelisk-handoffdeleted
No changes to the content.
migration/c2d4eeb20f2b319a2d9dc5b6b0762f83-01c0ee6c93a3f9f69e097c41169927ac/obelisk-upgradedeleted
No changes to the content.
migration/c2d581d48dd821a94d7906ca8f33b504-81223455459db28cdbc990c3d4e6eedd/obelisk-handoffdeleted
No changes to the content.
migration/c2d581d48dd821a94d7906ca8f33b504-81223455459db28cdbc990c3d4e6eedd/obelisk-upgradedeleted
No changes to the content.
migration/c3298d81428117be58196b80853e3c7b-f68462dc88ed7fc451d1c757c040cfee/obelisk-handoffdeleted
No changes to the content.
migration/c3298d81428117be58196b80853e3c7b-f68462dc88ed7fc451d1c757c040cfee/obelisk-upgradedeleted
No changes to the content.
migration/c3a8b70b1290031feb21880914cb081e-c2d581d48dd821a94d7906ca8f33b504/obelisk-handoffdeleted
No changes to the content.
migration/c3a8b70b1290031feb21880914cb081e-c2d581d48dd821a94d7906ca8f33b504/obelisk-upgradedeleted
No changes to the content.
migration/c56de2f95c90def16704f62639246bbc-77a721a8fa97d1f84dd2af622089871b/obelisk-handoffdeleted
No changes to the content.
migration/c56de2f95c90def16704f62639246bbc-77a721a8fa97d1f84dd2af622089871b/obelisk-upgradedeleted
No changes to the content.
migration/c5a306045ad998f906f80748fe18487f-e474bad466cd6e413fba753746eb58ef/obelisk-handoffdeleted
No changes to the content.
migration/c5a306045ad998f906f80748fe18487f-e474bad466cd6e413fba753746eb58ef/obelisk-upgradedeleted
No changes to the content.
migration/c66bc5ba27dec52d144ceb0aa429e449-1b1686b03b41bd840ff46776cec7b33a/obelisk-handoffdeleted
No changes to the content.
migration/c66bc5ba27dec52d144ceb0aa429e449-1b1686b03b41bd840ff46776cec7b33a/obelisk-upgradedeleted
No changes to the content.
migration/c67f206b6d2626eb6d36b00122b52784-3bc53f3a28cb8f403cc41c11a37eec5d/obelisk-handoffdeleted
No changes to the content.
migration/c67f206b6d2626eb6d36b00122b52784-3bc53f3a28cb8f403cc41c11a37eec5d/obelisk-upgradedeleted
No changes to the content.
migration/c6baede3962454713b73acefcc92fe75-a96d491705acc139315264fd340d228f/obelisk-handoffdeleted
No changes to the content.
migration/c6baede3962454713b73acefcc92fe75-a96d491705acc139315264fd340d228f/obelisk-upgradedeleted
No changes to the content.
migration/c6f38304ee53762590c67020f30d2ab4-58391ba73c13d922e8a12116b28caad2/obelisk-handoffdeleted
No changes to the content.
migration/c6f38304ee53762590c67020f30d2ab4-58391ba73c13d922e8a12116b28caad2/obelisk-upgradedeleted
No changes to the content.
migration/c7dbf17de8aebd3043617ea6db790dcc-d35f6eb2d1b066d366c9a89ab26144e1/obelisk-handoffdeleted
No changes to the content.
migration/c7dbf17de8aebd3043617ea6db790dcc-d35f6eb2d1b066d366c9a89ab26144e1/obelisk-upgradedeleted
No changes to the content.
migration/c801cbcf925c0a7b084ef152e3c08f8e-8d5dba70e93ae7e784ea238281842408/obelisk-handoffdeleted
No changes to the content.
migration/c801cbcf925c0a7b084ef152e3c08f8e-8d5dba70e93ae7e784ea238281842408/obelisk-upgradedeleted
No changes to the content.
migration/c93529e579e64263fd91663216fd3fe7-12c8a24c34c2d8441f3181d179c2baab/obelisk-handoffdeleted
No changes to the content.
migration/c93529e579e64263fd91663216fd3fe7-12c8a24c34c2d8441f3181d179c2baab/obelisk-upgradedeleted
No changes to the content.
migration/ca5ee8f372ecb07b09283081f0298733-36cdb1c744c3036c2932f01d5fadd9f5/obelisk-handoffdeleted
No changes to the content.
migration/ca5ee8f372ecb07b09283081f0298733-36cdb1c744c3036c2932f01d5fadd9f5/obelisk-upgradedeleted
No changes to the content.
migration/ca88f98cf9fb63d2feaef7fc19b30eca-962e2bd1ae8d0c233f8da89ecebffe50/obelisk-handoffdeleted
No changes to the content.
migration/ca88f98cf9fb63d2feaef7fc19b30eca-962e2bd1ae8d0c233f8da89ecebffe50/obelisk-upgradedeleted
No changes to the content.
migration/cb2197d0267b52385ee39bf4adcfe475-fbe0c6b69a63f3a44109a2c7526bc577/obelisk-handoffdeleted
No changes to the content.
migration/cb2197d0267b52385ee39bf4adcfe475-fbe0c6b69a63f3a44109a2c7526bc577/obelisk-upgradedeleted
No changes to the content.
migration/cb2d040cc16752b1dc89eecf200ea798-5734398c41e4eb5bb58d933ed2e12041/obelisk-handoffdeleted
No changes to the content.
migration/cb2d040cc16752b1dc89eecf200ea798-5734398c41e4eb5bb58d933ed2e12041/obelisk-upgradedeleted
No changes to the content.
migration/cb98f93880e6dea74014976977d6eb93-a7c7b80a875d1863f027c97eb433b884/obelisk-handoffdeleted
No changes to the content.
migration/cb98f93880e6dea74014976977d6eb93-a7c7b80a875d1863f027c97eb433b884/obelisk-upgradedeleted
No changes to the content.
migration/cba28ee4b736cf8ed43cb342ccaef12e-8e01c7fee83aa74229a77772d8c928f3/obelisk-handoffdeleted
No changes to the content.
migration/cba28ee4b736cf8ed43cb342ccaef12e-8e01c7fee83aa74229a77772d8c928f3/obelisk-upgradedeleted
No changes to the content.
migration/cbe155a3e856fb7eaad0bd18feb408be-4c9372bf9aa6ebed1ea20abf3dbb0075/obelisk-handoffdeleted
No changes to the content.
migration/cbe155a3e856fb7eaad0bd18feb408be-4c9372bf9aa6ebed1ea20abf3dbb0075/obelisk-upgradedeleted
No changes to the content.
migration/cc4307fc88e3486b1c3f9ce07db95808-0fba399e046852d4ecf8e1dad831a2f9/obelisk-handoffdeleted
No changes to the content.
migration/cc4307fc88e3486b1c3f9ce07db95808-0fba399e046852d4ecf8e1dad831a2f9/obelisk-upgradedeleted
No changes to the content.
migration/ccadc106cd03c9c32e77457d3adc77a1-aa8e6712fd46824acdea303068634078/obelisk-handoffdeleted
No changes to the content.
migration/ccadc106cd03c9c32e77457d3adc77a1-aa8e6712fd46824acdea303068634078/obelisk-upgradedeleted
No changes to the content.
migration/cccf4140dc336263489bcf67c8c58f86-d50a30fd9643486c5848399d5ba7f1f1/obelisk-handoffdeleted
No changes to the content.
migration/cccf4140dc336263489bcf67c8c58f86-d50a30fd9643486c5848399d5ba7f1f1/obelisk-upgradedeleted
No changes to the content.
migration/cd38e239c47fb92fabd867b7f86fc99a-7447d29f4712c72458c049cdb9380753/obelisk-handoffdeleted
No changes to the content.
migration/cd38e239c47fb92fabd867b7f86fc99a-7447d29f4712c72458c049cdb9380753/obelisk-upgradedeleted
No changes to the content.
migration/cd5b54d21dd0fb868f48624d41021f47-0fe60df438daa8a2cca5f2b569e361a5/obelisk-handoffdeleted
No changes to the content.
migration/cd5b54d21dd0fb868f48624d41021f47-0fe60df438daa8a2cca5f2b569e361a5/obelisk-upgradedeleted
No changes to the content.
migration/cd86427cc2d5b2e931d7ab03deb19d20-bd8f5fa095c3eb19b87d85247b36f1df/obelisk-handoffdeleted
No changes to the content.
migration/cd86427cc2d5b2e931d7ab03deb19d20-bd8f5fa095c3eb19b87d85247b36f1df/obelisk-upgradedeleted
No changes to the content.
migration/ce7f0d15d71d36d4bcf4fbadcdfa1b58-4db97ca86399c557e5ee0d04d0838acc/obelisk-handoffdeleted
No changes to the content.
migration/ce7f0d15d71d36d4bcf4fbadcdfa1b58-4db97ca86399c557e5ee0d04d0838acc/obelisk-upgradedeleted
No changes to the content.
migration/cffcc6cab6080a35b7bf7c5c7facd6bc-5631293b75143d170b8fca5579e15fee/obelisk-handoffdeleted
No changes to the content.
migration/cffcc6cab6080a35b7bf7c5c7facd6bc-5631293b75143d170b8fca5579e15fee/obelisk-upgradedeleted
No changes to the content.
migration/d125109aa22f485d282f6ceb7cd5936e-9b9d73736773550dde7d36de2498b029/obelisk-handoffdeleted
No changes to the content.
migration/d125109aa22f485d282f6ceb7cd5936e-9b9d73736773550dde7d36de2498b029/obelisk-upgradedeleted
No changes to the content.
migration/d16784e9a2d93db7f953941e3003fa8c-a262678b7d849de5a9732d06199666ae/obelisk-handoffdeleted
No changes to the content.
migration/d16784e9a2d93db7f953941e3003fa8c-a262678b7d849de5a9732d06199666ae/obelisk-upgradedeleted
No changes to the content.
migration/d17b41a4669ac17960559614c830d69a-66f7a274206ad9f6d3c5701e4bcffc9d/obelisk-handoffdeleted
No changes to the content.
migration/d17b41a4669ac17960559614c830d69a-66f7a274206ad9f6d3c5701e4bcffc9d/obelisk-upgradedeleted
No changes to the content.
migration/d1b3f5f5375558bf91d55c88547784b9-c0811b664036c7996fcfd19fee241a10/obelisk-handoffdeleted
No changes to the content.
migration/d1b3f5f5375558bf91d55c88547784b9-c0811b664036c7996fcfd19fee241a10/obelisk-upgradedeleted
No changes to the content.
migration/d207ab99328b8ece5fb27fa1f4dbf9f6-e6a85005bd7e5d343bc23e17bfc345f6/obelisk-handoffdeleted
No changes to the content.
migration/d207ab99328b8ece5fb27fa1f4dbf9f6-e6a85005bd7e5d343bc23e17bfc345f6/obelisk-upgradedeleted
No changes to the content.
migration/d2d86ce0ca16b143b49374302a9e9e2f-84f4d5c5491abb855d8dbe3acf3bc8e6/obelisk-handoffdeleted
No changes to the content.
migration/d2d86ce0ca16b143b49374302a9e9e2f-84f4d5c5491abb855d8dbe3acf3bc8e6/obelisk-upgradedeleted
No changes to the content.
migration/d327ceb69d24e40dc11792840454cff9-de469e6488ddf192f2104ec0a030daf7/obelisk-handoffdeleted
No changes to the content.
migration/d327ceb69d24e40dc11792840454cff9-de469e6488ddf192f2104ec0a030daf7/obelisk-upgradedeleted
No changes to the content.
migration/d35f6eb2d1b066d366c9a89ab26144e1-03b9747848d7f3e995b118f776ef96c7/obelisk-handoffdeleted
No changes to the content.
migration/d35f6eb2d1b066d366c9a89ab26144e1-03b9747848d7f3e995b118f776ef96c7/obelisk-upgradedeleted
No changes to the content.
migration/d37d70fe5d7d11e68b59ce12022281c9-5f0d3f7480d67df7deebdb880726b356/obelisk-handoffdeleted
No changes to the content.
migration/d37d70fe5d7d11e68b59ce12022281c9-5f0d3f7480d67df7deebdb880726b356/obelisk-upgradedeleted
No changes to the content.
migration/d40e0e3051a76c4c198cc11c2e8e4b7c-1859cc62bb2f89f528bb2aa170c36e84/obelisk-handoffdeleted
No changes to the content.
migration/d40e0e3051a76c4c198cc11c2e8e4b7c-1859cc62bb2f89f528bb2aa170c36e84/obelisk-upgradedeleted
No changes to the content.
migration/d50a30fd9643486c5848399d5ba7f1f1-1f5b6e2a19c87d3820b953f942ab4a27/obelisk-handoffdeleted
No changes to the content.
migration/d50a30fd9643486c5848399d5ba7f1f1-1f5b6e2a19c87d3820b953f942ab4a27/obelisk-upgradedeleted
No changes to the content.
migration/d532356dfb65a4c8a39452d2ebca2516-bf81caf2a7d528f86acacc1f5d2ffcfa/obelisk-handoffdeleted
No changes to the content.
migration/d532356dfb65a4c8a39452d2ebca2516-bf81caf2a7d528f86acacc1f5d2ffcfa/obelisk-upgradedeleted
No changes to the content.
migration/d5ba6f13296205e5bd88ca2756107df0-26a2491fc8a9658751c1511c777a67bd/obelisk-handoffdeleted
No changes to the content.
migration/d5ba6f13296205e5bd88ca2756107df0-26a2491fc8a9658751c1511c777a67bd/obelisk-upgradedeleted
No changes to the content.
migration/d62d6d443d9c2261b7e09664398aa005-fcc617e973168e1210379a6afe7171be/obelisk-handoffdeleted
No changes to the content.
migration/d62d6d443d9c2261b7e09664398aa005-fcc617e973168e1210379a6afe7171be/obelisk-upgradedeleted
No changes to the content.
migration/d6a3ea5f7eb3c95f5e5ea09fb1330270-bc7688ff47218c0e13d02d917b03caa0/obelisk-handoffdeleted
No changes to the content.
migration/d6a3ea5f7eb3c95f5e5ea09fb1330270-bc7688ff47218c0e13d02d917b03caa0/obelisk-upgradedeleted
No changes to the content.
migration/d6b34eba6ed4f89875a6615fe2c41ec2-3daecb03985f83d8af466a9e0541782b/obelisk-handoffdeleted
No changes to the content.
migration/d6b34eba6ed4f89875a6615fe2c41ec2-3daecb03985f83d8af466a9e0541782b/obelisk-upgradedeleted
No changes to the content.
migration/d6c090699acd25fc60213ff4bd9eebcf-0298e61f6a03e553df08dcef03e27bd1/obelisk-handoffdeleted
No changes to the content.
migration/d6c090699acd25fc60213ff4bd9eebcf-0298e61f6a03e553df08dcef03e27bd1/obelisk-upgradedeleted
No changes to the content.
migration/d6cacd7f4fab95c4b6aa2d6c1a4ad2a0-4d6197d8166de78f882376102e36300b/obelisk-handoffdeleted
No changes to the content.
migration/d6cacd7f4fab95c4b6aa2d6c1a4ad2a0-4d6197d8166de78f882376102e36300b/obelisk-upgradedeleted
No changes to the content.
migration/d747c3d0620b2034aca44265dd1c8c86-eeb970434a53f4883c9f0255db555581/obelisk-handoffdeleted
No changes to the content.
migration/d747c3d0620b2034aca44265dd1c8c86-eeb970434a53f4883c9f0255db555581/obelisk-upgradedeleted
No changes to the content.
migration/d8adb57b2f2266e128ebb6f6d7e65920-ccadc106cd03c9c32e77457d3adc77a1/obelisk-handoffdeleted
No changes to the content.
migration/d8adb57b2f2266e128ebb6f6d7e65920-ccadc106cd03c9c32e77457d3adc77a1/obelisk-upgradedeleted
No changes to the content.
migration/da23605ee4058c8474687e74a3999354-dfd7dbceea141c60bbfca962d50c1c06/obelisk-handoffdeleted
No changes to the content.
migration/da23605ee4058c8474687e74a3999354-dfd7dbceea141c60bbfca962d50c1c06/obelisk-upgradedeleted
No changes to the content.
migration/db327f87e60d4e59bdbfd482e5abe985-eb99c1a66237ba99cd1f6d244cafb9cc/obelisk-handoffdeleted
No changes to the content.
migration/db327f87e60d4e59bdbfd482e5abe985-eb99c1a66237ba99cd1f6d244cafb9cc/obelisk-upgradedeleted
No changes to the content.
migration/dc95f39fb27634ccbca7318ff2065608-0fb3a912a8aaf5ef6f734a25f0bce7e2/obelisk-handoffdeleted
No changes to the content.
migration/dc95f39fb27634ccbca7318ff2065608-0fb3a912a8aaf5ef6f734a25f0bce7e2/obelisk-upgradedeleted
No changes to the content.
migration/dd6ca52a58ea6cda7b3eaa2e87bb13d9-a6d50c7e756dfd1e3ae891111b81a1ae/obelisk-handoffdeleted
No changes to the content.
migration/dd6ca52a58ea6cda7b3eaa2e87bb13d9-a6d50c7e756dfd1e3ae891111b81a1ae/obelisk-upgradedeleted
No changes to the content.
migration/ddaa8e0e42a1ef00154d580a390c9f17-53d29061537ddaf7530aef88624ab266/obelisk-handoffdeleted
No changes to the content.
migration/ddaa8e0e42a1ef00154d580a390c9f17-53d29061537ddaf7530aef88624ab266/obelisk-upgradedeleted
No changes to the content.
migration/de469e6488ddf192f2104ec0a030daf7-3da7d4a3b507d18097a90becf4dde9aa/obelisk-handoffdeleted
No changes to the content.
migration/de469e6488ddf192f2104ec0a030daf7-3da7d4a3b507d18097a90becf4dde9aa/obelisk-upgradedeleted
No changes to the content.
migration/df71cd82e801ca701bf4bc44b80b6d50-f423ecd4d096de9dca37a67b8b4143eb/obelisk-handoffdeleted
No changes to the content.
migration/df71cd82e801ca701bf4bc44b80b6d50-f423ecd4d096de9dca37a67b8b4143eb/obelisk-upgradedeleted
No changes to the content.
migration/dfd7dbceea141c60bbfca962d50c1c06-030ed18dacf3571cbb9e3e7d9d99627b/obelisk-handoffdeleted
No changes to the content.
migration/dfd7dbceea141c60bbfca962d50c1c06-030ed18dacf3571cbb9e3e7d9d99627b/obelisk-upgradedeleted
No changes to the content.
migration/e01cc01684deaf4c75ad5d65270bf3d5-c7dbf17de8aebd3043617ea6db790dcc/obelisk-handoffdeleted
No changes to the content.
migration/e01cc01684deaf4c75ad5d65270bf3d5-c7dbf17de8aebd3043617ea6db790dcc/obelisk-upgradedeleted
No changes to the content.
migration/e1ef432db54d9a6daa9bdeeb543262ae-2ba356b187db8db13b8aa40f43ca025f/obelisk-handoffdeleted
No changes to the content.
migration/e1ef432db54d9a6daa9bdeeb543262ae-2ba356b187db8db13b8aa40f43ca025f/obelisk-upgradedeleted
No changes to the content.
migration/e22c51145e08d4a089003460ae80a7f9-42357310c09e345f9360259c6c4102f2/obelisk-handoffdeleted
No changes to the content.
migration/e22c51145e08d4a089003460ae80a7f9-42357310c09e345f9360259c6c4102f2/obelisk-upgradedeleted
No changes to the content.
migration/e24a771ee59f24e45afc0a27307f2070-2eb907820012f77e60350430d89631fe/obelisk-handoffdeleted
No changes to the content.
migration/e24a771ee59f24e45afc0a27307f2070-2eb907820012f77e60350430d89631fe/obelisk-upgradedeleted
No changes to the content.
migration/e2706f337218a12a3bdddd18fa3f4cfd-475f9a0d63e84e9cf13b8be3986cb603/obelisk-handoffdeleted
No changes to the content.
migration/e2706f337218a12a3bdddd18fa3f4cfd-475f9a0d63e84e9cf13b8be3986cb603/obelisk-upgradedeleted
No changes to the content.
migration/e2b2d878b0ba6eb653b194523bf0a0e0-5f307639ccf6a64309166bfe58037397/obelisk-handoffdeleted
No changes to the content.
migration/e2b2d878b0ba6eb653b194523bf0a0e0-5f307639ccf6a64309166bfe58037397/obelisk-upgradedeleted
No changes to the content.
migration/e2be519915794ef130249f2be7640382-455279b6974b96a673613cd0ccc8ed54/obelisk-handoffdeleted
No changes to the content.
migration/e2be519915794ef130249f2be7640382-455279b6974b96a673613cd0ccc8ed54/obelisk-upgradedeleted
No changes to the content.
migration/e323ce1352e512109f1609276fb509b4-2c1521e5a5be64e6d28a9fdae950cd76/obelisk-handoffdeleted
No changes to the content.
migration/e323ce1352e512109f1609276fb509b4-2c1521e5a5be64e6d28a9fdae950cd76/obelisk-upgradedeleted
No changes to the content.
migration/e327773e1525eaa1eb2112dff8f41b26-f595b01939b4c87b7c146ea9ff331b39/obelisk-handoffdeleted
No changes to the content.
migration/e327773e1525eaa1eb2112dff8f41b26-f595b01939b4c87b7c146ea9ff331b39/obelisk-upgradedeleted
No changes to the content.
migration/e3b3014d7e0dc983fe118d32546654e5-063665b78b6705e7de952f73fa9797bf/obelisk-handoffdeleted
No changes to the content.
migration/e3b3014d7e0dc983fe118d32546654e5-063665b78b6705e7de952f73fa9797bf/obelisk-upgradedeleted
No changes to the content.
migration/e4051219d89b3c9a8350fe824ad96a82-166c5f8e4a0f1dfd227b075a96237386/obelisk-handoffdeleted
No changes to the content.
migration/e4051219d89b3c9a8350fe824ad96a82-166c5f8e4a0f1dfd227b075a96237386/obelisk-upgradedeleted
No changes to the content.
migration/e4513b485b6ba8b7f4bd34b12458ff0c-3c80eccfe80d0abd36b07bb11e69fc7a/obelisk-handoffdeleted
No changes to the content.
migration/e4513b485b6ba8b7f4bd34b12458ff0c-3c80eccfe80d0abd36b07bb11e69fc7a/obelisk-upgradedeleted
No changes to the content.
migration/e474bad466cd6e413fba753746eb58ef-f19b3699616f3b1de3a277f9cba617c7/obelisk-handoffdeleted
No changes to the content.
migration/e474bad466cd6e413fba753746eb58ef-f19b3699616f3b1de3a277f9cba617c7/obelisk-upgradedeleted
No changes to the content.
migration/e4b89dd259f3831bc60b56147b3586a6-98da197f133bca81e533ab5ffbf4c82d/obelisk-handoffdeleted
No changes to the content.
migration/e4b89dd259f3831bc60b56147b3586a6-98da197f133bca81e533ab5ffbf4c82d/obelisk-upgradedeleted
No changes to the content.
migration/e609d945b642fd9d4ce99931e3699db7-85c2c4fb8472d50eaa97aed0bdc9b142/obelisk-handoffdeleted
No changes to the content.
migration/e609d945b642fd9d4ce99931e3699db7-85c2c4fb8472d50eaa97aed0bdc9b142/obelisk-upgradedeleted
No changes to the content.
migration/e6980e47ba847245dfab61fb4d5b8ce5-58f9d23d2cede2081dc6f6cfa2283f60/obelisk-handoffdeleted
No changes to the content.
migration/e6980e47ba847245dfab61fb4d5b8ce5-58f9d23d2cede2081dc6f6cfa2283f60/obelisk-upgradedeleted
No changes to the content.
migration/e6a85005bd7e5d343bc23e17bfc345f6-98f9e0bbd21e36b0f4daa440d11e7177/obelisk-handoffdeleted
No changes to the content.
migration/e6a85005bd7e5d343bc23e17bfc345f6-98f9e0bbd21e36b0f4daa440d11e7177/obelisk-upgradedeleted
No changes to the content.
migration/e7288bb723a4e5b7139ac67842963287-7b75ffdcd86b5a330d9c325ad5767393/obelisk-handoffdeleted
No changes to the content.
migration/e7288bb723a4e5b7139ac67842963287-7b75ffdcd86b5a330d9c325ad5767393/obelisk-upgradedeleted
No changes to the content.
migration/e7385c9eae2b807a483b73be4295b207-fb02559b6f723d599e12931a81be3a1b/obelisk-handoffdeleted
No changes to the content.
migration/e7385c9eae2b807a483b73be4295b207-fb02559b6f723d599e12931a81be3a1b/obelisk-upgradedeleted
No changes to the content.
migration/e7667778f2ab3055aa3ccc68443d14df-7adece557941a7d7ac7c150f77f758be/obelisk-handoffdeleted
No changes to the content.
migration/e7667778f2ab3055aa3ccc68443d14df-7adece557941a7d7ac7c150f77f758be/obelisk-upgradedeleted
No changes to the content.
migration/e78ec85bec14f4784faeef4d8d3e4d0a-e7667778f2ab3055aa3ccc68443d14df/obelisk-handoffdeleted
No changes to the content.
migration/e78ec85bec14f4784faeef4d8d3e4d0a-e7667778f2ab3055aa3ccc68443d14df/obelisk-upgradedeleted
No changes to the content.
migration/e7b17aa124e17c357cead8081a58f089-ac5e28caddd6832d0bf1f7445a4a6a28/obelisk-handoffdeleted
No changes to the content.
migration/e7b17aa124e17c357cead8081a58f089-ac5e28caddd6832d0bf1f7445a4a6a28/obelisk-upgradedeleted
No changes to the content.
migration/e7b566495114e160f1f4d722b7ed8174-7cf814f7404638f1c1be662a24d7cfea/obelisk-handoffdeleted
No changes to the content.
migration/e7b566495114e160f1f4d722b7ed8174-7cf814f7404638f1c1be662a24d7cfea/obelisk-upgradedeleted
No changes to the content.
migration/e92786eaf56c32fd6b452c4a841d6317-f24a7fb6e3261c4919ea2a2fee83ed6b/obelisk-handoffdeleted
No changes to the content.
migration/e92786eaf56c32fd6b452c4a841d6317-f24a7fb6e3261c4919ea2a2fee83ed6b/obelisk-upgradedeleted
No changes to the content.
migration/e9ec84bfe7099b713c0fda32308f5815-f0a064ca5f709233204168c136b99a7e/obelisk-handoffdeleted
No changes to the content.
migration/e9ec84bfe7099b713c0fda32308f5815-f0a064ca5f709233204168c136b99a7e/obelisk-upgradedeleted
No changes to the content.
migration/eb99c1a66237ba99cd1f6d244cafb9cc-da23605ee4058c8474687e74a3999354/obelisk-handoffdeleted
No changes to the content.
migration/eb99c1a66237ba99cd1f6d244cafb9cc-da23605ee4058c8474687e74a3999354/obelisk-upgradedeleted
No changes to the content.
migration/ebb95c5864d1d1d2f78fbf7cc8235dac-ba4829dc61dcc12bcafd8de5fc8a76dc/obelisk-handoffdeleted
No changes to the content.
migration/ebb95c5864d1d1d2f78fbf7cc8235dac-ba4829dc61dcc12bcafd8de5fc8a76dc/obelisk-upgradedeleted
No changes to the content.
migration/ec11d10a6131abca9222a8f8026fb5e4-f3d494ffee7091cd588bbdd2fd9bcdf9/obelisk-handoffdeleted
No changes to the content.
migration/ec11d10a6131abca9222a8f8026fb5e4-f3d494ffee7091cd588bbdd2fd9bcdf9/obelisk-upgradedeleted
No changes to the content.
migration/ec94619fa3f25db1ca84d179e47db1ca-23af4d9671962484de53f537a0626d83/obelisk-handoffdeleted
No changes to the content.
migration/ec94619fa3f25db1ca84d179e47db1ca-23af4d9671962484de53f537a0626d83/obelisk-upgradedeleted
No changes to the content.
migration/ed95a99cdde4adc90c6a8e2de82410eb-1c4fc23cbf5653613c6060668e065f37/obelisk-handoffdeleted
No changes to the content.
migration/ed95a99cdde4adc90c6a8e2de82410eb-1c4fc23cbf5653613c6060668e065f37/obelisk-upgradedeleted
No changes to the content.
migration/ee3dccc89ea6fdaaf9c1146b92861e90-f3eac05465851232f8174a7a347d1c4b/obelisk-handoffdeleted
No changes to the content.
migration/ee3dccc89ea6fdaaf9c1146b92861e90-f3eac05465851232f8174a7a347d1c4b/obelisk-upgradedeleted
No changes to the content.
migration/eeb970434a53f4883c9f0255db555581-a2b33f8dc1f90b8dddce942b174be5b8/obelisk-handoffdeleted
No changes to the content.
migration/eeb970434a53f4883c9f0255db555581-a2b33f8dc1f90b8dddce942b174be5b8/obelisk-upgradedeleted
No changes to the content.
migration/ef33c06500054e09c97eee9e9c55485a-367616bd36eda757f251a5e8e9096acc/obelisk-handoffdeleted
No changes to the content.
migration/ef33c06500054e09c97eee9e9c55485a-367616bd36eda757f251a5e8e9096acc/obelisk-upgradedeleted
No changes to the content.
migration/ef6aebc8cba2af6c4f930c981b06e8ac-d17b41a4669ac17960559614c830d69a/obelisk-handoffdeleted
No changes to the content.
migration/ef6aebc8cba2af6c4f930c981b06e8ac-d17b41a4669ac17960559614c830d69a/obelisk-upgradedeleted
No changes to the content.
migration/f0a064ca5f709233204168c136b99a7e-ef6aebc8cba2af6c4f930c981b06e8ac/obelisk-handoffdeleted
No changes to the content.
migration/f0a064ca5f709233204168c136b99a7e-ef6aebc8cba2af6c4f930c981b06e8ac/obelisk-upgradedeleted
No changes to the content.
migration/f15c9c2f894c8cc4fac07e2cdef47180-94252585266fa745a91733888e2f50b7/obelisk-handoffdeleted
No changes to the content.
migration/f15c9c2f894c8cc4fac07e2cdef47180-94252585266fa745a91733888e2f50b7/obelisk-upgradedeleted
No changes to the content.
migration/f19b3699616f3b1de3a277f9cba617c7-4d85ee8cdb0db20a5662b09567a2bbe7/obelisk-handoffdeleted
No changes to the content.
migration/f19b3699616f3b1de3a277f9cba617c7-4d85ee8cdb0db20a5662b09567a2bbe7/obelisk-upgradedeleted
No changes to the content.
migration/f24a7fb6e3261c4919ea2a2fee83ed6b-f913f01e90549c56a8b05f8100cfa21d/obelisk-handoffdeleted
No changes to the content.
migration/f24a7fb6e3261c4919ea2a2fee83ed6b-f913f01e90549c56a8b05f8100cfa21d/obelisk-upgradedeleted
No changes to the content.
migration/f2a9ba4a93c3a04acbee2211bca9e27a-ec94619fa3f25db1ca84d179e47db1ca/obelisk-handoffdeleted
No changes to the content.
migration/f2a9ba4a93c3a04acbee2211bca9e27a-ec94619fa3f25db1ca84d179e47db1ca/obelisk-upgradedeleted
No changes to the content.
migration/f391c6a74ee14217ce4565c278fceed6-e7288bb723a4e5b7139ac67842963287/obelisk-handoffdeleted
No changes to the content.
migration/f391c6a74ee14217ce4565c278fceed6-e7288bb723a4e5b7139ac67842963287/obelisk-upgradedeleted
No changes to the content.
migration/f3d494ffee7091cd588bbdd2fd9bcdf9-b68a785fbf27a63334ef1d1fe82b2dac/obelisk-handoffdeleted
No changes to the content.
migration/f3d494ffee7091cd588bbdd2fd9bcdf9-b68a785fbf27a63334ef1d1fe82b2dac/obelisk-upgradedeleted
No changes to the content.
migration/f3eac05465851232f8174a7a347d1c4b-1629d0d70e360df6b2280fac36d21e8a/obelisk-handoffdeleted
No changes to the content.
migration/f3eac05465851232f8174a7a347d1c4b-1629d0d70e360df6b2280fac36d21e8a/obelisk-upgradedeleted
No changes to the content.
migration/f3ec62d09836804e39fad9d814137845-ef33c06500054e09c97eee9e9c55485a/obelisk-handoffdeleted
No changes to the content.
migration/f3ec62d09836804e39fad9d814137845-ef33c06500054e09c97eee9e9c55485a/obelisk-upgradedeleted
No changes to the content.
migration/f41b690c74938e347cf042cee2d4fc72-7fc381538805adac19c54b73ea118601/obelisk-handoffdeleted
No changes to the content.
migration/f41b690c74938e347cf042cee2d4fc72-7fc381538805adac19c54b73ea118601/obelisk-upgradedeleted
No changes to the content.
migration/f423ecd4d096de9dca37a67b8b4143eb-469a31d20d69da72e6a3a3ea2bb02f9d/obelisk-handoffdeleted
No changes to the content.
migration/f423ecd4d096de9dca37a67b8b4143eb-469a31d20d69da72e6a3a3ea2bb02f9d/obelisk-upgradedeleted
No changes to the content.
migration/f595b01939b4c87b7c146ea9ff331b39-4da182e21be35feeee484dc85be7a075/obelisk-handoffdeleted
No changes to the content.
migration/f595b01939b4c87b7c146ea9ff331b39-4da182e21be35feeee484dc85be7a075/obelisk-upgradedeleted
No changes to the content.
migration/f68462dc88ed7fc451d1c757c040cfee-589eb89cdb09655c5edde4cd2a4deb80/obelisk-handoffdeleted
No changes to the content.
migration/f68462dc88ed7fc451d1c757c040cfee-589eb89cdb09655c5edde4cd2a4deb80/obelisk-upgradedeleted
No changes to the content.
migration/f790ac9400501511b4ee045e22bc5fe1-a826f01311fe00ef5cf87568832605d3/obelisk-handoffdeleted
No changes to the content.
migration/f790ac9400501511b4ee045e22bc5fe1-a826f01311fe00ef5cf87568832605d3/obelisk-upgradedeleted
No changes to the content.
migration/f8e51a9e8ac6598f7c073b09e4ba09b5-ff57aebc7325bd7e02b436fec79e799c/obelisk-handoffdeleted
No changes to the content.
migration/f8e51a9e8ac6598f7c073b09e4ba09b5-ff57aebc7325bd7e02b436fec79e799c/obelisk-upgradedeleted
No changes to the content.
migration/f8eee9431c8b7a767d96da0a8cfae95d-9e05cc6b81c6380ba0ac59bad1021cac/obelisk-handoffdeleted
No changes to the content.
migration/f8eee9431c8b7a767d96da0a8cfae95d-9e05cc6b81c6380ba0ac59bad1021cac/obelisk-upgradedeleted
No changes to the content.
migration/f913f01e90549c56a8b05f8100cfa21d-001efbbe866b66eebc6ee1ea0a906f2d/obelisk-handoffdeleted
No changes to the content.
migration/f913f01e90549c56a8b05f8100cfa21d-001efbbe866b66eebc6ee1ea0a906f2d/obelisk-upgradedeleted
No changes to the content.
migration/f9716ad47c84e0b7ac7d426e8ad059f3-ec11d10a6131abca9222a8f8026fb5e4/obelisk-handoffdeleted
No changes to the content.
migration/f9716ad47c84e0b7ac7d426e8ad059f3-ec11d10a6131abca9222a8f8026fb5e4/obelisk-upgradedeleted
No changes to the content.
migration/f98b82f5d142ce83733a3f18bdacb138-35acc1e0c4d9c02d60abd116f3df84ee/obelisk-handoffdeleted
No changes to the content.
migration/f98b82f5d142ce83733a3f18bdacb138-35acc1e0c4d9c02d60abd116f3df84ee/obelisk-upgradedeleted
No changes to the content.
migration/f9ad863c0bebc103f8b81afdf82e6293-c6f38304ee53762590c67020f30d2ab4/obelisk-handoffdeleted
No changes to the content.
migration/f9ad863c0bebc103f8b81afdf82e6293-c6f38304ee53762590c67020f30d2ab4/obelisk-upgradedeleted
No changes to the content.
migration/fa18f7522903a21b615dbee24c26bfbe-0535e06dd0d61f3e6970b491a17cf1f8/obelisk-handoffdeleted
No changes to the content.
migration/fa18f7522903a21b615dbee24c26bfbe-0535e06dd0d61f3e6970b491a17cf1f8/obelisk-upgradedeleted
No changes to the content.
migration/fb02559b6f723d599e12931a81be3a1b-71a47d4d6856c1956c0d1c9de9af231f/obelisk-handoffdeleted
No changes to the content.
migration/fb02559b6f723d599e12931a81be3a1b-71a47d4d6856c1956c0d1c9de9af231f/obelisk-upgradedeleted
No changes to the content.
migration/fb374b0721716a1e849e64daf6da73c4-f8e51a9e8ac6598f7c073b09e4ba09b5/obelisk-handoffdeleted
No changes to the content.
migration/fb374b0721716a1e849e64daf6da73c4-f8e51a9e8ac6598f7c073b09e4ba09b5/obelisk-upgradedeleted
No changes to the content.
migration/fb5110e527cf77c568bcae7d435ee035-53fdf819333b86dfb485bf16a8f28db2/obelisk-handoffdeleted
No changes to the content.
migration/fb5110e527cf77c568bcae7d435ee035-53fdf819333b86dfb485bf16a8f28db2/obelisk-upgradedeleted
No changes to the content.
migration/fb81153791e49cd00850e91ff7418018-9b33a49f0c978e27b752fa457aca97cc/obelisk-handoffdeleted
No changes to the content.
migration/fb81153791e49cd00850e91ff7418018-9b33a49f0c978e27b752fa457aca97cc/obelisk-upgradedeleted
No changes to the content.
migration/fbb3eb3209281031dc5183d289eb4e75-8c7718f94e2676c957fe844b7dc2637c/obelisk-handoffdeleted
No changes to the content.
migration/fbb3eb3209281031dc5183d289eb4e75-8c7718f94e2676c957fe844b7dc2637c/obelisk-upgradedeleted
No changes to the content.
migration/fbe0c6b69a63f3a44109a2c7526bc577-c3a8b70b1290031feb21880914cb081e/obelisk-handoffdeleted
No changes to the content.
migration/fbe0c6b69a63f3a44109a2c7526bc577-c3a8b70b1290031feb21880914cb081e/obelisk-upgradedeleted
No changes to the content.
migration/fc42c5fc24031fc6a8836a10cfb45143-d125109aa22f485d282f6ceb7cd5936e/obelisk-handoffdeleted
No changes to the content.
migration/fc42c5fc24031fc6a8836a10cfb45143-d125109aa22f485d282f6ceb7cd5936e/obelisk-upgradedeleted
No changes to the content.
migration/fca48edfdaa31b036176b97b04384682-2df092178e167b474dd08dfa46ec3a49/obelisk-handoffdeleted
No changes to the content.
migration/fca48edfdaa31b036176b97b04384682-2df092178e167b474dd08dfa46ec3a49/obelisk-upgradedeleted
No changes to the content.
migration/fcc617e973168e1210379a6afe7171be-ed95a99cdde4adc90c6a8e2de82410eb/obelisk-handoffdeleted
No changes to the content.
migration/fcc617e973168e1210379a6afe7171be-ed95a99cdde4adc90c6a8e2de82410eb/obelisk-upgradedeleted
No changes to the content.
migration/ff1105290f89350bc9deb6eb907e0a53-0c991bc3c06801f72df48486ee78e350/obelisk-handoffdeleted
No changes to the content.
migration/ff1105290f89350bc9deb6eb907e0a53-0c991bc3c06801f72df48486ee78e350/obelisk-upgradedeleted
No changes to the content.
migration/ff57aebc7325bd7e02b436fec79e799c-9f71fc9d2ed805fecbc8c4a3aae5685b/obelisk-handoffdeleted
No changes to the content.
migration/ff57aebc7325bd7e02b436fec79e799c-9f71fc9d2ed805fecbc8c4a3aae5685b/obelisk-upgradedeleted
No changes to the content.
migration/ffa62158ed6fdece012980e4ad25e6ac-959ae2925bcd2b5beff631a8e7aeaf00/obelisk-handoffdeleted
No changes to the content.
migration/ffa62158ed6fdece012980e4ad25e6ac-959ae2925bcd2b5beff631a8e7aeaf00/obelisk-upgradedeleted
No changes to the content.