Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix re-downloading when extension is tar.gz #3

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/Linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Linux

on:
push:
pull_request:
schedule:
#Every Sunday at midnight
- cron: '0 0 * * 0'

jobs:

test:
name: "Test"
strategy:
matrix:
version_test: ["NoVersion","3.1"]

runs-on: ubuntu-latest
steps:

- name: Setup Python
uses: actions/setup-python@v2

- name: Checkout
uses: actions/[email protected]

- name: Cache tools
uses: actions/cache@v2
with:
path: tools
key: ${{ runner.os }}-cmakes

- name: "Download cmake packages"
run: |
python3 -mvenv venv
venv/bin/pip3 install -r requirements.txt
venv/bin/python3 cmake_downloader.py --latest_patch
venv/bin/python3 cmake_min_version.py --full_search FULL_SEARCH $GITHUB_WORKSPACE/tests/${{ matrix.version_test }}/
36 changes: 36 additions & 0 deletions .github/workflows/MacOS.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: MacOS

on:
push:
pull_request:
schedule:
#Every Sunday at midnight
- cron: '0 0 * * 0'

jobs:
test:
name: "Test"
strategy:
matrix:
version_test: ["NoVersion","3.1"]
runs-on: macos-latest
steps:

- name: Setup Python
uses: actions/setup-python@v2

- name: Checkout
uses: actions/[email protected]

- name: Cache tools
uses: actions/cache@v2
with:
path: tools
key: ${{ runner.os }}-cmakes

- name: "Download cmake packages"
run: |
python3 -mvenv venv
venv/bin/pip3 install -r requirements.txt
venv/bin/python3 cmake_downloader.py --latest_patch
venv/bin/python3 cmake_min_version.py --full_search FULL_SEARCH $GITHUB_WORKSPACE/tests/${{ matrix.version_test }}/
36 changes: 36 additions & 0 deletions .github/workflows/Windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Windows

on:
push:
pull_request:
schedule:
#Every Sunday at midnight
- cron: '0 0 * * 0'

jobs:
test:
name: "Test"
strategy:
matrix:
version_test: ["NoVersion","3.1"]
runs-on: windows-latest
steps:

- name: Setup Python
uses: actions/setup-python@v2

- name: Checkout
uses: actions/[email protected]

- name: Cache tools
uses: actions/cache@v2
with:
path: tools
key: ${{ runner.os }}-cmakes

- name: "Download cmake packages"
run: |
python -m venv venv
.\venv\Scripts\pip.exe install -r .\requirements.txt
.\venv\Scripts\python.exe cmake_downloader.py --latest_patch
.\venv\Scripts\python.exe cmake_min_version.py --full_search FULL_SEARCH $GITHUB_WORKSPACE\tests\${{ matrix.version_test }}\
4 changes: 3 additions & 1 deletion cmake_downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ def download_and_extract(url: str, path: str):
file_name_start_pos = url.rfind("/") + 1
file_name = url[file_name_start_pos:]
file_wo_ext, file_ext = os.path.splitext(file_name)

if file_ext != ".zip":
file_wo_ext, file_ext2 = os.path.splitext(file_wo_ext)
file_ext=file_ext+file_ext2
if not os.path.exists(os.path.join(path, file_wo_ext)):
response = requests.get(url, stream=True)
response.raise_for_status()
Expand Down
155 changes: 102 additions & 53 deletions cmake_min_version.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import argparse
import glob
import platform
import math
import os.path
import platform
import re
import subprocess
import sys
import tempfile
from typing import List, Optional, NamedTuple
from typing import List
from typing import NamedTuple
from typing import Optional

from packaging.version import parse as version_parse
from termcolor import colored

sys.stdout.reconfigure(encoding="utf-8")


class CMakeBinary(NamedTuple):
version: str
Expand All @@ -25,22 +30,23 @@ def __init__(self, return_code: int, stderr: str):

# try to read proposed minimal version from stderr output
try:
self.proposed_version = re.findall(r'CMake ([^ ]+) or higher is required.', stderr)[0]
self.proposed_version = re.findall(
r"CMake ([^ ]+) or higher is required.", stderr)[0]

# support ranges
if '..' in self.proposed_version:
self.proposed_version = self.proposed_version.split('..')[0]
if ".." in self.proposed_version:
self.proposed_version = self.proposed_version.split("..")[0]
# make sure all versions are major.minor.patch
if self.proposed_version.count('.') == 1:
self.proposed_version += '.0'
if self.proposed_version.count(".") == 1:
self.proposed_version += ".0"
except IndexError:
pass

