Skip to content

Commit

Permalink
Move mx clangformat command to sdk suite.
Browse files Browse the repository at this point in the history
  • Loading branch information
rschatz committed Oct 4, 2022
1 parent a8d89df commit 0ea525f
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 74 deletions.
File renamed without changes.
3 changes: 2 additions & 1 deletion sdk/mx.sdk/mx_sdk.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -47,6 +47,7 @@
import mx_sdk_vm
import mx_sdk_vm_impl
import mx_sdk_benchmark # pylint: disable=unused-import
import mx_sdk_clangformat # pylint: disable=unused-import
import datetime
from mx_bisect import define_bisect_default_build_steps
from mx_bisect_strategy import BuildStepsGraalVMStrategy
Expand Down
112 changes: 112 additions & 0 deletions sdk/mx.sdk/mx_sdk_clangformat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# The Universal Permissive License (UPL), Version 1.0
#
# Subject to the condition set forth below, permission is hereby granted to any
# person obtaining a copy of this software, associated documentation and/or
# data (collectively the "Software"), free of charge and under any and all
# copyright rights in the Software, and any and all patent rights owned or
# freely licensable by each licensor hereunder covering either (i) the
# unmodified Software as contributed to or provided by such licensor, or (ii)
# the Larger Works (as defined below), to deal in both
#
# (a) the Software, and
#
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
# one is included with the Software each a "Larger Work" to which the Software
# is contributed by such licensors),
#
# without restriction, including without limitation the rights to copy, create
# derivative works of, display, perform, and distribute the Software and make,
# use, sell, offer for sale, import, export, have made, and have sold the
# Software and the Larger Work(s), and to sublicense the foregoing rights on
# either these or other terms.
#
# This license is subject to the following condition:
#
# The above copyright notice and either this complete permission notice or at a
# minimum a reference to the UPL must be included in all copies or substantial
# portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#

import mx

import os.path
import subprocess
import sys

from argparse import ArgumentParser

_suite = mx.suite('sdk')

@mx.command(_suite.name, "clangformat")
def clangformat(args=None):
""" Runs clang-format on C/C++ files in native projects of the primary suite """
parser = ArgumentParser(prog='mx clangformat')
parser.add_argument('--with-projects', action='store_true', help='check native projects. Defaults to true unless a path is specified.')
parser.add_argument('--primary', action='store_true', help='limit checks to primary suite')
parser.add_argument('paths', metavar='path', nargs='*', help='check given paths')
args = parser.parse_args(args)
paths = [(p, "<cmd-line-argument>") for p in args.paths]

if not paths or args.with_projects:
paths += [(p.dir, p.name) for p in mx.projects(limit_to_primary=args.primary) if p.isNativeProject() and getattr(p, "clangFormat", True)]

# ensure LLVM_TOOLCHAIN is built
mx.command_function('build')(['--dependencies', 'LLVM_TOOLCHAIN'])
clangFormat = os.path.join(mx.dependency('LLVM_TOOLCHAIN', fatalIfMissing=True).get_output(), 'bin', mx.exe_suffix('clang-format'))

error = False
for f, reason in paths:
if not checkCFiles(clangFormat, f, reason):
error = True
if error:
mx.log_error("found formatting errors!")
sys.exit(-1)


def checkCFiles(clangFormat, target, reason):
error = False
files_to_check = []
if os.path.isfile(target):
files_to_check.append(target)
else:
for path, _, files in os.walk(target):
for f in files:
if f.endswith('.c') or f.endswith('.cpp') or f.endswith('.h') or f.endswith('.hpp'):
files_to_check.append(os.path.join(path, f))
if not files_to_check:
mx.logv("clang-format: no files found {} ({})".format(target, reason))
return True
mx.logv("clang-format: checking {} ({}, {} files)".format(target, reason, len(files_to_check)))
for f in files_to_check:
if not checkCFile(clangFormat, f):
error = True
return not error


def checkCFile(clangFormat, targetFile):
mx.logvv(" checking file " + targetFile)
""" Checks the formatting of a C file and returns True if the formatting is okay """
formatCommand = [clangFormat, targetFile]
formattedContent = subprocess.check_output(formatCommand).decode().splitlines()
with open(targetFile) as f:
originalContent = f.read().splitlines()
if not formattedContent == originalContent:
# modify the file to the right format
subprocess.check_output(formatCommand + ['-i'])
mx.log('\n'.join(formattedContent))
mx.log('\nmodified formatting in {0} to the format above'.format(targetFile))
mx.logv("command: " + " ".join(formatCommand))
return False
return True
74 changes: 1 addition & 73 deletions sulong/mx.sulong/mx_sulong_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,10 @@
#
import argparse
import os
import sys
import subprocess
from argparse import ArgumentParser

