Skip to content

Commit

Permalink
fix migration lru (#15135)
Browse files Browse the repository at this point in the history
* fix migration lru

* fix back migration
  • Loading branch information
memsharded authored Dec 14, 2023
1 parent c655809 commit 0843372
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 31 deletions.
52 changes: 29 additions & 23 deletions conan/api/subapi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,32 +46,38 @@ def global_conf(self):
to the profile ones and passed to the conanfiles.conf, which can be passed to collaborators
"""
if self._new_config is None:
self._new_config = ConfDefinition()
cache_folder = self.conan_api.cache_folder
home_paths = HomePaths(cache_folder)
global_conf_path = home_paths.global_conf_path
if os.path.exists(global_conf_path):
text = load(global_conf_path)
distro = None
if platform.system() in ["Linux", "FreeBSD"]:
import distro
template = Environment(loader=FileSystemLoader(cache_folder)).from_string(text)
content = template.render({"platform": platform, "os": os, "distro": distro,
"conan_version": conan_version,
"conan_home_folder": cache_folder,
"detect_api": detect_api})
self._new_config.loads(content)
else: # creation of a blank global.conf file for user convenience
default_global_conf = textwrap.dedent("""\
# Core configuration (type 'conan config list' to list possible values)
# e.g, for CI systems, to raise if user input would block
# core:non_interactive = True
# some tools.xxx config also possible, though generally better in profiles
# tools.android:ndk_path = my/path/to/android/ndk
""")
save(global_conf_path, default_global_conf)
self._new_config = self.load_config(cache_folder)
return self._new_config

@staticmethod
def load_config(home_folder):
# Do not document yet, keep it private
home_paths = HomePaths(home_folder)
global_conf_path = home_paths.global_conf_path
new_config = ConfDefinition()
if os.path.exists(global_conf_path):
text = load(global_conf_path)
distro = None
if platform.system() in ["Linux", "FreeBSD"]:
import distro
template = Environment(loader=FileSystemLoader(home_folder)).from_string(text)
content = template.render({"platform": platform, "os": os, "distro": distro,
"conan_version": conan_version,
"conan_home_folder": home_folder,
"detect_api": detect_api})
new_config.loads(content)
else: # creation of a blank global.conf file for user convenience
default_global_conf = textwrap.dedent("""\
# Core configuration (type 'conan config list' to list possible values)
# e.g, for CI systems, to raise if user input would block
# core:non_interactive = True
# some tools.xxx config also possible, though generally better in profiles
# tools.android:ndk_path = my/path/to/android/ndk
""")
save(global_conf_path, default_global_conf)
return new_config

@property
def builtin_confs(self):
return BUILT_IN_CONFS
Expand Down
31 changes: 27 additions & 4 deletions conans/client/migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import textwrap

from conan.api.output import ConanOutput
from conan.api.subapi.config import ConfigAPI
from conans.migrations import Migrator
from conans.util.dates import timestamp_now
from conans.util.files import load, save
Expand Down Expand Up @@ -59,7 +60,9 @@ def _apply_migrations(self, old_version):
def _migrate_pkg_db_lru(cache_folder, old_version):
ConanOutput().warning(f"Upgrade cache from Conan version '{old_version}'")
ConanOutput().warning("Running 2.0.14 Cache DB migration to add LRU column")
db_filename = os.path.join(cache_folder, 'p', 'cache.sqlite3')
config = ConfigAPI.load_config(cache_folder)
storage = config.get("core.cache:storage_path") or os.path.join(cache_folder, "p")
db_filename = os.path.join(storage, 'cache.sqlite3')
connection = sqlite3.connect(db_filename, isolation_level=None,
timeout=1, check_same_thread=False)
try:
Expand All @@ -73,10 +76,30 @@ def _migrate_pkg_db_lru(cache_folder, old_version):
raise
else: # generate the back-migration script
undo_lru = textwrap.dedent("""\
import os
import os, platform
import sqlite3
def migrate(cache_folder):
db = os.path.join(cache_folder, 'p', 'cache.sqlite3')
from jinja2 import Environment, FileSystemLoader
from conan import conan_version
from conan.internal.api import detect_api
from conans.model.conf import ConfDefinition
def migrate(home_folder):
config = os.path.join(home_folder, "global.conf")
global_conf = open(config, "r").read() if os.path.isfile(config) else ""
distro = None
if platform.system() in ["Linux", "FreeBSD"]:
import distro
template = Environment(loader=FileSystemLoader(home_folder)).from_string(global_conf)
content = template.render({"platform": platform, "os": os, "distro": distro,
"conan_version": conan_version,
"conan_home_folder": home_folder,
"detect_api": detect_api})
conf = ConfDefinition()
conf.loads(content)
storage = conf.get("core.cache:storage_path") or os.path.join(home_folder, "p")
db = os.path.join(storage, 'cache.sqlite3')
connection = sqlite3.connect(db, isolation_level=None, timeout=1,
check_same_thread=False)
rec_cols = 'reference, rrev, path, timestamp'
Expand Down
30 changes: 26 additions & 4 deletions conans/test/integration/test_migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
import pytest

from conan import conan_version
from conans.test.assets.genconanfile import GenConanfile
from conans.test.utils.test_files import temp_folder
from conans.test.utils.tools import TestClient
from conans.util.files import save, load


def _drop_lru_column(cache_folder):
db = os.path.join(cache_folder, 'p', 'cache.sqlite3')
def _drop_lru_column(db_folder):
db = os.path.join(db_folder, "cache.sqlite3")
connection = sqlite3.connect(db, isolation_level=None, timeout=1, check_same_thread=False)
rec_cols = 'reference, rrev, path, timestamp'
pkg_cols = 'reference, rrev, pkgid, prev, path, timestamp, build_id'
Expand Down Expand Up @@ -39,7 +41,8 @@ def test_migration_profile_checker_plugin(plugin_path, string_replace, new_strin
# Let's change the version
version_txt_file_path = os.path.join(t.cache_folder, "version.txt")
save(version_txt_file_path, "1.0.0")
_drop_lru_column(t.cache_folder)
db = os.path.join(t.cache_folder, 'p')
_drop_lru_column(db)

# Do a modification to the profile plugin without changing the comment
contents = contents.replace(string_replace, new_string)
Expand Down Expand Up @@ -70,7 +73,8 @@ def test_migration_profile_checker_plugin(plugin_path, string_replace, new_strin
# Let's change the version
version_txt_file_path2 = os.path.join(t2.cache_folder, "version.txt")
save(version_txt_file_path2, "1.0.0")
_drop_lru_column(t2.cache_folder)
db = os.path.join(t2.cache_folder, 'p')
_drop_lru_column(db)
# Trigger the migrations
t2.run("-v")
assert "WARN: Running 2.0.14 Cache DB migration to add LRU column" in t2.out
Expand All @@ -82,6 +86,24 @@ def test_migration_profile_checker_plugin(plugin_path, string_replace, new_strin
assert new_string in contents


def test_migration_db_lru():
t = TestClient()
storage = temp_folder()
save(t.cache.global_conf_path, f"core.cache:storage_path={storage}")
t.save({"conanfile.py": GenConanfile("pkg", "0.1")})
t.run("create .")
# Any command generates the profile and compatibility plugin files
# Let's change the version
version_txt_file_path = os.path.join(t.cache_folder, "version.txt")
save(version_txt_file_path, "1.0.0")
_drop_lru_column(storage)

# Trigger the migrations
t.run("list *")
assert "WARN: Running 2.0.14 Cache DB migration to add LRU column" in t.out
assert "pkg/0.1" in t.out


def test_back_migrations():
t = TestClient()

Expand Down

0 comments on commit 0843372

Please sign in to comment.