Skip to content

Commit

Permalink
Updated tools and workflows (#255)
Browse files Browse the repository at this point in the history
* Updated tools and workflows

* Fixed script_component.hpp

* Run all validations always

* Arma is now testing in action caption

* Added manual deploy
  • Loading branch information
AndreasBrostrom authored Jul 29, 2024
1 parent 1c619ca commit b2fe15a
Show file tree
Hide file tree
Showing 23 changed files with 1,335 additions and 293 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/arma.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Arma
name: Testing

on:
push:
Expand All @@ -13,13 +13,17 @@ jobs:
- name: Checkout the source code
uses: actions/checkout@master
- name: Validate SQF
if: always()
run: python3 tools/sqf_validator.py
- name: Validate Config
if: always()
run: python3 tools/config_style_checker.py
- name: Validate Stringtables
if: always()
run: python3 tools/stringtable_validator.py
continue-on-error: true
- name: Check Strings
if: always()
run: python3 tools/check_strings.py
# - name: Check for BOM
# uses: arma-actions/bom-check@master
Expand Down
39 changes: 39 additions & 0 deletions .github/workflows/hemtt-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Deploy

on:
workflow_dispatch:
inputs:
environment:
description: 'Selected deploy enviroment'
required: true
default: 'dev'
type: choice
options:
- dev
- live
jobs:
windows:
runs-on: windows-latest
steps:
- name: Checkout the source code
uses: actions/checkout@v4
- name: Setup HEMTT
uses: arma-actions/hemtt@v1
- name: Checkout pull request
uses: actions/checkout@v4
- name: Run HEMTT release
run: hemtt release
#- name: Rename build folder
# run: mv .hemttout/build .hemttout/@cav
- name: DEBUG ending...
run: |
Write-Host "Environment: $ENVIRONMENT"
Get-Content -Path .hemttout
env:
ENVIRONMENT: ${{ inputs.environment }}
shell: pwsh
#- name: Upload Artifact
# uses: actions/upload-artifact@v4
# with:
# name: cav-${{ github.sha }}
# path: .hemttout/@*
38 changes: 38 additions & 0 deletions .github/workflows/hemtt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: HEMTT

on:
push:
branches:
- main
pull_request_target:

jobs:
windows:
runs-on: windows-latest
steps:
- name: Checkout the source code
uses: actions/checkout@v4
- name: Setup HEMTT
uses: arma-actions/hemtt@v1
- name: Checkout pull request
uses: actions/checkout@v4
if: ${{ github.event_name == 'pull_request_target' }}
with:
path: pullrequest
ref: 'refs/pull/${{ github.event.number }}/merge'
- name: Replace addons with pull request addons
if: ${{ github.event_name == 'pull_request_target' }}
run: |
rm -r addons\
rm -r include\
xcopy /e /h /q pullrequest\addons addons\
xcopy /e /h /q pullrequest\include include\
- name: Run HEMTT build
run: hemtt build
- name: Rename build folder
run: mv .hemttout/build .hemttout/@cav
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: cav-${{ github.sha }}
path: .hemttout/@*
2 changes: 1 addition & 1 deletion addons/pronelauncher/functions/fnc_onKeyDown.sqf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "script_component.hpp"
#include "..\script_component.hpp"
/*
* Author: PiZZADOX, Jonpas
* Handles keyDown EH for overriding engine stance changes when in AT launcher stance.
Expand Down
1 change: 0 additions & 1 deletion addons/pronelauncher/functions/script_component.hpp

This file was deleted.

53 changes: 31 additions & 22 deletions tools/check_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ def getDefinedStrings(filepath):
# print("getDefinedStrings {0}".format(filepath))
with open(filepath, 'r', encoding="latin-1") as file:
content = file.read()
srch = re.compile('Key ID\=\"(STR_CAV_[_a-zA-Z0-9]*)"', re.IGNORECASE)
srch = re.compile('Key ID\=\"(STR_ACE_[_a-zA-Z0-9]*)"', re.IGNORECASE)
modStrings = srch.findall(content)
modStrings = [s.lower() for s in modStrings]
return modStrings

def getStringUsage(filepath):
selfmodule = (re.search('addons[\W]*([_a-zA-Z0-9]*)', filepath)).group(1)
# print("Checking {0} from {1}".format(filepath,selfmodule))
selfmodule = (re.search('(addons|optionals)[\W]*([_a-zA-Z0-9]*)', filepath)).group(2)
submodule = (re.search(f'(addons|optionals)[\W]*{selfmodule}[\W]*([_a-zA-Z0-9]*)', filepath)).group(2)
# print(f"Checking {filepath} from {selfmodule} ({submodule})")
fileStrings = []

with open(filepath, 'r') as file:
Expand All @@ -27,7 +28,7 @@ def getStringUsage(filepath):
srch = re.compile('(STR_CAV_[_a-zA-Z0-9]*)', re.IGNORECASE)
fileStrings = srch.findall(content)

srch = re.compile('[^E][CL]STRING\(([_a-zA-Z0-9]*)\)', re.IGNORECASE)
srch = re.compile('[^EB][CL]STRING\(([_a-zA-Z0-9]*)\)', re.IGNORECASE)
modStrings = srch.findall(content)
for localString in modStrings:
fileStrings.append("STR_CAV_{0}_{1}".format(selfmodule, localString))
Expand All @@ -37,6 +38,11 @@ def getStringUsage(filepath):
for (exModule, exString) in exStrings:
fileStrings.append("STR_CAV_{0}_{1}".format(exModule, exString))

srch = re.compile('SUB[CL]STRING\(([_a-zA-Z0-9]*)\)')
subStrings = srch.findall(content)
for (subString) in subStrings:
fileStrings.append(f"STR_CAV_{submodule}_{subString}")

srch = re.compile('IGNORE_STRING_WARNING\([\'"]*([_a-zA-Z0-9]*)[\'"]*\)')
ignoreWarnings = srch.findall(content)

Expand All @@ -51,23 +57,24 @@ def main(argv):
allDefinedStrings = []
allUsedStrings = []

# Allow running from root directory as well as from inside the tools directory
rootDir = "../addons"
if (os.path.exists("addons")):
rootDir = "addons"

for root, dirnames, filenames in os.walk(rootDir):
for filename in fnmatch.filter(filenames, '*.sqf'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.cpp'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.hpp'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.h'):
sqf_list.append(os.path.join(root, filename))

for filename in fnmatch.filter(filenames, '*.xml'):
xml_list.append(os.path.join(root, filename))
for folder in ['addons', 'optionals']:
# Allow running from root directory as well as from inside the tools directory
rootDir = "../" + folder
if (os.path.exists(folder)):
rootDir = folder

for root, dirnames, filenames in os.walk(rootDir):
for filename in fnmatch.filter(filenames, '*.sqf'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.cpp'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.hpp'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.h'):
sqf_list.append(os.path.join(root, filename))

for filename in fnmatch.filter(filenames, '*.xml'):
xml_list.append(os.path.join(root, filename))

for filename in xml_list:
allDefinedStrings = allDefinedStrings + getDefinedStrings(filename)
Expand All @@ -77,6 +84,8 @@ def main(argv):
allDefinedStrings = list(sorted(set(allDefinedStrings)))
allUsedStrings = list(sorted(set(allUsedStrings)))

if ("str_cav_tagging_name" in allUsedStrings): allUsedStrings.remove("str_cav_tagging_name") # Handle tagging macro

print("-----------")
countUnusedStrings = 0
countUndefinedStrings = 0
Expand All @@ -98,4 +107,4 @@ def main(argv):
return countUndefinedStrings

if __name__ == "__main__":
main(sys.argv)
main(sys.argv)
97 changes: 97 additions & 0 deletions tools/compileExtensions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/usr/bin/env python3
# vim: set fileencoding=utf-8 :

# compileExtensions.py (from acre2's make.py)

###############################################################################

# The MIT License (MIT)

# Copyright (c) 2013-2014 Ryan Schultz

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall 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 sys
import os.path
import subprocess
import shutil
import time
import timeit

if sys.platform == "win32":
import winreg


def compile_extensions(force_build):
originalDir = os.getcwd()
extensions_root = os.path.join(os.path.dirname(os.getcwd()), "extensions")
os.chdir(extensions_root)
print("\nCompiling extensions in {} with rebuild:{}\n".format(extensions_root, force_build))

if shutil.which("git") == None:
print("Failed to find Git!")
return
if shutil.which("cmake") == None:
print("Failed to find CMake!")
return
if shutil.which("msbuild") == None:
print("Failed to find MSBuild!")
return

try:
buildType = "rebuild" if force_build else "build"
# 32-bit
vcproj32 = os.path.join(extensions_root, "vcproj32")
if not os.path.exists(vcproj32):
os.mkdir(vcproj32)
os.chdir(vcproj32)
subprocess.call(["cmake", "..", "-A", "Win32"]) # note: cmake will update ace_version stuff
subprocess.call(["msbuild", "ACE.sln", "/m", "/t:{}".format(buildType), "/p:Configuration=Release"])

# 64-bit
vcproj64 = os.path.join(extensions_root, "vcproj64")
if not os.path.exists(vcproj64):
os.mkdir(vcproj64)
os.chdir(vcproj64)
subprocess.call(["cmake", "..", "-A", "x64"])
subprocess.call(["msbuild", "ACE.sln", "/m", "/t:{}".format(buildType), "/p:Configuration=Release"])
except Exception as e:
print("Error: COMPILING EXTENSIONS - {}".format(e))
raise
finally:
os.chdir(originalDir)


def main(argv):
if "force" in argv:
argv.remove("force")
force_build = True
else:
force_build = False

compile_extensions(force_build)


if __name__ == "__main__":
start_time = timeit.default_timer()
main(sys.argv)
print("\nTotal Program time elapsed: {0} sec".format(timeit.default_timer() - start_time))
input("Press Enter to continue...")
46 changes: 36 additions & 10 deletions tools/config_style_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ def pushClosing(t):
def popClosing():
closing << closingStack.pop()

reIsClass = re.compile(r'^\s*class(.*)')
reIsClassInherit = re.compile(r'^\s*class(.*):')
reIsClassBody = re.compile(r'^\s*class(.*){')
reBadColon = re.compile(r'\s*class (.*) :')
reSpaceAfterColon = re.compile(r'\s*class (.*): ')
reSpaceBeforeCurly = re.compile(r'\s*class (.*) {')
reClassSingleLine = re.compile(r'\s*class (.*)[{;]')

with open(filepath, 'r', encoding='utf-8', errors='ignore') as file:
content = file.read()

Expand Down Expand Up @@ -118,6 +126,23 @@ def popClosing():
if brackets_list.count('{') != brackets_list.count('}'):
print("ERROR: A possible missing curly brace {{ or }} in file {0} {{ = {1} }} = {2}".format(filepath,brackets_list.count('{'),brackets_list.count('}')))
bad_count_file += 1

file.seek(0)
for lineNumber, line in enumerate(file.readlines()):
if reIsClass.match(line):
if reBadColon.match(line):
print(f"WARNING: bad class colon {filepath} Line number: {lineNumber+1}")
# bad_count_file += 1
if reIsClassInherit.match(line):
if not reSpaceAfterColon.match(line):
print(f"WARNING: bad class missing space after colon {filepath} Line number: {lineNumber+1}")
if reIsClassBody.match(line):
if not reSpaceBeforeCurly.match(line):
print(f"WARNING: bad class inherit missing space before curly braces {filepath} Line number: {lineNumber+1}")
if not reClassSingleLine.match(line):
print(f"WARNING: bad class braces placement {filepath} Line number: {lineNumber+1}")
# bad_count_file += 1

return bad_count_file

def main():
Expand All @@ -131,16 +156,17 @@ def main():
parser.add_argument('-m','--module', help='only search specified module addon folder', required=False, default="")
args = parser.parse_args()

# Allow running from root directory as well as from inside the tools directory
rootDir = "../addons"
if (os.path.exists("addons")):
rootDir = "addons"

for root, dirnames, filenames in os.walk(rootDir + '/' + args.module):
for filename in fnmatch.filter(filenames, '*.cpp'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.hpp'):
sqf_list.append(os.path.join(root, filename))
for folder in ['addons', 'optionals']:
# Allow running from root directory as well as from inside the tools directory
rootDir = "../" + folder
if (os.path.exists(folder)):
rootDir = folder

for root, dirnames, filenames in os.walk(rootDir + '/' + args.module):
for filename in fnmatch.filter(filenames, '*.cpp'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.hpp'):
sqf_list.append(os.path.join(root, filename))

for filename in sqf_list:
bad_count = bad_count + check_config_style(filename)
Expand Down
2 changes: 1 addition & 1 deletion tools/config_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

######## GLOBALS #########
MAINPREFIX = "Z"
PREFIX = "cav"
PREFIX = "ACE"
##########################

def Fract_Sec(s):
Expand Down
Loading

0 comments on commit b2fe15a

Please sign in to comment.