Skip to content

Commit

Permalink
Merge pull request #135 from DCC-EX:133-feature-request-resolve-local…
Browse files Browse the repository at this point in the history
…-changes-neatly-and-without-user-interaction

133-feature-request-resolve-local-changes-neatly-and-without-user-interaction
  • Loading branch information
peteGSX authored Feb 14, 2024
2 parents ed3415b + 7df55d3 commit 4efc755
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 20 deletions.
Binary file removed dist/EX-Installer-Linux64
Binary file not shown.
Binary file removed dist/EX-Installer-Win32.exe
Binary file not shown.
Binary file modified dist/EX-Installer-Win64.exe
Binary file not shown.
Binary file removed dist/EX-Installer-macOS
Binary file not shown.
3 changes: 3 additions & 0 deletions ex_installer/common_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ def __init__(self, parent, *args, **kwargs):
# Get application version
self.app_version = parent.app_version

# Set parent
self.parent = parent

# Product version variables
self.product_version_name = None
self.product_major_version = None
Expand Down
16 changes: 8 additions & 8 deletions ex_installer/ex_commandstation.py
Original file line number Diff line number Diff line change
Expand Up @@ -744,15 +744,15 @@ def generate_config(self):
else:
line = '#define WIFI_SSID "' + self.wifi_ssid_entry.get() + '"\n'
config_list.append(line)
if self.wifi_pwd_entry.get() == "":
param_errors.append("WiFi password not set")
# if self.wifi_pwd_entry.get() == "":
# param_errors.append("WiFi password not set")
# else:
invalid, issue = self.check_invalid_wifi_password()
if invalid:
param_errors.append(issue)
else:
invalid, issue = self.check_invalid_wifi_password()
if invalid:
param_errors.append(issue)
else:
line = '#define WIFI_PASSWORD "' + self.wifi_pwd_entry.get() + '"\n'
config_list.append(line)
line = '#define WIFI_PASSWORD "' + self.wifi_pwd_entry.get() + '"\n'
config_list.append(line)
if self.ethernet_switch.get() == "on":
param_errors.append("Can not have both Ethernet and WiFi enabled")
else:
Expand Down
55 changes: 45 additions & 10 deletions ex_installer/git_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@

QueueMessage = namedtuple("QueueMessage", ["status", "topic", "data"])

"""
A list of files that should be in .gitignore and therefore can safely be deleted
This allows proceeding without user interaction if these files are not ignored as they should be
"""
gitignore_files = [
".DS_Store"
]


@staticmethod
def get_exception(error):
Expand Down Expand Up @@ -114,6 +123,8 @@ def check_local_changes(repo):
"""
Function to check for local changes to files in the provided repo
If file ".DS_Store" is added/modified, this is forcefully discarded as it should be in .gitignore
Returns False (no changes) or a list of changed files
"""
file_list = None
Expand All @@ -122,16 +133,27 @@ def check_local_changes(repo):
file_list = []
status = repo.status()
for file, flag in status.items():
change = "Unknown"
if flag == pygit2.GIT_STATUS_WT_NEW:
change = "Added"
elif flag == pygit2.GIT_STATUS_WT_DELETED:
change = "Deleted"
elif flag == pygit2.GIT_STATUS_WT_MODIFIED:
change = "Modified"
file_list.append(file + " (" + change + ")")
GitClient.log.error("Local file changes in %s", repo)
GitClient.log.error(file_list)
if os.path.basename(file) in gitignore_files and flag == pygit2.GIT_STATUS_WT_NEW:
file_path = os.path.join(repo.workdir, file)
try:
os.remove(file_path)
except Exception:
GitClient.log.error("Unable to delete file to ignore: %s", file_path)
else:
GitClient.log.info("File to ignore found and discarded: %s", file_path)
status = repo.status()
if len(status) > 0:
for file, flag in status.items():
change = "Unknown"
if flag == pygit2.GIT_STATUS_WT_NEW:
change = "Added"
elif flag == pygit2.GIT_STATUS_WT_DELETED:
change = "Deleted"
elif flag == pygit2.GIT_STATUS_WT_MODIFIED:
change = "Modified"
file_list.append(file + " (" + change + ")")
GitClient.log.error("Local file changes in %s", repo)
GitClient.log.error(file_list)
else:
GitClient.log.debug("No local file changes in %s", repo)
else:
Expand Down Expand Up @@ -302,3 +324,16 @@ def get_latest_devel(repo, tag_name="Devel"):
break
GitClient.log.debug("Lastest development is %s", devel_version)
return devel_version