import mx
import mx_subst
import mx_sulong
import mx_unittest

from mx_gate import Task, add_gate_runner, add_gate_argument
Expand Down Expand Up @@ -185,11 +182,8 @@ def _unittest(title, test_suite, tags=None, testClasses=None, unittestArgs=None,
if mx.checkcopyrights(['--primary']) != 0:
t.abort('Copyright errors found. Please run "mx checkcopyrights --primary -- --fix" to fix them.')

with Task('BuildLLVMorg', tasks, tags=['style', 'clangformat']) as t:
# needed for clang-format
if t: build_llvm_org(args)
with Task('ClangFormat', tasks, tags=['style', 'clangformat']) as t:
if t: clangformat([])
if t: mx.command_function('clangformat')([])
# Folders not containing tests: options, services, util
_unittest('Benchmarks', 'SULONG_SHOOTOUT_TEST_SUITE', description="Language Benchmark game tests", testClasses=['ShootoutsSuite'], tags=['benchmarks', 'sulongMisc'])
_unittest('Types', 'SULONG_TEST', description="Test floating point arithmetic", testClasses=['com.oracle.truffle.llvm.tests.types.floating.'], tags=['type', 'sulongMisc', 'sulongCoverage'])
Expand Down Expand Up @@ -280,69 +274,3 @@ def runLLVMUnittests(unittest_runner):
build_args = ['--language:llvm'] + java_run_props
unittest_runner(['com.oracle.truffle.llvm.tests.interop', '--force-builder-on-cp', '--run-args'] + run_args +
['--build-args', '--initialize-at-build-time'] + build_args)


def build_llvm_org(args=None):
defaultBuildArgs = ['-p']
if not args.no_warning_as_error:
defaultBuildArgs += ['--warning-as-error']
mx.command_function('build')(defaultBuildArgs + ['--project', 'LLVM_TOOLCHAIN'] + args.extra_build_args)


@mx.command(_suite.name, "clangformat")
def clangformat(args=None):
""" Runs clang-format on C/C++ files in native projects of the primary suite """
parser = ArgumentParser(prog='mx clangformat')
parser.add_argument('--with-projects', action='store_true', help='check native projects. Defaults to true unless a path is specified.')
parser.add_argument('paths', metavar='path', nargs='*', help='check given paths')
args = parser.parse_args(args)
paths = [(p, "<cmd-line-argument>") for p in args.paths]

if not paths or args.with_projects:
paths += [(p.dir, p.name) for p in mx.projects(limit_to_primary=True) if p.isNativeProject() and getattr(p, "clangFormat", True)]

error = False
for f, reason in paths:
if not checkCFiles(f, reason):
error = True
if error:
mx.log_error("found formatting errors!")
sys.exit(-1)


def checkCFiles(target, reason):
error = False
files_to_check = []
if os.path.isfile(target):
files_to_check.append(target)
else:
for path, _, files in os.walk(target):
for f in files:
if f.endswith('.c') or f.endswith('.cpp') or f.endswith('.h') or f.endswith('.hpp'):
files_to_check.append(os.path.join(path, f))
if not files_to_check:
mx.logv("clang-format: no files found {} ({})".format(target, reason))
return True
mx.logv("clang-format: checking {} ({}, {} files)".format(target, reason, len(files_to_check)))
for f in files_to_check:
if not checkCFile(f):
error = True
return not error


def checkCFile(targetFile):
mx.logvv(" checking file " + targetFile)
""" Checks the formatting of a C file and returns True if the formatting is okay """
clangFormat = mx_sulong.findBundledLLVMProgram('clang-format')
formatCommand = [clangFormat, targetFile]
formattedContent = mx_sulong._decode(subprocess.check_output(formatCommand)).splitlines()
with open(targetFile) as f:
originalContent = f.read().splitlines()
if not formattedContent == originalContent:
# modify the file to the right format
subprocess.check_output(formatCommand + ['-i'])
mx.log('\n'.join(formattedContent))
mx.log('\nmodified formatting in {0} to the format above'.format(targetFile))
mx.logv("command: " + " ".join(formatCommand))
return False
return True

0 comments on commit 0ea525f

Please sign in to comment.