Skip to content

Commit

Permalink
Fix/build id error (#14555)
Browse files Browse the repository at this point in the history
* wip

* wip

* fixed problem
  • Loading branch information
memsharded authored Aug 24, 2023
1 parent 76719ef commit f595556
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 232 deletions.
2 changes: 2 additions & 0 deletions conan/api/subapi/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ def clean(self, package_list, source=True, build=True, download=True, temp=True)
pref_layout = app.cache.pkg_layout(pref)
if build:
rmdir(pref_layout.build())
# It is important to remove the "build_id" identifier if build-folder is removed
app.cache.remove_build_id(pref)
if download:
rmdir(pref_layout.download_package())

Expand Down
5 changes: 4 additions & 1 deletion conan/internal/cache/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ def remove_package(self, layout: PackageLayout):
layout.remove()
self._db.remove_package(layout.reference)

def remove_build_id(self, pref):
self._db.remove_build_id(pref)

def assign_prev(self, layout: PackageLayout):
pref = layout.reference

Expand All @@ -185,7 +188,7 @@ def assign_prev(self, layout: PackageLayout):
# This was exported before, making it latest again, update timestamp
pkg_layout = self.get_package_layout(pref)
pkg_layout.remove()
self._db.update_package_timestamp(pref, path=relpath)
self._db.update_package_timestamp(pref, path=relpath, build_id=build_id)

def assign_rrev(self, layout: RecipeLayout):
""" called at export, once the exported recipe revision has been computed, it
Expand Down
7 changes: 5 additions & 2 deletions conan/internal/cache/db/cache_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ def get_latest_package_reference(self, ref):
def update_recipe_timestamp(self, ref):
self._recipes.update_timestamp(ref)

def update_package_timestamp(self, pref: PkgReference, path: str):
self._packages.update_timestamp(pref, path=path)
def update_package_timestamp(self, pref: PkgReference, path: str, build_id: str):
self._packages.update_timestamp(pref, path=path, build_id=build_id)

def remove_recipe(self, ref: RecipeReference):
# Removing the recipe must remove all the package binaries too from DB
Expand All @@ -39,6 +39,9 @@ def remove_package(self, ref: PkgReference):
# Removing the recipe must remove all the package binaries too from DB
self._packages.remove(ref)

def remove_build_id(self, pref):
self._packages.remove_build_id(pref)

def get_matching_build_id(self, ref, build_id):
# TODO: This can also be done in a single query in DB
for d in self._packages.get_package_references(ref):
Expand Down
15 changes: 13 additions & 2 deletions conan/internal/cache/db/packages_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,11 @@ def create(self, path, pref: PkgReference, build_id):
except sqlite3.IntegrityError:
raise ConanReferenceAlreadyExistsInDB(f"Reference '{repr(pref)}' already exists")

def update_timestamp(self, pref: PkgReference, path: str):
def update_timestamp(self, pref: PkgReference, path: str, build_id: str):
assert pref.revision
assert pref.timestamp
where_clause = self._where_clause(pref)
set_clause = self._set_clause(pref, path=path)
set_clause = self._set_clause(pref, path=path, build_id=build_id)
query = f"UPDATE {self.table_name} " \
f"SET {set_clause} " \
f"WHERE {where_clause};"
Expand All @@ -96,6 +96,17 @@ def update_timestamp(self, pref: PkgReference, path: str):
except sqlite3.IntegrityError:
raise ConanReferenceAlreadyExistsInDB(f"Reference '{repr(pref)}' already exists")

def remove_build_id(self, pref):
where_clause = self._where_clause(pref)
query = f"UPDATE {self.table_name} " \
f'SET {self.columns.build_id} = "null" ' \
f"WHERE {where_clause};"
with self.db_connection() as conn:
try:
conn.execute(query)
except sqlite3.IntegrityError:
raise ConanReferenceAlreadyExistsInDB(f"Reference '{repr(pref)}' already exists")

def remove_recipe(self, ref: RecipeReference):
# can't use the _where_clause, because that is an exact match on the package_id, etc
query = f"DELETE FROM {self.table_name} " \
Expand Down
3 changes: 3 additions & 0 deletions conans/client/cache/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ def remove_recipe_layout(self, layout):
def remove_package_layout(self, layout):
self._data_cache.remove_package(layout)

def remove_build_id(self, pref):
self._data_cache.remove_build_id(pref)

def update_recipe_timestamp(self, ref):
""" when the recipe already exists in cache, but we get a new timestamp from a server
that would affect its order in our cache """
Expand Down
2 changes: 1 addition & 1 deletion conans/client/conanfile/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def run_package_method(conanfile, package_id, hook_manager, ref):
scoped_output = conanfile.output
# Make the copy of all the patterns
scoped_output.info("Generating the package")
scoped_output.info("Temporary package folder %s" % conanfile.package_folder)
scoped_output.info("Packaging in folder %s" % conanfile.package_folder)

hook_manager.execute("pre_package", conanfile=conanfile)
if hasattr(conanfile, "package"):
Expand Down
9 changes: 6 additions & 3 deletions conans/client/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ def _get_build_folder(self, conanfile, package_layout):
recipe_build_id = build_id(conanfile)
pref = package_layout.reference
if recipe_build_id is not None and pref.package_id != recipe_build_id:
package_layout.build_id = recipe_build_id
conanfile.output.info(f"build_id() computed {recipe_build_id}")
# check if we already have a package with the calculated build_id
recipe_ref = pref.ref
build_prev = self._cache.get_matching_build_id(recipe_ref, recipe_build_id)
if build_prev is None: # Only store build_id of the first one actually building it
package_layout.build_id = recipe_build_id
build_prev = build_prev or pref

# We are trying to build a package id different from the one that has the
Expand All @@ -65,10 +67,11 @@ def _get_build_folder(self, conanfile, package_layout):
conanfile.output.warning("Build folder is dirty, removing it: %s" % build_folder)
rmdir(build_folder)
clean_dirty(build_folder)
skip_build = False

if skip_build and os.path.exists(build_folder):
conanfile.output.info("Won't be built, using previous build folder as defined "
"in build_id()")
f"in build_id(): {build_folder}")

return build_folder, skip_build

Expand Down Expand Up @@ -136,7 +139,6 @@ def build_package(self, node, package_layout):
# TODO: cache2.0 check locks
# with package_layout.conanfile_read_lock(self._output):
with chdir(base_build):
conanfile.output.info('Building your package in %s' % base_build)
try:
src = base_source if getattr(conanfile, 'no_copy_source', False) else base_build
conanfile.folders.set_base_source(src)
Expand All @@ -147,6 +149,7 @@ def build_package(self, node, package_layout):
conanfile.folders.set_base_pkg_metadata(package_layout.metadata())

if not skip_build:
conanfile.output.info('Building your package in %s' % base_build)
# In local cache, install folder always is build_folder
self._build(conanfile, pref)
clean_dirty(base_build)
Expand Down
Loading

0 comments on commit f595556

Please sign in to comment.