try:
self.reason = re.findall(r'CMake Error at (.*):', stderr)[0]
self.reason = re.findall(r"CMake Error at (.*):", stderr)[0]
except IndexError:
try:
self.reason = re.findall(r'CMake Error: ([^\n]+)', stderr)[0]
self.reason = re.findall(r"CMake Error: ([^\n]+)", stderr)[0]
except IndexError:
pass

Expand All @@ -49,35 +55,41 @@ def get_cmake_binaries(tools_dir: str) -> List[CMakeBinary]:
binaries = [] # type: List[CMakeBinary]
mGlob = []
if platform.system() == "Windows":
mGlob = glob.glob(tools_dir + '/**/bin/cmake.exe', recursive=True)
mGlob = glob.glob(tools_dir + "/**/bin/cmake.exe", recursive=True)
else:
mGlob = glob.glob(tools_dir + '/**/bin/cmake', recursive=True)
mGlob = glob.glob(tools_dir + "/**/bin/cmake", recursive=True)

for filename in mGlob:
try:
version = re.findall(r'cmake-([^-]+)-', filename)[0]
version = re.findall(r"cmake-([^-]+)-", filename)[0]
binaries.append(CMakeBinary(version, os.path.abspath(filename)))
except IndexError:
pass

print('Found {count} CMake binaries from directory {tools_dir}\n'.format(
count=len(binaries), tools_dir=tools_dir)
)
print("Found {count} CMake binaries from directory {tools_dir}\n".format(
count=len(binaries), tools_dir=tools_dir))
return sorted(binaries, key=lambda x: version_parse(x.version))


def try_configure(binary: str, cmake_parameters: List[str]) -> ConfigureResult:
tmpdir = tempfile.TemporaryDirectory()
proc = subprocess.Popen([binary] + cmake_parameters + ['-Wno-dev'],
stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, cwd=tmpdir.name)
proc = subprocess.Popen(
[binary] + ["-S"] + cmake_parameters + ["-Wno-dev"],
stdout=subprocess.DEVNULL,
stderr=subprocess.PIPE,
cwd=tmpdir.name,
)
proc.wait()

return ConfigureResult(return_code=proc.returncode, stderr=proc.stderr.read().decode('utf-8'))
return ConfigureResult(return_code=proc.returncode,
stderr=proc.stderr.read().decode("utf-8"))


def binary_search(cmake_parameters: List[str], tools_dir: str) -> Optional[CMakeBinary]:
def binary_search(cmake_parameters: List[str],
tools_dir: str) -> Optional[CMakeBinary]:
versions = get_cmake_binaries(tools_dir) # type: List[CMakeBinary]
longest_version_string = max([len(cmake.version) for cmake in versions]) + 1 # type: int
longest_version_string = (max([len(cmake.version)
for cmake in versions]) + 1) # type: int

