11import asyncio
2+ import fileinput
23import logging
34import os
45from dataclasses import dataclass
56from functools import wraps
67from os .path import dirname , join
7- from typing import List
8+ from typing import List , NoReturn
89
910import click
1011from fcache .cache import FileCache # type: ignore
1112
12- from dipdup import __version__
13+ from dipdup import __spec_version__ , __version__
1314from dipdup .config import DipDupConfig , LoggingConfig
1415from dipdup .dipdup import DipDup
15- from dipdup .exceptions import HandlerImportError
1616
1717_logger = logging .getLogger (__name__ )
1818
19+ spec_version_to_version = {
20+ '0.1' : 'dipdup <0.4.3' ,
21+ '1.0' : 'dipdup ^1.0.0' ,
22+ }
23+
24+ migration_required_message = """
25+
26+ Migration required!
27+
28+ project spec version: %s (%s)
29+ current spec version: %s (%s)
30+
31+ 1. Run `dipdup migrate`
32+ 2. Review and commit changes
33+
34+ See https://baking-bad.org/blog/ for additional release information.
35+ """
36+
37+
38+ def migration_required (from_ : str , to : str ) -> NoReturn :
39+ _logger .warning (
40+ migration_required_message ,
41+ from_ ,
42+ spec_version_to_version [from_ ],
43+ to ,
44+ spec_version_to_version [to ],
45+ )
46+ quit ()
47+
1948
2049def click_async (fn ):
2150 @wraps (fn )
@@ -27,6 +56,7 @@ def wrapper(*args, **kwargs):
2756
2857@dataclass
2958class CLIContext :
59+ config_paths : List [str ]
3060 config : DipDupConfig
3161 logging_config : LoggingConfig
3262
@@ -45,8 +75,13 @@ async def cli(ctx, config: List[str], logging_config: str):
4575 path = join (dirname (__file__ ), 'configs' , logging_config )
4676 _logging_config = LoggingConfig .load (path )
4777 _logging_config .apply ()
78+
4879 _config = DipDupConfig .load (config )
80+ if _config .spec_version != __spec_version__ and ctx .invoked_subcommand != 'migrate' :
81+ migration_required (_config .spec_version , __spec_version__ )
82+
4983 ctx .obj = CLIContext (
84+ config_paths = config ,
5085 config = _config ,
5186 logging_config = _logging_config ,
5287 )
@@ -59,12 +94,7 @@ async def cli(ctx, config: List[str], logging_config: str):
5994@click_async
6095async def run (ctx , reindex : bool , oneshot : bool ) -> None :
6196 config : DipDupConfig = ctx .obj .config
62-
63- try :
64- config .initialize ()
65- except HandlerImportError :
66- await DipDup (config ).migrate ()
67-
97+ config .initialize ()
6898 dipdup = DipDup (config )
6999 await dipdup .run (reindex , oneshot )
70100
@@ -79,6 +109,22 @@ async def init(ctx):
79109 await dipdup .init ()
80110
81111
112+ @cli .command (help = 'Migrate project to the new spec version' )
113+ @click .pass_context
114+ @click_async
115+ async def migrate (ctx ):
116+ config : DipDupConfig = ctx .obj .config
117+ config .pre_initialize ()
118+ await DipDup (config ).migrate ()
119+
120+ for config_path in ctx .obj .config_paths :
121+ for line in fileinput .input (config_path , inplace = True ):
122+ if 'spec_version' in line :
123+ print (f'spec_version: { __spec_version__ } ' )
124+ else :
125+ print (line .rstrip ())
126+
127+
82128@cli .command (help = 'Clear development request cache' )
83129@click .pass_context
84130@click_async
0 commit comments