add version, change icon file name
This commit is contained in:
parent
ef7452a378
commit
071f34e0c3
BIN
projectinitializer.ico
Normal file
BIN
projectinitializer.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
36
projectinitializer.spec
Normal file
36
projectinitializer.spec
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
a = Analysis(scripts=['projectinitializer\\__main__.py'],
|
||||||
|
pathex=['projectinitializer'],
|
||||||
|
binaries=[],
|
||||||
|
datas=[('projectinitializer.ico', '.')],
|
||||||
|
hiddenimports=[],
|
||||||
|
hookspath=[],
|
||||||
|
hooksconfig={},
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=None,
|
||||||
|
noarchive=False)
|
||||||
|
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data, cipher=None)
|
||||||
|
|
||||||
|
exe = EXE(pyz,
|
||||||
|
a.scripts,
|
||||||
|
[], # Binaries/Datas usually handled by Analysis/COLLECT
|
||||||
|
exclude_binaries=True, # Let COLLECT handle binaries in one-dir
|
||||||
|
name='projectinitializer',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True, # Use UPX based on config
|
||||||
|
runtime_tmpdir=None,
|
||||||
|
console=True, # Set console based on GUI checkbox
|
||||||
|
disable_windowed_traceback=False,
|
||||||
|
target_arch=None,
|
||||||
|
codesign_identity=None,
|
||||||
|
entitlements_file=None,
|
||||||
|
icon='projectinitializer.ico')
|
||||||
90
projectinitializer/_version.py
Normal file
90
projectinitializer/_version.py
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# File generated by PyInstaller GUI Wrapper. DO NOT EDIT MANUALLY.
|
||||||
|
# Contains build-time information scraped from Git (if available)
|
||||||
|
# and a helper function to format version strings.
|
||||||
|
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
# --- Version Data (Generated) ---
|
||||||
|
# This section is automatically generated by the build process.
|
||||||
|
__version__ = "v.0.0.0.1-1-g1fdf738-dirty"
|
||||||
|
GIT_COMMIT_HASH = "1fdf738d0257a954189792f557dc2bcd427f1264"
|
||||||
|
GIT_BRANCH = "master"
|
||||||
|
BUILD_TIMESTAMP = "2025-05-08T08:42:23Z"
|
||||||
|
IS_GIT_REPO = True
|
||||||
|
|
||||||
|
# --- Default Values (for comparison or fallback) ---
|
||||||
|
DEFAULT_VERSION = "0.0.0+unknown"
|
||||||
|
DEFAULT_COMMIT = "Unknown"
|
||||||
|
DEFAULT_BRANCH = "Unknown"
|
||||||
|
|
||||||
|
# --- Helper Function ---
|
||||||
|
def get_version_string(format_string=None):
|
||||||
|
"""
|
||||||
|
Returns a formatted string based on the build version information.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
format_string (str, optional): A format string using placeholders.
|
||||||
|
Defaults to "{{version}} ({{branch}}/{{commit_short}})" if None.
|
||||||
|
Placeholders:
|
||||||
|
{{version}}: Full version string (e.g., 'v1.0.0-5-gabcdef-dirty')
|
||||||
|
{{tag}}: Clean tag part if exists (e.g., 'v1.0.0'), else DEFAULT_VERSION.
|
||||||
|
{{commit}}: Full Git commit hash.
|
||||||
|
{{commit_short}}: Short Git commit hash (7 chars).
|
||||||
|
{{branch}}: Git branch name.
|
||||||
|
{{dirty}}: '-dirty' if the repo was dirty, empty otherwise.
|
||||||
|
{{timestamp}}: Full build timestamp (ISO 8601 UTC).
|
||||||
|
{{timestamp_short}}: Build date only (YYYY-MM-DD).
|
||||||
|
{{is_git}}: 'Git' if IS_GIT_REPO is True, 'Unknown' otherwise.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The formatted version string, or an error message if formatting fails.
|
||||||
|
"""
|
||||||
|
if format_string is None:
|
||||||
|
format_string = "{version} ({branch}/{commit_short})" # Sensible default
|
||||||
|
|
||||||
|
replacements = {}
|
||||||
|
try:
|
||||||
|
# Prepare data dictionary for substitution
|
||||||
|
replacements['version'] = __version__ if __version__ else DEFAULT_VERSION
|
||||||
|
replacements['commit'] = GIT_COMMIT_HASH if GIT_COMMIT_HASH else DEFAULT_COMMIT
|
||||||
|
replacements['commit_short'] = GIT_COMMIT_HASH[:7] if GIT_COMMIT_HASH and len(GIT_COMMIT_HASH) >= 7 else DEFAULT_COMMIT
|
||||||
|
replacements['branch'] = GIT_BRANCH if GIT_BRANCH else DEFAULT_BRANCH
|
||||||
|
replacements['timestamp'] = BUILD_TIMESTAMP if BUILD_TIMESTAMP else "Unknown"
|
||||||
|
replacements['timestamp_short'] = BUILD_TIMESTAMP.split('T')[0] if BUILD_TIMESTAMP and 'T' in BUILD_TIMESTAMP else "Unknown"
|
||||||
|
replacements['is_git'] = "Git" if IS_GIT_REPO else "Unknown"
|
||||||
|
replacements['dirty'] = "-dirty" if __version__ and __version__.endswith('-dirty') else ""
|
||||||
|
|
||||||
|
# Extract clean tag using regex (handles versions like v1.0.0, 1.0.0)
|
||||||
|
tag = DEFAULT_VERSION
|
||||||
|
if __version__ and IS_GIT_REPO:
|
||||||
|
# Match optional 'v' prefix, then major.minor.patch
|
||||||
|
match = re.match(r'^(v?([0-9]+)\.([0-9]+)\.([0-9]+))', __version__)
|
||||||
|
if match:
|
||||||
|
tag = match.group(1) # Get the full tag (e.g., 'v1.0.0')
|
||||||
|
replacements['tag'] = tag
|
||||||
|
|
||||||
|
# Perform substitution using regex to find placeholders {placeholder}
|
||||||
|
output_string = format_string
|
||||||
|
# Iterate through placeholders and replace them in the format string
|
||||||
|
for placeholder, value in replacements.items():
|
||||||
|
# Compile regex pattern for {placeholder}, allowing for whitespace inside braces
|
||||||
|
pattern = re.compile(r'{\s*' + re.escape(placeholder) + r'\s*}')
|
||||||
|
# Substitute found patterns with the corresponding string value
|
||||||
|
output_string = pattern.sub(str(value), output_string)
|
||||||
|
|
||||||
|
# Optional: Check if any placeholders remain unsubstituted (could indicate typo)
|
||||||
|
if re.search(r'{\s*[\w_]+\s*}', output_string):
|
||||||
|
# You might want to log this or handle it, for now, we return the string as is
|
||||||
|
# print(f"Warning: Unsubstituted placeholders remain in version string: {output_string}")
|
||||||
|
pass
|
||||||
|
|
||||||
|
return output_string
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# Return a simple error message in case of unexpected formatting issues
|
||||||
|
# Avoid printing directly from this generated function
|
||||||
|
return f"[Formatting Error: {e}]"
|
||||||
|
|
||||||
|
|
||||||
@ -6,31 +6,16 @@ from typing import Dict, Any
|
|||||||
|
|
||||||
# --- Constants ---
|
# --- Constants ---
|
||||||
CONFIG_FILE_NAME: str = ".project_initializer_config.json"
|
CONFIG_FILE_NAME: str = ".project_initializer_config.json"
|
||||||
DEFAULT_ICON_FILE_NAME: str = "default_icon.ico" # Nome del file icona in assets/
|
DEFAULT_ICON_FILE_NAME: str = "default_icon.ico"
|
||||||
|
|
||||||
# Path to the assets directory within the package
|
|
||||||
# Path(__file__) is the path to this settings.py file
|
|
||||||
# .parent is the config/ directory
|
|
||||||
# .parent is the project_initializer/ directory
|
|
||||||
# / "assets" gives project_initializer/assets/
|
|
||||||
PACKAGE_ASSETS_PATH: Path = Path(__file__).resolve().parent.parent / "assets"
|
PACKAGE_ASSETS_PATH: Path = Path(__file__).resolve().parent.parent / "assets"
|
||||||
DEFAULT_ICON_PATH: Path = PACKAGE_ASSETS_PATH / DEFAULT_ICON_FILE_NAME
|
DEFAULT_ICON_PATH: Path = PACKAGE_ASSETS_PATH / DEFAULT_ICON_FILE_NAME
|
||||||
|
|
||||||
|
# --- Configuration Management (invariato) ---
|
||||||
# --- Configuration Management ---
|
|
||||||
|
|
||||||
def get_config_file_path() -> Path:
|
def get_config_file_path() -> Path:
|
||||||
"""
|
|
||||||
Gets the path to the configuration file.
|
|
||||||
Stores it in the user's home directory.
|
|
||||||
"""
|
|
||||||
return Path.home() / CONFIG_FILE_NAME
|
return Path.home() / CONFIG_FILE_NAME
|
||||||
|
|
||||||
def load_app_configuration() -> Dict[str, Any]:
|
def load_app_configuration() -> Dict[str, Any]:
|
||||||
"""
|
|
||||||
Loads the application configuration (e.g., last used root directory).
|
|
||||||
Returns a dictionary with the configuration or an empty dictionary if not found/error.
|
|
||||||
"""
|
|
||||||
config_path = get_config_file_path()
|
config_path = get_config_file_path()
|
||||||
if config_path.exists():
|
if config_path.exists():
|
||||||
try:
|
try:
|
||||||
@ -45,9 +30,6 @@ def load_app_configuration() -> Dict[str, Any]:
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
def save_app_configuration(config_data: Dict[str, Any]) -> None:
|
def save_app_configuration(config_data: Dict[str, Any]) -> None:
|
||||||
"""
|
|
||||||
Saves the application configuration to a JSON file.
|
|
||||||
"""
|
|
||||||
config_path = get_config_file_path()
|
config_path = get_config_file_path()
|
||||||
try:
|
try:
|
||||||
with open(config_path, "w", encoding="utf-8") as f:
|
with open(config_path, "w", encoding="utf-8") as f:
|
||||||
@ -58,7 +40,7 @@ def save_app_configuration(config_data: Dict[str, Any]) -> None:
|
|||||||
# --- File Templates ---
|
# --- File Templates ---
|
||||||
|
|
||||||
def get_gitignore_template() -> str:
|
def get_gitignore_template() -> str:
|
||||||
"""Returns the .gitignore template string."""
|
# ... (contenuto invariato, omesso per brevità) ...
|
||||||
return """# Byte-compiled / optimized / DLL files
|
return """# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
@ -209,13 +191,10 @@ dmypy.json
|
|||||||
# Temporary files
|
# Temporary files
|
||||||
*.swp
|
*.swp
|
||||||
*~
|
*~
|
||||||
|
|
||||||
_dist/
|
|
||||||
_build/
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_readme_template(project_name_original: str) -> str:
|
def get_readme_template(project_name_original: str) -> str:
|
||||||
"""Returns the README.md template string, formatted with the project name."""
|
# ... (contenuto invariato, omesso per brevità) ...
|
||||||
return f"""# {project_name_original}
|
return f"""# {project_name_original}
|
||||||
|
|
||||||
A brief description of {project_name_original}.
|
A brief description of {project_name_original}.
|
||||||
@ -235,7 +214,7 @@ A brief description of {project_name_original}.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get_main_py_template(project_name_original: str, project_name_lower: str) -> str:
|
def get_main_py_template(project_name_original: str, project_name_lower: str) -> str:
|
||||||
"""Returns the __main__.py template string for the new project."""
|
# ... (contenuto invariato, omesso per brevità) ...
|
||||||
return f"""# {project_name_lower}/__main__.py
|
return f"""# {project_name_lower}/__main__.py
|
||||||
|
|
||||||
# Example import assuming your main logic is in a 'main' function
|
# Example import assuming your main logic is in a 'main' function
|
||||||
@ -255,17 +234,20 @@ if __name__ == "__main__":
|
|||||||
main()
|
main()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_spec_file_template(project_name_original: str, project_name_lower: str) -> str:
|
|
||||||
|
# --- MODIFICA QUI per accettare project_icon_filename ---
|
||||||
|
def get_spec_file_template(project_name_original: str, project_name_lower: str, project_icon_filename: str) -> str:
|
||||||
"""Returns the .spec file template string for PyInstaller."""
|
"""Returns the .spec file template string for PyInstaller."""
|
||||||
return f"""# -*- mode: python ; coding: utf-8 -*-
|
return f"""# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
|
||||||
block_cipher = None
|
block_cipher = None
|
||||||
|
|
||||||
a = Analysis(
|
a = Analysis(
|
||||||
['{project_name_lower}/__main__.py'], # Main script of the project being built
|
['{project_name_lower}/__main__.py'],
|
||||||
pathex=['.'], # Current directory, where the .spec file is, and project_name_lower is a subfolder
|
pathex=['.'],
|
||||||
binaries=[],
|
binaries=[],
|
||||||
datas=[('{DEFAULT_ICON_FILE_NAME}', '.')], # Icon file relative to project root
|
# Usa project_icon_filename nella sezione datas
|
||||||
|
datas=[('{project_icon_filename}', '.')],
|
||||||
hiddenimports=[],
|
hiddenimports=[],
|
||||||
hookspath=[],
|
hookspath=[],
|
||||||
runtime_hooks=[],
|
runtime_hooks=[],
|
||||||
@ -291,13 +273,15 @@ exe = EXE(
|
|||||||
upx=True,
|
upx=True,
|
||||||
upx_exclude=[],
|
upx_exclude=[],
|
||||||
runtime_tmpdir=None,
|
runtime_tmpdir=None,
|
||||||
console=True, # Set to False for GUI-only applications
|
console=True,
|
||||||
icon='{DEFAULT_ICON_FILE_NAME}' # Icon relative to project root
|
# Usa project_icon_filename per l'opzione icon
|
||||||
|
icon='{project_icon_filename}'
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
|
# --- FINE MODIFICA ---
|
||||||
|
|
||||||
def get_english_manual_template(project_name_original: str) -> str:
|
def get_english_manual_template(project_name_original: str) -> str:
|
||||||
"""Returns the English manual template string."""
|
# ... (contenuto invariato, omesso per brevità) ...
|
||||||
return f"""# {project_name_original} - English Manual
|
return f"""# {project_name_original} - English Manual
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
@ -325,7 +309,7 @@ Common issues and their solutions.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get_italian_manual_template(project_name_original: str) -> str:
|
def get_italian_manual_template(project_name_original: str) -> str:
|
||||||
"""Returns the Italian manual template string."""
|
# ... (contenuto invariato, omesso per brevità) ...
|
||||||
return f"""# {project_name_original} - Manuale Italiano
|
return f"""# {project_name_original} - Manuale Italiano
|
||||||
|
|
||||||
## Introduzione
|
## Introduzione
|
||||||
|
|||||||
@ -44,9 +44,21 @@ def create_project(root_directory_str: str, project_name_original: str) -> str:
|
|||||||
raise ProjectCreationError(f"Root directory '{root_directory}' does not exist or is not a directory.")
|
raise ProjectCreationError(f"Root directory '{root_directory}' does not exist or is not a directory.")
|
||||||
|
|
||||||
project_root_path = root_directory / project_name_original
|
project_root_path = root_directory / project_name_original
|
||||||
# Sanitize project_name_original for use as Python module/package name
|
|
||||||
project_name_lower = project_name_original.lower().replace("-", "_").replace(" ", "_")
|
project_name_lower = project_name_original.lower().replace("-", "_").replace(" ", "_")
|
||||||
# Basic validation for a Python module name (simplistic)
|
|
||||||
|
# Sanitize project_name_original for use as a filename (e.g., for the icon)
|
||||||
|
# Rimuovi spazi e caratteri problematici, ma mantieni il case originale se possibile per il nome file .ico
|
||||||
|
# Per il file .spec e l'icona, è meglio usare un nome file "pulito".
|
||||||
|
# Usiamo project_name_original ma rimuovendo solo gli spazi, o potremmo usare project_name_lower
|
||||||
|
# per coerenza con il file .spec. Scegliamo project_name_original ma sanitizzato.
|
||||||
|
# Un nome file come "Mio Progetto.ico" è valido su Windows, ma meno portabile.
|
||||||
|
# "MioProgetto.ico" è meglio.
|
||||||
|
project_icon_filename_base = "".join(c if c.isalnum() or c in ['_', '-'] else '' for c in project_name_original)
|
||||||
|
if not project_icon_filename_base: # Se il nome originale era tipo "!@#$%"
|
||||||
|
project_icon_filename_base = project_name_lower # Fallback a nome lowercase
|
||||||
|
project_icon_filename = f"{project_icon_filename_base}.ico"
|
||||||
|
|
||||||
|
|
||||||
if not project_name_lower.isidentifier():
|
if not project_name_lower.isidentifier():
|
||||||
raise ProjectCreationError(
|
raise ProjectCreationError(
|
||||||
f"The sanitized project name '{project_name_lower}' (derived from '{project_name_original}') "
|
f"The sanitized project name '{project_name_lower}' (derived from '{project_name_original}') "
|
||||||
@ -54,7 +66,6 @@ def create_project(root_directory_str: str, project_name_original: str) -> str:
|
|||||||
"not starting with a number."
|
"not starting with a number."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if project_root_path.exists():
|
if project_root_path.exists():
|
||||||
raise ProjectCreationError(f"Project directory '{project_root_path}' already exists.")
|
raise ProjectCreationError(f"Project directory '{project_root_path}' already exists.")
|
||||||
|
|
||||||
@ -73,17 +84,16 @@ def create_project(root_directory_str: str, project_name_original: str) -> str:
|
|||||||
core_subpath.mkdir()
|
core_subpath.mkdir()
|
||||||
print(f"Info: Created directory: {core_subpath}")
|
print(f"Info: Created directory: {core_subpath}")
|
||||||
(core_subpath / "__init__.py").touch()
|
(core_subpath / "__init__.py").touch()
|
||||||
(core_subpath / "core.py").touch() # Empty core logic file
|
(core_subpath / "core.py").touch()
|
||||||
|
|
||||||
gui_subpath = src_package_path / "gui"
|
gui_subpath = src_package_path / "gui"
|
||||||
gui_subpath.mkdir()
|
gui_subpath.mkdir()
|
||||||
print(f"Info: Created directory: {gui_subpath}")
|
print(f"Info: Created directory: {gui_subpath}")
|
||||||
(gui_subpath / "__init__.py").touch()
|
(gui_subpath / "__init__.py").touch()
|
||||||
(gui_subpath / "gui.py").touch() # Empty gui logic file
|
(gui_subpath / "gui.py").touch()
|
||||||
|
|
||||||
(src_package_path / "__init__.py").touch() # Make project_name_lower a package
|
(src_package_path / "__init__.py").touch()
|
||||||
|
|
||||||
# Create __main__.py for the new project
|
|
||||||
main_py_content = settings.get_main_py_template(project_name_original, project_name_lower)
|
main_py_content = settings.get_main_py_template(project_name_original, project_name_lower)
|
||||||
with open(src_package_path / "__main__.py", "w", encoding="utf-8") as f:
|
with open(src_package_path / "__main__.py", "w", encoding="utf-8") as f:
|
||||||
f.write(main_py_content)
|
f.write(main_py_content)
|
||||||
@ -110,26 +120,25 @@ def create_project(root_directory_str: str, project_name_original: str) -> str:
|
|||||||
f.write(readme_content)
|
f.write(readme_content)
|
||||||
print(f"Info: Created file: {project_root_path / 'README.md'}")
|
print(f"Info: Created file: {project_root_path / 'README.md'}")
|
||||||
|
|
||||||
|
# --- MODIFICA QUI per usare project_icon_filename ---
|
||||||
# 6) Create .spec file for PyInstaller for the new project
|
# 6) Create .spec file for PyInstaller for the new project
|
||||||
spec_content = settings.get_spec_file_template(project_name_original, project_name_lower)
|
# Passa project_icon_filename al template del file .spec
|
||||||
# The .spec file should be in the project_root_path
|
spec_content = settings.get_spec_file_template(project_name_original, project_name_lower, project_icon_filename)
|
||||||
with open(project_root_path / f"{project_name_lower}.spec", "w", encoding="utf-8") as f:
|
with open(project_root_path / f"{project_name_lower}.spec", "w", encoding="utf-8") as f:
|
||||||
f.write(spec_content)
|
f.write(spec_content)
|
||||||
print(f"Info: Created file: {project_root_path / f'{project_name_lower}.spec'}")
|
print(f"Info: Created file: {project_root_path / f'{project_name_lower}.spec'}")
|
||||||
|
|
||||||
# 7) Copy default .ico file to the new project's root
|
# 7) Copy default .ico file to the new project's root with the new name
|
||||||
# The icon in the .spec file is referenced relative to the project root.
|
# Usa project_icon_filename come nome del file di destinazione
|
||||||
destination_icon_path = project_root_path / settings.DEFAULT_ICON_FILE_NAME
|
destination_icon_path = project_root_path / project_icon_filename
|
||||||
if settings.DEFAULT_ICON_PATH.exists():
|
if settings.DEFAULT_ICON_PATH.exists():
|
||||||
shutil.copy2(settings.DEFAULT_ICON_PATH, destination_icon_path)
|
shutil.copy2(settings.DEFAULT_ICON_PATH, destination_icon_path)
|
||||||
print(f"Info: Copied icon: {destination_icon_path} from {settings.DEFAULT_ICON_PATH}")
|
print(f"Info: Copied icon: {destination_icon_path} from {settings.DEFAULT_ICON_PATH}")
|
||||||
else:
|
else:
|
||||||
# This case should ideally be handled by ensuring the tool's assets are present.
|
|
||||||
# For robustness, we can create an empty placeholder if it's truly missing.
|
|
||||||
destination_icon_path.touch()
|
destination_icon_path.touch()
|
||||||
print(f"Warning: Default icon '{settings.DEFAULT_ICON_PATH}' not found. "
|
print(f"Warning: Default icon '{settings.DEFAULT_ICON_PATH}' not found. "
|
||||||
f"Created empty placeholder: {destination_icon_path}")
|
f"Created empty placeholder: {destination_icon_path}")
|
||||||
|
# --- FINE MODIFICA ICONA ---
|
||||||
|
|
||||||
# 8) Create .gitignore for the new project
|
# 8) Create .gitignore for the new project
|
||||||
gitignore_content = settings.get_gitignore_template()
|
gitignore_content = settings.get_gitignore_template()
|
||||||
@ -142,7 +151,6 @@ def create_project(root_directory_str: str, project_name_original: str) -> str:
|
|||||||
print(f"Info: Initializing Git repository in {project_root_path}...")
|
print(f"Info: Initializing Git repository in {project_root_path}...")
|
||||||
subprocess.run(["git", "init"], cwd=project_root_path, check=True, capture_output=True, text=True)
|
subprocess.run(["git", "init"], cwd=project_root_path, check=True, capture_output=True, text=True)
|
||||||
print(f"Info: Git repository initialized.")
|
print(f"Info: Git repository initialized.")
|
||||||
# Optional: Add all files and make an initial commit
|
|
||||||
subprocess.run(["git", "add", "."], cwd=project_root_path, check=True, capture_output=True, text=True)
|
subprocess.run(["git", "add", "."], cwd=project_root_path, check=True, capture_output=True, text=True)
|
||||||
print(f"Info: All files added to Git staging area.")
|
print(f"Info: All files added to Git staging area.")
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
@ -151,19 +159,14 @@ def create_project(root_directory_str: str, project_name_original: str) -> str:
|
|||||||
)
|
)
|
||||||
print("Info: Initial commit made.")
|
print("Info: Initial commit made.")
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
# Git command not found, not a fatal error for project creation itself.
|
|
||||||
# The user can initialize git manually later.
|
|
||||||
print("Warning: Git command not found. Please install Git to initialize a repository automatically.")
|
print("Warning: Git command not found. Please install Git to initialize a repository automatically.")
|
||||||
print(" The project structure has been created, but a Git repository was not initialized.")
|
print(" The project structure has been created, but a Git repository was not initialized.")
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
# Error during Git operation.
|
|
||||||
error_message = f"Error during Git operation: {e.stderr}"
|
error_message = f"Error during Git operation: {e.stderr}"
|
||||||
if e.stdout:
|
if e.stdout: error_message += f"\nGit stdout: {e.stdout}"
|
||||||
error_message += f"\nGit stdout: {e.stdout}"
|
|
||||||
print(f"Warning: {error_message}")
|
print(f"Warning: {error_message}")
|
||||||
print(" The project structure has been created, but there was an issue with Git initialization.")
|
print(" The project structure has been created, but there was an issue with Git initialization.")
|
||||||
|
|
||||||
|
|
||||||
success_message = (
|
success_message = (
|
||||||
f"Project '{project_name_original}' created successfully in '{project_root_path}'.\n"
|
f"Project '{project_name_original}' created successfully in '{project_root_path}'.\n"
|
||||||
f"To run your new project (example): python -m {project_name_lower}"
|
f"To run your new project (example): python -m {project_name_lower}"
|
||||||
@ -172,8 +175,6 @@ def create_project(root_directory_str: str, project_name_original: str) -> str:
|
|||||||
return success_message
|
return success_message
|
||||||
|
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
# Catch other OS-level errors (permissions, disk full, etc.)
|
|
||||||
# Attempt to clean up if partial creation occurred
|
|
||||||
error_msg = f"OS error during project creation: {e}"
|
error_msg = f"OS error during project creation: {e}"
|
||||||
print(f"Error: {error_msg}")
|
print(f"Error: {error_msg}")
|
||||||
if project_root_path.exists() and project_root_path.is_dir():
|
if project_root_path.exists() and project_root_path.is_dir():
|
||||||
@ -183,10 +184,10 @@ def create_project(root_directory_str: str, project_name_original: str) -> str:
|
|||||||
except OSError as cleanup_e:
|
except OSError as cleanup_e:
|
||||||
print(f"Error: Error during cleanup of '{project_root_path}': {cleanup_e}")
|
print(f"Error: Error during cleanup of '{project_root_path}': {cleanup_e}")
|
||||||
raise ProjectCreationError(error_msg) from e
|
raise ProjectCreationError(error_msg) from e
|
||||||
except Exception as e: # Catch any other unexpected error
|
except Exception as e:
|
||||||
error_msg = f"An unexpected error occurred: {e}"
|
error_msg = f"An unexpected error occurred: {e}"
|
||||||
print(f"Error: {error_msg}")
|
print(f"Error: {error_msg}")
|
||||||
if project_root_path.exists() and project_root_path.is_dir(): # Defensive cleanup
|
if project_root_path.exists() and project_root_path.is_dir():
|
||||||
try:
|
try:
|
||||||
shutil.rmtree(project_root_path)
|
shutil.rmtree(project_root_path)
|
||||||
print(f"Info: Cleaned up partially created project at {project_root_path} due to unexpected error.")
|
print(f"Info: Cleaned up partially created project at {project_root_path} due to unexpected error.")
|
||||||
|
|||||||
@ -6,10 +6,29 @@ from pathlib import Path
|
|||||||
from projectinitializer.config import settings # type: ignore
|
from projectinitializer.config import settings # type: ignore
|
||||||
from projectinitializer.core import project_creator # type: ignore
|
from projectinitializer.core import project_creator # type: ignore
|
||||||
|
|
||||||
|
# --- Import Version Info FOR THE WRAPPER ITSELF ---
|
||||||
|
try:
|
||||||
|
# Use absolute import based on package name
|
||||||
|
from projectinitializer import _version as wrapper_version
|
||||||
|
WRAPPER_APP_VERSION_STRING = f"{wrapper_version.__version__} ({wrapper_version.GIT_BRANCH}/{wrapper_version.GIT_COMMIT_HASH[:7]})"
|
||||||
|
WRAPPER_BUILD_INFO = f"Wrapper Built: {wrapper_version.BUILD_TIMESTAMP}"
|
||||||
|
except ImportError:
|
||||||
|
# This might happen if you run the wrapper directly from source
|
||||||
|
# without generating its _version.py first (if you use that approach for the wrapper itself)
|
||||||
|
WRAPPER_APP_VERSION_STRING = "(Dev Wrapper)"
|
||||||
|
WRAPPER_BUILD_INFO = "Wrapper build time unknown"
|
||||||
|
# --- End Import Version Info ---
|
||||||
|
|
||||||
|
# --- Constants for Version Generation ---
|
||||||
|
DEFAULT_VERSION = "0.0.0+unknown"
|
||||||
|
DEFAULT_COMMIT = "Unknown"
|
||||||
|
DEFAULT_BRANCH = "Unknown"
|
||||||
|
# --- End Constants ---
|
||||||
|
|
||||||
class AppWindow:
|
class AppWindow:
|
||||||
def __init__(self, master: tk.Tk):
|
def __init__(self, master: tk.Tk):
|
||||||
self.master = master
|
self.master = master
|
||||||
master.title("Project Initializer Tool")
|
master.title(f"Project Initializer Tool - {WRAPPER_APP_VERSION_STRING}")
|
||||||
# master.geometry("500x200") # Optional: set a default size
|
# master.geometry("500x200") # Optional: set a default size
|
||||||
|
|
||||||
self.app_config = settings.load_app_configuration()
|
self.app_config = settings.load_app_configuration()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user