builder: Fix up .py[co] invalidation

Since we now only look at changed files we need to handle
the case where a .py file changed and the .pyc didn't, and
remove the now stale .pyc files.

Previously we looked at all files, so we detected this via
the stale .pyc file.
tingping/wmclass
Alexander Larsson 2017-02-24 13:47:21 +01:00
parent 75388609b3
commit 8983834f92
1 changed files with 91 additions and 3 deletions

View File

@ -34,6 +34,84 @@
#include "builder-utils.h"
#include "builder-post-process.h"
static gboolean
invalidate_old_python_compiled (const char *path,
const char *rel_path,
GError **error)
{
struct stat stbuf;
g_autofree char *pyc = NULL;
g_autofree char *pyo = NULL;
g_autofree char *dir = NULL;
g_autofree char *py3dir = NULL;
g_autofree char *pyfilename = NULL;
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
/* This is a python file, not a .py[oc]. If it changed (mtime != 0) then
* this needs to invalidate any old (mtime == 0) .py[oc] files that could refer to it.
*/
if (lstat (path, &stbuf) != 0)
{
g_warning ("Can't stat %s", rel_path);
return TRUE;
}
if (stbuf.st_mtime == OSTREE_TIMESTAMP)
return TRUE; /* Previously handled .py */
pyc = g_strconcat (path, "c", NULL);
if (lstat (pyc, &stbuf) == 0 &&
stbuf.st_mtime == OSTREE_TIMESTAMP)
{
g_print ("Removing stale file %sc", rel_path);
if (unlink (pyc) != 0)
g_warning ("Unable to delete %s", pyc);
}
pyo = g_strconcat (path, "o", NULL);
if (lstat (pyo, &stbuf) == 0 &&
stbuf.st_mtime == OSTREE_TIMESTAMP)
{
g_print ("Removing stale file %so", rel_path);
if (unlink (pyo) != 0)
g_warning ("Unable to delete %s", pyo);
}
/* Handle python3 which is in a __pycache__ subdir */
pyfilename = g_path_get_basename (path);
pyfilename[strlen (pyfilename) - 2] = 0; /* skip "py" */
dir = g_path_get_dirname (path);
py3dir = g_build_filename (dir, "__pycache__", NULL);
if (glnx_dirfd_iterator_init_at (AT_FDCWD, py3dir, FALSE, &dfd_iter, NULL))
{
struct dirent *dent;
while (glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, NULL, NULL) &&
dent != NULL)
{
if (!(g_str_has_suffix (dent->d_name, ".pyc") ||
g_str_has_suffix (dent->d_name, ".pyo")))
continue;
if (!g_str_has_prefix (dent->d_name, pyfilename))
continue;
if (fstatat (dfd_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) == 0 &&
stbuf.st_mtime == OSTREE_TIMESTAMP)
{
g_print ("Removing stale file %s/__pycache__/%s", rel_path, dent->d_name);
if (unlinkat (dfd_iter.fd, dent->d_name, 0))
g_warning ("Unable to delete %s", dent->d_name);
}
}
}
return TRUE;
}
static gboolean
fixup_python_time_stamp (const char *path,
const char *rel_path,
@ -194,7 +272,9 @@ builder_post_process_python_time_stamp (GFile *app_dir,
g_autofree char *path = NULL;
struct stat stbuf;
if (!(g_str_has_suffix (rel_path, ".pyc") || g_str_has_suffix (rel_path, ".pyo")))
if (!(g_str_has_suffix (rel_path, ".py") ||
g_str_has_suffix (rel_path, ".pyc") ||
g_str_has_suffix (rel_path, ".pyo")))
continue;
file = g_file_resolve_relative_path (app_dir, rel_path);
@ -206,8 +286,16 @@ builder_post_process_python_time_stamp (GFile *app_dir,
if (!S_ISREG (stbuf.st_mode))
continue;
if (!fixup_python_time_stamp (path, rel_path, error))
return FALSE;
if (g_str_has_suffix (rel_path, ".py"))
{
if (!invalidate_old_python_compiled (path, rel_path, error))
return FALSE;
}
else
{
if (!fixup_python_time_stamp (path, rel_path, error))
return FALSE;
}
}
return TRUE;