@staticmethod
def git_hard_reset(repo):
"""
Performs a hard reset of the provided repository to the current HEAD
"""
if isinstance(repo, pygit2.Repository):
status = repo.status()
for file, flag in status.items():
if flag == pygit2.GIT_STATUS_WT_NEW:
file_path = os.path.join(repo.workdir, file)
os.remove(file_path)
repo.reset(repo.head.peel().oid, pygit2.GIT_RESET_HARD)
28 changes: 26 additions & 2 deletions ex_installer/select_version_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import customtkinter as ctk
import os
import logging
from CTkMessagebox import CTkMessagebox

# Import local modules
from .common_widgets import WindowLayout
Expand Down Expand Up @@ -154,7 +155,7 @@ def setup_local_repo(self, event):
- check if the product directory already exists
- if so
- if the product directory is already a cloned repo
- any locally modified files that would interfere with Git commands
- any locally modified files that would interfere with Git commands (prompt to resolve)
- delete any existing configuration files
- if not, clone repo
- get list of versions, latest prod, and latest devel versions
Expand All @@ -169,9 +170,10 @@ def setup_local_repo(self, event):
if self.repo:
changes = self.git.check_local_changes(self.repo)
if changes:
self.process_error(f"Local changes detected: f{changes}")
self.process_error("Local changes have been detected that require resolution")
self.restore_input_states()
self.log.error("Local repository file changes: %s", changes)
self.resolve_local_changes(changes)
else:
self.setup_local_repo("get_latest")
else:
Expand Down Expand Up @@ -384,3 +386,25 @@ def copy_config_files(self):
else:
self.process_error("Selected configuration directory is missing the required files")
self.log.error("Directory %s is missing required files", self.config_path.get())

def resolve_local_changes(self, changes):
"""
Function to prompt the user to resolve locally detected repository changes
Resolution means perforing a git hard reset, cancel means exiting the app
"""
message = f"WARNING: The following changes have been detected in {pd[self.product]['product_name']}:\n"
for change in changes:
message += change + "\n"
message += ("\nYou can either override these changes or cancel and resolve these issues manually.\n\n"
"(Note that overriding will delete any added files, undo any modifications,"
" and restore deleted files)")
resolver = CTkMessagebox(master=self.parent, title="Local changes detected", icon="warning",
message=message, border_width=3, width=500, cancel_button=None,
option_2="Override", option_1="Cancel", icon_size=(30, 30),
font=self.common_fonts.instruction_font)
if resolver.get() == "Override":
self.git.git_hard_reset(self.repo)
self.setup_local_repo("setup_local_repo")
else:
self.parent.switch_view("select_product")
3 changes: 3 additions & 0 deletions ex_installer/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
- Disable enabling WiFi on Uno/Nano
- Change default behaviour of programming on Uno/Nano to enabled
- Change start with power on option from JOIN to POWERON
- Add warning screen to flag local repo changes and allow overriding if desired
- Automatically discard macOS .DS_Store file if it exists
- Allow blank WiFi password in STA mode
0.0.16 - Implement less restrictive matching for context highlights in Device Monitor
- Implement device specific restrictions and recommendations:
- Uno/Nano disable TrackManager, select disable EEPROM/PROG options by default
Expand Down

0 comments on commit 4efc755

Please sign in to comment.