lower_idx = 0 # type: int
upper_idx = len(versions) - 1 # type: int
Expand All @@ -91,32 +103,45 @@ def binary_search(cmake_parameters: List[str], tools_dir: str) -> Optional[CMake

steps += 1
remaining_versions = upper_idx - lower_idx + 1 # type: int
remaining_steps = int(math.ceil(math.log2(remaining_versions))) # type: int

print('[{progress:3.0f}%] CMake {cmake_version:{longest_version_string}}'.format(
progress=100.0 * float(steps - 1) / (steps + remaining_steps),
cmake_version=cmake_binary.version, longest_version_string=longest_version_string), end='', flush=True
remaining_steps = int(math.ceil(
math.log2(remaining_versions))) # type: int

print(
"[{progress:3.0f}%] CMake {cmake_version:{longest_version_string}}"
.format(
progress=100.0 * float(steps - 1) / (steps + remaining_steps),
cmake_version=cmake_binary.version,
longest_version_string=longest_version_string,
),
end="",
flush=True,
)

result = try_configure(cmake_binary.binary, cmake_parameters) # type: ConfigureResult
# type: ConfigureResult
result = try_configure(cmake_binary.binary, cmake_parameters)

if result.success:
print(colored('✔ works', 'green'))
print(colored("✔ works", "green"))
last_success_idx = mid_idx
upper_idx = mid_idx - 1
else:
print(colored('✘ error', 'red'))
print(colored("✘ error", "red"))
if result.reason:
print(' {reason}'.format(reason=result.reason))
proposed_binary = [x for x in versions if x.version == result.proposed_version]
lower_idx = versions.index(proposed_binary[0]) if len(proposed_binary) else mid_idx + 1
print(" {reason}".format(reason=result.reason))
proposed_binary = [
x for x in versions if x.version == result.proposed_version
]
lower_idx = (versions.index(proposed_binary[0])
if len(proposed_binary) else mid_idx + 1)

return versions[last_success_idx] if last_success_idx is not None else None


def full_search(cmake_parameters: List[str], tools_dir: str) -> Optional[CMakeBinary]:
def full_search(cmake_parameters: List[str],
tools_dir: str) -> Optional[CMakeBinary]:
versions = get_cmake_binaries(tools_dir) # type: List[CMakeBinary]
longest_version_string = max([len(cmake.version) for cmake in versions]) + 1 # type: int
longest_version_string = (max([len(cmake.version)
for cmake in versions]) + 1) # type: int

lower_idx = 0 # type: int
upper_idx = len(versions) - 1 # type: int
Expand All @@ -127,34 +152,54 @@ def full_search(cmake_parameters: List[str], tools_dir: str) -> Optional[CMakeBi
for cmake_binary in versions:
steps += 1
remaining_versions = upper_idx - lower_idx + 1 # type: int
remaining_steps = int(math.ceil(math.log2(remaining_versions))) # type: int

print('[{progress:3.0f}%] CMake {cmake_version:{longest_version_string}}'.format(
progress=100.0 * float(steps - 1) / (steps + remaining_steps),
cmake_version=cmake_binary.version, longest_version_string=longest_version_string), end='', flush=True
remaining_steps = int(math.ceil(
math.log2(remaining_versions))) # type: int

print(
"[{progress:3.0f}%] CMake {cmake_version:{longest_version_string}}"
.format(
progress=100.0 * float(steps - 1) / (steps + remaining_steps),
cmake_version=cmake_binary.version,
longest_version_string=longest_version_string,
),
end="",
flush=True,
)

result = try_configure(cmake_binary.binary, cmake_parameters) # type: ConfigureResult
# type: ConfigureResult
result = try_configure(cmake_binary.binary, cmake_parameters)

if result.success:
print(colored('✔ works', 'green'))
print(colored("\U00002714 works", "green"))
if not last_success_idx or last_success_idx > steps - 1:
last_success_idx = steps - 1
else:
print(colored('✘ error', 'red'))
print(colored("\U0000274C error", "red"))
if result.reason:
print(' {reason}'.format(reason=result.reason))
print(" {reason}".format(reason=result.reason))

return versions[last_success_idx] if last_success_idx is not None else None


if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Find the minimal required CMake version for a project.')
parser.add_argument('params', type=str, nargs='+', help='parameters to pass to CMake')
parser.add_argument('--tools_directory', metavar='DIR', default='tools',
help='path to the CMake binaries (default: "tools")')
parser.add_argument('--full_search', default=False,
help='Searches using a top down approach instead of a binary search (default: False)')
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Find the minimal required CMake version for a project.")
parser.add_argument("params",
type=str,
nargs="+",
help="parameters to pass to CMake")
parser.add_argument(
"--tools_directory",
metavar="DIR",
default="tools",
help='path to the CMake binaries (default: "tools")',
)
parser.add_argument(
"--full_search",
default=False,
help=
"Searches using a top down approach instead of a binary search (default: False)",
)
args = parser.parse_args()

if args.full_search:
Expand All @@ -163,10 +208,14 @@ def full_search(cmake_parameters: List[str], tools_dir: str) -> Optional[CMakeBi
working_version = binary_search(args.params, args.tools_directory)

if working_version:
print('[100%] Minimal working version: {cmake} {version}'.format(
cmake=colored('CMake', 'blue'), version=colored(working_version.version, 'blue')))
print("[100%] Minimal working version: {cmake} {version}".format(
cmake=colored("CMake", "blue"),
version=colored(working_version.version, "blue"),
))

print('\ncmake_minimum_required(VERSION {version})'.format(version=working_version.version))
print("\ncmake_minimum_required(VERSION {version})".format(
version=working_version.version))

else:
print('[100%] {message}'.format(message=colored('ERROR: Could not find working version.', 'red')))
print("[100%] {message}".format(
message=colored("ERROR: Could not find working version.", "red")))
6 changes: 6 additions & 0 deletions tests/3.1/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.1.0)

project(Test3.1)

#https://cmake.org/cmake/help/v3.1/release/3.1.0.html
include(FindOpenCL)
1 change: 1 addition & 0 deletions tests/NoVersion/CMakeLists.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@