mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Merge pull request #104080 from Repiteo/ci/cache-trim
CI: Trim cache before saving
This commit is contained in:
commit
87f897ae0a
11 changed files with 71 additions and 63 deletions
9
.github/actions/godot-build/action.yml
vendored
9
.github/actions/godot-build/action.yml
vendored
|
@ -19,11 +19,6 @@ inputs:
|
||||||
scons-cache:
|
scons-cache:
|
||||||
description: The SCons cache path.
|
description: The SCons cache path.
|
||||||
default: ${{ github.workspace }}/.scons_cache/
|
default: ${{ github.workspace }}/.scons_cache/
|
||||||
scons-cache-limit:
|
|
||||||
description: The SCons cache size limit.
|
|
||||||
# actions/cache has 10 GiB limit, and GitHub runners have a 14 GiB disk.
|
|
||||||
# Limit to 7 GiB to avoid having the extracted cache fill the disk.
|
|
||||||
default: 7
|
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: composite
|
||||||
|
@ -33,7 +28,7 @@ runs:
|
||||||
env:
|
env:
|
||||||
SCONSFLAGS: ${{ inputs.sconsflags }}
|
SCONSFLAGS: ${{ inputs.sconsflags }}
|
||||||
run: |
|
run: |
|
||||||
echo "Building with flags:" platform=${{ inputs.platform }} target=${{ inputs.target }} tests=${{ inputs.tests }} ${{ env.SCONSFLAGS }} "cache_path=${{ inputs.scons-cache }}" cache_limit=${{ inputs.scons-cache-limit }}
|
echo "Building with flags:" platform=${{ inputs.platform }} target=${{ inputs.target }} tests=${{ inputs.tests }} ${{ env.SCONSFLAGS }} "cache_path=${{ inputs.scons-cache }}"
|
||||||
|
|
||||||
if [ "${{ inputs.target }}" != "editor" ]; then
|
if [ "${{ inputs.target }}" != "editor" ]; then
|
||||||
# Ensure we don't include editor code in export template builds.
|
# Ensure we don't include editor code in export template builds.
|
||||||
|
@ -47,5 +42,5 @@ runs:
|
||||||
export BUILD_NAME="gh"
|
export BUILD_NAME="gh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
scons platform=${{ inputs.platform }} target=${{ inputs.target }} tests=${{ inputs.tests }} ${{ env.SCONSFLAGS }} "cache_path=${{ inputs.scons-cache }}" cache_limit=${{ inputs.scons-cache-limit }}
|
scons platform=${{ inputs.platform }} target=${{ inputs.target }} tests=${{ inputs.tests }} ${{ env.SCONSFLAGS }} "cache_path=${{ inputs.scons-cache }}"
|
||||||
ls -l bin/
|
ls -l bin/
|
||||||
|
|
43
.github/actions/godot-cache-restore/action.yml
vendored
43
.github/actions/godot-cache-restore/action.yml
vendored
|
@ -11,42 +11,29 @@ inputs:
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: composite
|
||||||
steps:
|
steps:
|
||||||
# Because all branches can refer to the repository's default branch's cache, we want it to
|
- name: Restore default cache
|
||||||
# persist as the de-facto fallback. However, it easily expunges in a matter of hours if
|
|
||||||
# nothing explicitly calls to it, so we work around that by ensuring it's *always* pinged
|
|
||||||
# prior to any cache operations.
|
|
||||||
- name: Ping main cache
|
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-ping
|
id: cache-ping
|
||||||
with:
|
with:
|
||||||
path: ${{ inputs.scons-cache }}
|
path: ${{ inputs.scons-cache }}
|
||||||
key: ${{ github.sha }} # Dummy key; we have to rely on the fallback value.
|
key: ${{ inputs.cache-name }}|${{ github.event.repository.default_branch }}|${{ github.sha }}
|
||||||
restore-keys: ${{ inputs.cache-name }}|${{ github.event.repository.default_branch }}
|
restore-keys: ${{ inputs.cache-name }}|${{ github.event.repository.default_branch }}
|
||||||
lookup-only: true
|
|
||||||
|
|
||||||
# Fallback access isn't logged, so register an explicit cache-hit if found.
|
- name: Log default cache files
|
||||||
- name: Ping main cache (exact)
|
if: github.ref_name != github.event.repository.default_branch
|
||||||
if: steps.cache-ping.outputs.cache-matched-key
|
shell: sh
|
||||||
uses: actions/cache/restore@v4
|
run: find "${{ inputs.scons-cache }}" >> redundant.txt
|
||||||
with:
|
|
||||||
path: ${{ inputs.scons-cache }}
|
|
||||||
key: ${{ steps.cache-ping.outputs.cache-matched-key }}
|
|
||||||
lookup-only: true
|
|
||||||
|
|
||||||
# We try to match an existing cache to restore from it. Each potential key is checked against
|
# This is done after pulling the default cache so that PRs can integrate any potential changes
|
||||||
# all existing caches as a prefix. E.g. 'linux-template-minimal' would match any cache that
|
# from the default branch without conflicting with whatever local changes were already made.
|
||||||
# starts with "linux-template-minimal", such as
|
- name: Restore local cache
|
||||||
# "linux-template-minimal|master|6588a4a29af1621086feac0117d5d4d37af957fd".
|
|
||||||
#
|
|
||||||
# We check these prefixes in this order:
|
|
||||||
# 1. An exact match for the base branch, reference name, and SHA hash.
|
|
||||||
# 2. A partial match for the same cache name and reference name.
|
|
||||||
# 3. A partial match for the same cache name and default branch name.
|
|
||||||
- name: Restore SCons cache directory
|
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
|
if: github.ref_name != github.event.repository.default_branch
|
||||||
with:
|
with:
|
||||||
path: ${{ inputs.scons-cache }}
|
path: ${{ inputs.scons-cache }}
|
||||||
key: ${{ inputs.cache-name }}|${{ github.ref_name }}|${{ github.sha }}
|
key: ${{ inputs.cache-name }}|${{ github.ref_name }}|${{ github.sha }}
|
||||||
restore-keys: |
|
restore-keys: ${{ inputs.cache-name }}|${{ github.ref_name }}
|
||||||
${{ inputs.cache-name }}|${{ github.ref_name }}
|
|
||||||
${{ inputs.cache-name }}|${{ github.event.repository.default_branch }}
|
- name: Store unix timestamp
|
||||||
|
shell: sh
|
||||||
|
run: echo "CACHE_TIMESTAMP=$(date +%s)" >> $GITHUB_ENV
|
||||||
|
|
4
.github/actions/godot-cache-save/action.yml
vendored
4
.github/actions/godot-cache-save/action.yml
vendored
|
@ -11,6 +11,10 @@ inputs:
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: composite
|
||||||
steps:
|
steps:
|
||||||
|
- name: Purge files before timestamp
|
||||||
|
shell: sh
|
||||||
|
run: misc/scripts/purge_cache.py ${{ env.CACHE_TIMESTAMP }} "${{ inputs.scons-cache }}"
|
||||||
|
|
||||||
- name: Save SCons cache directory
|
- name: Save SCons cache directory
|
||||||
uses: actions/cache/save@v4
|
uses: actions/cache/save@v4
|
||||||
with:
|
with:
|
||||||
|
|
4
.github/workflows/android_builds.yml
vendored
4
.github/workflows/android_builds.yml
vendored
|
@ -20,21 +20,18 @@ jobs:
|
||||||
target: editor
|
target: editor
|
||||||
tests: false
|
tests: false
|
||||||
sconsflags: arch=arm64 production=yes swappy=yes
|
sconsflags: arch=arm64 production=yes swappy=yes
|
||||||
cache-limit: 1
|
|
||||||
|
|
||||||
- name: Template arm32 (target=template_release, arch=arm32)
|
- name: Template arm32 (target=template_release, arch=arm32)
|
||||||
cache-name: android-template-arm32
|
cache-name: android-template-arm32
|
||||||
target: template_release
|
target: template_release
|
||||||
tests: false
|
tests: false
|
||||||
sconsflags: arch=arm32 swappy=yes
|
sconsflags: arch=arm32 swappy=yes
|
||||||
cache-limit: 1
|
|
||||||
|
|
||||||
- name: Template arm64 (target=template_release, arch=arm64)
|
- name: Template arm64 (target=template_release, arch=arm64)
|
||||||
cache-name: android-template-arm64
|
cache-name: android-template-arm64
|
||||||
target: template_release
|
target: template_release
|
||||||
tests: false
|
tests: false
|
||||||
sconsflags: arch=arm64 swappy=yes
|
sconsflags: arch=arm64 swappy=yes
|
||||||
cache-limit: 1
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
@ -75,7 +72,6 @@ jobs:
|
||||||
platform: android
|
platform: android
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
tests: ${{ matrix.tests }}
|
tests: ${{ matrix.tests }}
|
||||||
scons-cache-limit: ${{ matrix.cache-limit }}
|
|
||||||
|
|
||||||
- name: Save Godot build cache
|
- name: Save Godot build cache
|
||||||
uses: ./.github/actions/godot-cache-save
|
uses: ./.github/actions/godot-cache-save
|
||||||
|
|
1
.github/workflows/ios_builds.yml
vendored
1
.github/workflows/ios_builds.yml
vendored
|
@ -32,7 +32,6 @@ jobs:
|
||||||
platform: ios
|
platform: ios
|
||||||
target: template_release
|
target: template_release
|
||||||
tests: false
|
tests: false
|
||||||
scons-cache-limit: 1
|
|
||||||
|
|
||||||
- name: Save Godot build cache
|
- name: Save Godot build cache
|
||||||
uses: ./.github/actions/godot-cache-save
|
uses: ./.github/actions/godot-cache-save
|
||||||
|
|
8
.github/workflows/linux_builds.yml
vendored
8
.github/workflows/linux_builds.yml
vendored
|
@ -34,7 +34,6 @@ jobs:
|
||||||
artifact: true
|
artifact: true
|
||||||
# Validate godot-cpp compatibility on one arbitrary editor build.
|
# Validate godot-cpp compatibility on one arbitrary editor build.
|
||||||
godot-cpp: true
|
godot-cpp: true
|
||||||
cache-limit: 2
|
|
||||||
|
|
||||||
- name: Editor with doubles and GCC sanitizers (target=editor, tests=yes, dev_build=yes, scu_build=yes, precision=double, use_asan=yes, use_ubsan=yes, linker=gold)
|
- name: Editor with doubles and GCC sanitizers (target=editor, tests=yes, dev_build=yes, scu_build=yes, precision=double, use_asan=yes, use_ubsan=yes, linker=gold)
|
||||||
cache-name: linux-editor-double-sanitizers
|
cache-name: linux-editor-double-sanitizers
|
||||||
|
@ -47,7 +46,6 @@ jobs:
|
||||||
proj-test: true
|
proj-test: true
|
||||||
# Skip 2GiB artifact speeding up action.
|
# Skip 2GiB artifact speeding up action.
|
||||||
artifact: false
|
artifact: false
|
||||||
cache-limit: 7
|
|
||||||
|
|
||||||
- name: Editor with clang sanitizers (target=editor, tests=yes, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)
|
- name: Editor with clang sanitizers (target=editor, tests=yes, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)
|
||||||
cache-name: linux-editor-llvm-sanitizers
|
cache-name: linux-editor-llvm-sanitizers
|
||||||
|
@ -60,7 +58,6 @@ jobs:
|
||||||
artifact: false
|
artifact: false
|
||||||
# Test our oldest supported SCons/Python versions on one arbitrary editor build.
|
# Test our oldest supported SCons/Python versions on one arbitrary editor build.
|
||||||
legacy-scons: true
|
legacy-scons: true
|
||||||
cache-limit: 7
|
|
||||||
|
|
||||||
- name: Editor with ThreadSanitizer (target=editor, tests=yes, dev_build=yes, use_tsan=yes, use_llvm=yes, linker=lld)
|
- name: Editor with ThreadSanitizer (target=editor, tests=yes, dev_build=yes, use_tsan=yes, use_llvm=yes, linker=lld)
|
||||||
cache-name: linux-editor-thread-sanitizer
|
cache-name: linux-editor-thread-sanitizer
|
||||||
|
@ -71,7 +68,6 @@ jobs:
|
||||||
build-mono: false
|
build-mono: false
|
||||||
# Skip 2GiB artifact speeding up action.
|
# Skip 2GiB artifact speeding up action.
|
||||||
artifact: false
|
artifact: false
|
||||||
cache-limit: 5
|
|
||||||
|
|
||||||
- name: Template w/ Mono, release (target=template_release, tests=yes)
|
- name: Template w/ Mono, release (target=template_release, tests=yes)
|
||||||
cache-name: linux-template-mono
|
cache-name: linux-template-mono
|
||||||
|
@ -81,7 +77,6 @@ jobs:
|
||||||
build-mono: false
|
build-mono: false
|
||||||
tests: true
|
tests: true
|
||||||
artifact: true
|
artifact: true
|
||||||
cache-limit: 1
|
|
||||||
|
|
||||||
- name: Template w/ Mono, debug (target=template_debug, tests=yes)
|
- name: Template w/ Mono, debug (target=template_debug, tests=yes)
|
||||||
cache-name: linux-template-mono-debug
|
cache-name: linux-template-mono-debug
|
||||||
|
@ -91,7 +86,6 @@ jobs:
|
||||||
build-mono: false
|
build-mono: false
|
||||||
tests: true
|
tests: true
|
||||||
artifact: true
|
artifact: true
|
||||||
cache-limit: 1
|
|
||||||
|
|
||||||
- name: Minimal template (target=template_release, tests=yes, everything disabled)
|
- name: Minimal template (target=template_release, tests=yes, everything disabled)
|
||||||
cache-name: linux-template-minimal
|
cache-name: linux-template-minimal
|
||||||
|
@ -100,7 +94,6 @@ jobs:
|
||||||
bin: ./bin/godot.linuxbsd.template_release.x86_64
|
bin: ./bin/godot.linuxbsd.template_release.x86_64
|
||||||
tests: true
|
tests: true
|
||||||
artifact: true
|
artifact: true
|
||||||
cache-limit: 1
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
@ -165,7 +158,6 @@ jobs:
|
||||||
platform: linuxbsd
|
platform: linuxbsd
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
tests: ${{ matrix.tests }}
|
tests: ${{ matrix.tests }}
|
||||||
scons-cache-limit: ${{ matrix.cache-limit }}
|
|
||||||
|
|
||||||
- name: Compilation (godot-cpp)
|
- name: Compilation (godot-cpp)
|
||||||
uses: ./.github/actions/godot-cpp-build
|
uses: ./.github/actions/godot-cpp-build
|
||||||
|
|
4
.github/workflows/macos_builds.yml
vendored
4
.github/workflows/macos_builds.yml
vendored
|
@ -20,7 +20,6 @@ jobs:
|
||||||
target: editor
|
target: editor
|
||||||
tests: true
|
tests: true
|
||||||
bin: ./bin/godot.macos.editor.universal
|
bin: ./bin/godot.macos.editor.universal
|
||||||
cache-limit: 1
|
|
||||||
|
|
||||||
- name: Template (target=template_release, tests=yes)
|
- name: Template (target=template_release, tests=yes)
|
||||||
cache-name: macos-template
|
cache-name: macos-template
|
||||||
|
@ -28,7 +27,6 @@ jobs:
|
||||||
tests: true
|
tests: true
|
||||||
sconsflags: debug_symbols=no
|
sconsflags: debug_symbols=no
|
||||||
bin: ./bin/godot.macos.template_release.universal
|
bin: ./bin/godot.macos.template_release.universal
|
||||||
cache-limit: 1
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
@ -56,7 +54,6 @@ jobs:
|
||||||
platform: macos
|
platform: macos
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
tests: ${{ matrix.tests }}
|
tests: ${{ matrix.tests }}
|
||||||
scons-cache-limit: 0 # Only cap on second run to avoid purging unnecessarily
|
|
||||||
|
|
||||||
- name: Compilation (arm64)
|
- name: Compilation (arm64)
|
||||||
uses: ./.github/actions/godot-build
|
uses: ./.github/actions/godot-build
|
||||||
|
@ -65,7 +62,6 @@ jobs:
|
||||||
platform: macos
|
platform: macos
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
tests: ${{ matrix.tests }}
|
tests: ${{ matrix.tests }}
|
||||||
scons-cache-limit: ${{ matrix.cache-limit }}
|
|
||||||
|
|
||||||
- name: Save Godot build cache
|
- name: Save Godot build cache
|
||||||
uses: ./.github/actions/godot-cache-save
|
uses: ./.github/actions/godot-cache-save
|
||||||
|
|
1
.github/workflows/web_builds.yml
vendored
1
.github/workflows/web_builds.yml
vendored
|
@ -62,7 +62,6 @@ jobs:
|
||||||
platform: web
|
platform: web
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
tests: ${{ matrix.tests }}
|
tests: ${{ matrix.tests }}
|
||||||
scons-cache-limit: 0.5
|
|
||||||
|
|
||||||
- name: Save Godot build cache
|
- name: Save Godot build cache
|
||||||
uses: ./.github/actions/godot-cache-save
|
uses: ./.github/actions/godot-cache-save
|
||||||
|
|
5
.github/workflows/windows_builds.yml
vendored
5
.github/workflows/windows_builds.yml
vendored
|
@ -26,7 +26,6 @@ jobs:
|
||||||
sconsflags: debug_symbols=no vsproj=yes vsproj_gen_only=no windows_subsystem=console
|
sconsflags: debug_symbols=no vsproj=yes vsproj_gen_only=no windows_subsystem=console
|
||||||
bin: ./bin/godot.windows.editor.x86_64.exe
|
bin: ./bin/godot.windows.editor.x86_64.exe
|
||||||
compiler: msvc
|
compiler: msvc
|
||||||
cache-limit: 2
|
|
||||||
|
|
||||||
- name: Editor w/ clang-cl (target=editor, tests=yes, use_llvm=yes)
|
- name: Editor w/ clang-cl (target=editor, tests=yes, use_llvm=yes)
|
||||||
cache-name: windows-editor-clang
|
cache-name: windows-editor-clang
|
||||||
|
@ -35,7 +34,6 @@ jobs:
|
||||||
sconsflags: debug_symbols=no windows_subsystem=console use_llvm=yes
|
sconsflags: debug_symbols=no windows_subsystem=console use_llvm=yes
|
||||||
bin: ./bin/godot.windows.editor.x86_64.llvm.exe
|
bin: ./bin/godot.windows.editor.x86_64.llvm.exe
|
||||||
compiler: clang
|
compiler: clang
|
||||||
cache-limit: 1
|
|
||||||
|
|
||||||
- name: Template (target=template_release, tests=yes)
|
- name: Template (target=template_release, tests=yes)
|
||||||
cache-name: windows-template
|
cache-name: windows-template
|
||||||
|
@ -44,7 +42,6 @@ jobs:
|
||||||
sconsflags: debug_symbols=no
|
sconsflags: debug_symbols=no
|
||||||
bin: ./bin/godot.windows.template_release.x86_64.console.exe
|
bin: ./bin/godot.windows.template_release.x86_64.console.exe
|
||||||
compiler: msvc
|
compiler: msvc
|
||||||
cache-limit: 2
|
|
||||||
|
|
||||||
- name: Template w/ GCC (target=template_release, tests=yes, use_mingw=yes)
|
- name: Template w/ GCC (target=template_release, tests=yes, use_mingw=yes)
|
||||||
cache-name: windows-template-gcc
|
cache-name: windows-template-gcc
|
||||||
|
@ -54,7 +51,6 @@ jobs:
|
||||||
sconsflags: debug_symbols=no use_mingw=yes
|
sconsflags: debug_symbols=no use_mingw=yes
|
||||||
bin: ./bin/godot.windows.template_release.x86_64.console.exe
|
bin: ./bin/godot.windows.template_release.x86_64.console.exe
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
cache-limit: 1
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
@ -92,7 +88,6 @@ jobs:
|
||||||
platform: windows
|
platform: windows
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
tests: ${{ matrix.tests }}
|
tests: ${{ matrix.tests }}
|
||||||
scons-cache-limit: ${{ matrix.cache-limit }}
|
|
||||||
|
|
||||||
- name: Save Godot build cache
|
- name: Save Godot build cache
|
||||||
uses: ./.github/actions/godot-cache-save
|
uses: ./.github/actions/godot-cache-save
|
||||||
|
|
|
@ -897,11 +897,9 @@ def prepare_cache(env) -> None:
|
||||||
# Convert GiB to bytes; treat negative numbers as 0 (unlimited).
|
# Convert GiB to bytes; treat negative numbers as 0 (unlimited).
|
||||||
cache_limit = max(0, int(cache_limit * 1024 * 1024 * 1024))
|
cache_limit = max(0, int(cache_limit * 1024 * 1024 * 1024))
|
||||||
if env["verbose"]:
|
if env["verbose"]:
|
||||||
print(
|
print_info(
|
||||||
"Current cache limit is {} (used: {})".format(
|
f"Current cache size is {convert_size(get_size(cache_path))}"
|
||||||
convert_size(cache_limit) if cache_limit else "∞",
|
+ (f" (limit: {convert_size(cache_limit)})" if cache_limit else "")
|
||||||
convert_size(get_size(cache_path)),
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
atexit.register(clean_cache, cache_path, cache_limit, env["verbose"])
|
atexit.register(clean_cache, cache_path, cache_limit, env["verbose"])
|
||||||
|
|
47
misc/scripts/purge_cache.py
Executable file
47
misc/scripts/purge_cache.py
Executable file
|
@ -0,0 +1,47 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import glob
|
||||||
|
import os
|
||||||
|
|
||||||
|
if __name__ != "__main__":
|
||||||
|
raise ImportError(f"{__name__} should not be used as a module.")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Cleanup old cache files")
|
||||||
|
parser.add_argument("timestamp", type=int, help="Unix timestamp cutoff")
|
||||||
|
parser.add_argument("directory", help="Path to cache directory")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
ret = 0
|
||||||
|
|
||||||
|
# TODO: Convert to non-hardcoded path
|
||||||
|
if os.path.exists("redundant.txt"):
|
||||||
|
with open("redundant.txt") as redundant:
|
||||||
|
for item in map(str.strip, redundant):
|
||||||
|
if os.path.isfile(item):
|
||||||
|
try:
|
||||||
|
os.remove(item)
|
||||||
|
except OSError:
|
||||||
|
print(f'Failed to handle "{item}"; skipping.')
|
||||||
|
ret += 1
|
||||||
|
|
||||||
|
for file in glob.glob(os.path.join(args.directory, "*", "*")):
|
||||||
|
try:
|
||||||
|
if os.path.getatime(file) < args.timestamp:
|
||||||
|
os.remove(file)
|
||||||
|
except OSError:
|
||||||
|
print(f'Failed to handle "{file}"; skipping.')
|
||||||
|
ret += 1
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
raise SystemExit(main())
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
import signal
|
||||||
|
|
||||||
|
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||||
|
os.kill(os.getpid(), signal.SIGINT)
|
Loading…
Add table
Add a link
Reference in a new issue