mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-25 01:38:11 -07:00
Merge branch 'dev' of https://github.com/DarkFlippers/unleashed-firmware
This commit is contained in:
@@ -5,7 +5,6 @@ from flipper.app import App
|
||||
from flipper.assets.icon import file2image
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import pathlib
|
||||
|
||||
ICONS_SUPPORTED_FORMATS = ["png"]
|
||||
@@ -289,7 +288,6 @@ class Main(App):
|
||||
self.logger.info(f"Packing")
|
||||
dolphin.pack(self.args.output_directory, self.args.symbol_name)
|
||||
self.logger.info(f"Complete")
|
||||
__import__("time").sleep(2)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
@@ -51,7 +51,6 @@ class FlipperApplication:
|
||||
stack_size: int = 2048
|
||||
icon: Optional[str] = None
|
||||
order: int = 0
|
||||
link: Optional[str] = ""
|
||||
sdk_headers: List[str] = field(default_factory=list)
|
||||
targets: List[str] = field(default_factory=lambda: ["all"])
|
||||
|
||||
@@ -194,8 +193,6 @@ class AppBuildset:
|
||||
return self.appmgr.get(app_name).supports_hardware_target(self.hw_target)
|
||||
|
||||
def _get_app_depends(self, app_name: str) -> List[str]:
|
||||
app_def = self.appmgr.get(app_name)
|
||||
|
||||
# Skip app if its target is not supported by the target we are building for
|
||||
if not self._check_if_app_target_supported(app_name):
|
||||
self._writer(
|
||||
@@ -203,6 +200,7 @@ class AppBuildset:
|
||||
)
|
||||
return []
|
||||
|
||||
app_def = self.appmgr.get(app_name)
|
||||
return list(
|
||||
filter(
|
||||
self._check_if_app_target_supported,
|
||||
@@ -325,7 +323,6 @@ class ApplicationsCGenerator:
|
||||
.name = "{app.name}",
|
||||
.stack_size = {app.stack_size},
|
||||
.icon = {f"&{app.icon}" if app.icon else "NULL"},
|
||||
.link = "{f"{app.link}" if app.link else "NULL"}",
|
||||
.flags = {'|'.join(f"FlipperApplicationFlag{flag}" for flag in app.flags)} }}"""
|
||||
|
||||
def generate(self):
|
||||
|
||||
@@ -8,6 +8,10 @@ import os
|
||||
|
||||
WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)")
|
||||
|
||||
# Used by default when globbing for files with GlobRecursive
|
||||
# Excludes all files ending with ~, usually created by editors as backup files
|
||||
GLOB_FILE_EXCLUSION = ["*~"]
|
||||
|
||||
|
||||
def tempfile_arg_esc_func(arg):
|
||||
arg = quote_spaces(arg)
|
||||
|
||||
@@ -27,9 +27,7 @@ def proto_emitter(target, source, env):
|
||||
def dolphin_emitter(target, source, env):
|
||||
res_root_dir = source[0].Dir(env["DOLPHIN_RES_TYPE"])
|
||||
source = [res_root_dir]
|
||||
source.extend(
|
||||
env.GlobRecursive("*.*", res_root_dir.srcnode()),
|
||||
)
|
||||
source.extend(env.GlobRecursive("*.*", res_root_dir.srcnode()))
|
||||
|
||||
target_base_dir = target[0]
|
||||
env.Replace(_DOLPHIN_OUT_DIR=target[0])
|
||||
|
||||
@@ -47,6 +47,7 @@ def generate(env, **kw):
|
||||
"source ${FBT_DEBUG_DIR}/gdbinit",
|
||||
],
|
||||
GDBOPTS_BLACKMAGIC=[
|
||||
"-q",
|
||||
"-ex",
|
||||
"monitor swdp_scan",
|
||||
"-ex",
|
||||
|
||||
@@ -169,7 +169,6 @@ def prepare_app_metadata(target, source, env):
|
||||
sdk_cache = SdkCache(env["SDK_DEFINITION"].path, load_version_only=True)
|
||||
|
||||
if not sdk_cache.is_buildable():
|
||||
print(target, source, env)
|
||||
raise UserError(
|
||||
"SDK version is not finalized, please review changes and re-run operation"
|
||||
)
|
||||
|
||||
@@ -219,7 +219,9 @@ def gen_sdk_data(sdk_cache: SdkCache):
|
||||
|
||||
def _check_sdk_is_up2date(sdk_cache: SdkCache):
|
||||
if not sdk_cache.is_buildable():
|
||||
print("Working with WIP SDK. Expect failures")
|
||||
raise UserError(
|
||||
"SDK version is not finalized, please review changes and re-run operation"
|
||||
)
|
||||
|
||||
|
||||
def validate_sdk_cache(source, target, env):
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import SCons
|
||||
from SCons.Script import Flatten
|
||||
from fbt.util import GLOB_FILE_EXCLUSION
|
||||
|
||||
|
||||
def GlobRecursive(env, pattern, node=".", exclude=None):
|
||||
def GlobRecursive(env, pattern, node=".", exclude=[]):
|
||||
exclude = list(set(Flatten(exclude) + GLOB_FILE_EXCLUSION))
|
||||
# print(f"Starting glob for {pattern} from {node} (exclude: {exclude})")
|
||||
results = []
|
||||
if isinstance(node, str):
|
||||
node = env.Dir(node)
|
||||
@@ -13,7 +17,7 @@ def GlobRecursive(env, pattern, node=".", exclude=None):
|
||||
source=True,
|
||||
exclude=exclude,
|
||||
)
|
||||
# print(f"Glob for {pattern} from {node}: {results}")
|
||||
# print(f"Glob result for {pattern} from {node}: {results}")
|
||||
return results
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import logging
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import pathlib
|
||||
from collections import Counter
|
||||
|
||||
from flipper.utils.fff import *
|
||||
@@ -34,7 +33,6 @@ class DolphinBubbleAnimation:
|
||||
min_level: int,
|
||||
max_level: int,
|
||||
weight: int,
|
||||
subpath: str = None,
|
||||
):
|
||||
# Manifest
|
||||
self.name = name
|
||||
@@ -43,7 +41,6 @@ class DolphinBubbleAnimation:
|
||||
self.min_level = min_level
|
||||
self.max_level = max_level
|
||||
self.weight = weight
|
||||
self.subpath = subpath
|
||||
# Meta and data
|
||||
self.meta = {}
|
||||
self.frames = []
|
||||
@@ -186,12 +183,7 @@ class DolphinBubbleAnimation:
|
||||
bubble["_NextBubbleIndex"] = bubble_index + 1
|
||||
|
||||
def save(self, output_directory: str):
|
||||
if self.subpath:
|
||||
animation_directory = os.path.join(
|
||||
output_directory, self.subpath, self.name
|
||||
)
|
||||
else:
|
||||
animation_directory = os.path.join(output_directory, self.name)
|
||||
animation_directory = os.path.join(output_directory, self.name)
|
||||
os.makedirs(animation_directory, exist_ok=True)
|
||||
meta_filename = os.path.join(animation_directory, "meta.txt")
|
||||
|
||||
@@ -263,8 +255,8 @@ class DolphinManifest:
|
||||
self.animations = []
|
||||
self.logger = logging.getLogger("DolphinManifest")
|
||||
|
||||
def load(self, loc: str, subpath: str = None):
|
||||
manifest_filename = os.path.join(loc, "manifest.txt")
|
||||
def load(self, source_directory: str):
|
||||
manifest_filename = os.path.join(source_directory, "manifest.txt")
|
||||
|
||||
file = FlipperFormatFile()
|
||||
file.load(manifest_filename)
|
||||
@@ -294,17 +286,11 @@ class DolphinManifest:
|
||||
|
||||
# Initialize animation
|
||||
animation = DolphinBubbleAnimation(
|
||||
name,
|
||||
min_butthurt,
|
||||
max_butthurt,
|
||||
min_level,
|
||||
max_level,
|
||||
weight,
|
||||
subpath,
|
||||
name, min_butthurt, max_butthurt, min_level, max_level, weight
|
||||
)
|
||||
|
||||
# Load Animation meta and frames
|
||||
animation.load(os.path.join(loc, name))
|
||||
animation.load(os.path.join(source_directory, name))
|
||||
|
||||
# Add to array
|
||||
self.animations.append(animation)
|
||||
@@ -373,20 +359,11 @@ class Dolphin:
|
||||
self.manifest = DolphinManifest()
|
||||
self.logger = logging.getLogger("Dolphin")
|
||||
|
||||
def load(self, input_directory, dirs: list = None):
|
||||
if dirs:
|
||||
input = str(pathlib.Path(input_directory).absolute())
|
||||
for path in dirs:
|
||||
path = str(pathlib.Path(path).absolute())
|
||||
assert os.path.isdir(path)
|
||||
# Load Manifest
|
||||
self.logger.info(f"Loading directory {path}")
|
||||
self.manifest.load(path, subpath=path.removeprefix(input + os.sep))
|
||||
else:
|
||||
assert os.path.isdir(input_directory)
|
||||
# Load Manifest
|
||||
self.logger.info(f"Loading directory {input_directory}")
|
||||
self.manifest.load(input_directory)
|
||||
def load(self, source_directory: str):
|
||||
assert os.path.isdir(source_directory)
|
||||
# Load Manifest
|
||||
self.logger.info(f"Loading directory {source_directory}")
|
||||
self.manifest.load(source_directory)
|
||||
|
||||
def pack(self, output_directory: str, symbol_name: str = None):
|
||||
self.manifest.save(output_directory, symbol_name)
|
||||
|
||||
@@ -105,7 +105,7 @@ def file2image(file):
|
||||
data_enc = bytearray([len(data_enc) & 0xFF, len(data_enc) >> 8]) + data_enc
|
||||
|
||||
# Use encoded data only if its length less than original, including header
|
||||
if len(data_enc) < len(data_bin) + 1:
|
||||
if len(data_enc) + 2 < len(data_bin) + 1:
|
||||
data = b"\x01\x00" + data_enc
|
||||
else:
|
||||
data = b"\x00" + data_bin
|
||||
|
||||
@@ -17,7 +17,7 @@ def parse_args():
|
||||
|
||||
|
||||
def checkCommitMessage(msg):
|
||||
regex = re.compile(r"^'?\[FL-\d+\]")
|
||||
regex = re.compile(r"^'?\[(FL-\d+,?\s?)+\]")
|
||||
if regex.match(msg):
|
||||
return True
|
||||
return False
|
||||
|
||||
+12
-9
@@ -16,11 +16,11 @@ class Main(App):
|
||||
def init(self):
|
||||
self.parser.add_argument("-p", "--port", help="CDC Port", default="auto")
|
||||
self.parser.add_argument(
|
||||
"-l",
|
||||
"--launch",
|
||||
"-n",
|
||||
"--no-launch",
|
||||
dest="launch_app",
|
||||
action="store_true",
|
||||
help="Launch app",
|
||||
action="store_false",
|
||||
help="Don't launch app",
|
||||
)
|
||||
|
||||
self.parser.add_argument("fap_src_path", help="App file to upload")
|
||||
@@ -91,11 +91,14 @@ class Main(App):
|
||||
self.logger.error(f"Error: upload failed: {storage.last_error}")
|
||||
return -3
|
||||
|
||||
storage.send_and_wait_eol(f'loader open "Applications" {fap_dst_path}\r')
|
||||
result = storage.read.until(storage.CLI_EOL)
|
||||
if len(result):
|
||||
self.logger.error(f"Unexpected response: {result.decode('ascii')}")
|
||||
return -4
|
||||
if self.args.launch_app:
|
||||
storage.send_and_wait_eol(
|
||||
f'loader open "Applications" {fap_dst_path}\r'
|
||||
)
|
||||
result = storage.read.until(storage.CLI_EOL)
|
||||
if len(result):
|
||||
self.logger.error(f"Unexpected response: {result.decode('ascii')}")
|
||||
return -4
|
||||
|
||||
return 0
|
||||
finally:
|
||||
|
||||
@@ -166,13 +166,11 @@ class Main(App):
|
||||
)
|
||||
)
|
||||
bundle_args.extend(self.other_args)
|
||||
log_custom_fz_name = environ.get("CUSTOM_FLIPPER_NAME", None) or ""
|
||||
if (
|
||||
(log_custom_fz_name != "")
|
||||
and (len(log_custom_fz_name) <= 8)
|
||||
and (log_custom_fz_name.isalnum())
|
||||
and (log_custom_fz_name.isascii())
|
||||
):
|
||||
log_custom_fz_name = (
|
||||
environ.get("CUSTOM_FLIPPER_NAME", None)
|
||||
or ""
|
||||
)
|
||||
if (log_custom_fz_name != "") and (len(log_custom_fz_name) <= 8) and (log_custom_fz_name.isalnum()) and (log_custom_fz_name.isascii()):
|
||||
self.logger.info(
|
||||
f"Flipper Custom Name is set:\n\tName: {log_custom_fz_name} : length - {len(log_custom_fz_name)} chars"
|
||||
)
|
||||
|
||||
+1
-1
@@ -199,7 +199,7 @@ class Main(App):
|
||||
|
||||
def disclaimer(self):
|
||||
self.logger.error(
|
||||
"You might brick you device into a state in which you'd need an SWD programmer to fix it."
|
||||
"You might brick your device into a state in which you'd need an SWD programmer to fix it."
|
||||
)
|
||||
self.logger.error(
|
||||
"Please confirm that you REALLY want to do that with --I-understand-what-I-am-doing=yes"
|
||||
|
||||
+31
-31
@@ -1,4 +1,5 @@
|
||||
#!/usb/bin/env python3
|
||||
VERSION = "XFW-0041"
|
||||
|
||||
from flipper.app import App
|
||||
|
||||
@@ -11,24 +12,9 @@ from datetime import date, datetime
|
||||
class GitVersion:
|
||||
def __init__(self, source_dir):
|
||||
self.source_dir = source_dir
|
||||
self.gitlist = [
|
||||
("commit", "rev-parse --short HEAD"),
|
||||
("branch", "rev-parse --abbrev-ref"),
|
||||
("branch_num", "rev-list -count HEAD"),
|
||||
]
|
||||
|
||||
def get_version_info(self):
|
||||
commit = branch = branch_num = "XFW-0041"
|
||||
|
||||
# We dont use an `or` in commands that we expect to fail. It will serve no function.
|
||||
# We also dont try;exept an entire block of code. This is bad practise. We only try the single part that we expect to fail!
|
||||
# Furthermore, traceback.format_exc() is a thing. Fucking use it. JFC
|
||||
|
||||
for git_tuple in self.gitlist:
|
||||
try:
|
||||
exec(f"{git_tuple[0]} = {self._exec_git(git_tuple[1])}")
|
||||
except:
|
||||
exec(f'{git_tuple[0]} = "Unknown"')
|
||||
commit = self._exec_git("rev-parse --short HEAD") or "unknown"
|
||||
|
||||
dirty = False
|
||||
try:
|
||||
@@ -39,35 +25,49 @@ class GitVersion:
|
||||
|
||||
# If WORKFLOW_BRANCH_OR_TAG is set in environment, is has precedence
|
||||
# (set by CI)
|
||||
branch = (
|
||||
os.environ.get("WORKFLOW_BRANCH_OR_TAG", None)
|
||||
or VERSION
|
||||
or self._exec_git("rev-parse --abbrev-ref HEAD")
|
||||
or "unknown"
|
||||
)
|
||||
|
||||
custom_fz_name = os.environ.get("CUSTOM_FLIPPER_NAME", None) or ""
|
||||
branch_num = self._exec_git("rev-list --count HEAD") or "n/a"
|
||||
|
||||
force_no_dirty = os.environ.get("FORCE_NO_DIRTY", None) or ""
|
||||
version = (
|
||||
os.environ.get("DIST_SUFFIX", None)
|
||||
or VERSION
|
||||
or "unknown"
|
||||
)
|
||||
|
||||
if force_no_dirty != "":
|
||||
custom_fz_name = (
|
||||
os.environ.get("CUSTOM_FLIPPER_NAME", None)
|
||||
or ""
|
||||
)
|
||||
|
||||
force_no_dirty = (
|
||||
os.environ.get("FORCE_NO_DIRTY", None)
|
||||
or ""
|
||||
)
|
||||
if (force_no_dirty != ""):
|
||||
dirty = False
|
||||
|
||||
if (
|
||||
(custom_fz_name != "")
|
||||
and (len(custom_fz_name) <= 8)
|
||||
and (custom_fz_name.isalnum())
|
||||
and (custom_fz_name.isascii())
|
||||
):
|
||||
if (custom_fz_name != "") and (len(custom_fz_name) <= 8) and (custom_fz_name.isalnum()) and (custom_fz_name.isascii()):
|
||||
return {
|
||||
"GIT_COMMIT": commit,
|
||||
"GIT_BRANCH": "dev",
|
||||
"GIT_BRANCH": branch,
|
||||
"GIT_BRANCH_NUM": branch_num,
|
||||
"FURI_CUSTOM_FLIPPER_NAME": custom_fz_name,
|
||||
"VERSION": "0.74.3",
|
||||
"BUILD_DIRTY": 0,
|
||||
"VERSION": version,
|
||||
"BUILD_DIRTY": dirty and 1 or 0,
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"GIT_COMMIT": commit,
|
||||
"GIT_BRANCH": "dev",
|
||||
"GIT_BRANCH": branch,
|
||||
"GIT_BRANCH_NUM": branch_num,
|
||||
"VERSION": "0.74.3",
|
||||
"BUILD_DIRTY": 0,
|
||||
"VERSION": version,
|
||||
"BUILD_DIRTY": dirty and 1 or 0,
|
||||
}
|
||||
|
||||
def _exec_git(self, args):
|
||||
|
||||
Reference in New Issue
Block a user