first commit
This commit is contained in:
commit
c35aaed66b
57
.gitignore
vendored
Normal file
57
.gitignore
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
# === sub-módulos clonados ===
|
||||
src/modules/
|
||||
|
||||
# === Autotools build artefacts ===
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
missing
|
||||
py-compile
|
||||
stamp-h1
|
||||
|
||||
# === Build & dist directories ===
|
||||
build/
|
||||
dist/
|
||||
*.tar.gz
|
||||
*.tar.bz2
|
||||
*.zip
|
||||
|
||||
# === Python cache & venv ===
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
*.egg-info/
|
||||
.eggs/
|
||||
venv/
|
||||
.env/
|
||||
.venv/
|
||||
|
||||
# === Editor / OS junk ===
|
||||
*.swp
|
||||
*.swo
|
||||
*.bak
|
||||
*.tmp
|
||||
*~
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# === Logs ===
|
||||
*.log
|
||||
nohup.out
|
||||
|
||||
# === IDE / workspace ===
|
||||
.vscode/
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
# === Backup copies ===
|
||||
*.old
|
||||
*.orig
|
||||
*.rej
|
||||
96
Makefile.am
Normal file
96
Makefile.am
Normal file
@ -0,0 +1,96 @@
|
||||
SUBDIRS = src
|
||||
|
||||
# ===========================
|
||||
# Configurações de Git
|
||||
# ===========================
|
||||
GIT_USER ?= "neo.webmaster.2@gmail.com"
|
||||
GIT_EMAIL ?= "neo.webmaster.2@gmail.com"
|
||||
GIT_REMOTE ?= "origin"
|
||||
GIT_BRANCH ?= "main"
|
||||
COMMIT_MSG ?= "Auto-commit via make git"
|
||||
|
||||
# ===========================
|
||||
# Caminhos e artefactos
|
||||
# ===========================
|
||||
DIST_DIR ?= $(top_builddir)/dist
|
||||
BUILD_DIR ?= $(top_builddir)/build
|
||||
SRC_TAR ?= $(DIST_DIR)/neoricalex-src.tar.gz
|
||||
|
||||
# ===========================
|
||||
# Alvos principais
|
||||
# ===========================
|
||||
.PHONY: all tarball git release run clean-local
|
||||
|
||||
all: $(DIST_DIR)
|
||||
|
||||
$(DIST_DIR):
|
||||
mkdir -p $(DIST_DIR)
|
||||
|
||||
# ===========================
|
||||
# Empacotamento do código-fonte
|
||||
# ===========================
|
||||
tarball: $(SRC_TAR)
|
||||
|
||||
$(SRC_TAR):
|
||||
@echo "[TAR] Empacotando código-fonte..."
|
||||
mkdir -p $(DIST_DIR)
|
||||
cd $(top_srcdir) && tar \
|
||||
--exclude="$(notdir $(SRC_TAR))" \
|
||||
--exclude="$(DIST_DIR)" \
|
||||
--exclude="$(BUILD_DIR)" \
|
||||
--exclude='*/__pycache__' \
|
||||
--exclude='*/.venv' \
|
||||
--exclude='*/venv' \
|
||||
--exclude='*.pyc' \
|
||||
--exclude='*.pyo' \
|
||||
--exclude='*.o' \
|
||||
--exclude='*.a' \
|
||||
--exclude='*.so' \
|
||||
-czf $(SRC_TAR) .
|
||||
@echo "[✔] Tarball gerado em $(SRC_TAR)"
|
||||
|
||||
# ===========================
|
||||
# Git (commit + push)
|
||||
# ===========================
|
||||
git:
|
||||
@echo "📦 Commit automático → Gitea"
|
||||
@git config user.name $(GIT_USER)
|
||||
@git config user.email $(GIT_EMAIL)
|
||||
@git rev-parse --abbrev-ref HEAD >/dev/null 2>&1 || true
|
||||
@git add -A
|
||||
@git commit -m "$(COMMIT_MSG)" || echo "Nenhuma modificação para commitar."
|
||||
@git push $(GIT_REMOTE) $(GIT_BRANCH)
|
||||
|
||||
# ===========================
|
||||
# Release (Tarball)
|
||||
# ===========================
|
||||
release: tarball
|
||||
@echo "🚀 Publicando build em dist/releases"
|
||||
@mkdir -p $(DIST_DIR)/releases
|
||||
@if ls $(DIST_DIR)/neoricalex-*.tar.gz >/dev/null 2>&1; then \
|
||||
cp $(DIST_DIR)/neoricalex-*.tar.gz $(DIST_DIR)/releases/; \
|
||||
else \
|
||||
echo "⚠️ Nenhum tarball encontrado. Execute 'make tarball' primeiro."; \
|
||||
fi
|
||||
@git add $(DIST_DIR)/releases/
|
||||
@git commit -m "Build automático: release $(shell date +%F_%H-%M)" || echo "Nenhum ficheiro novo para commitar."
|
||||
@git push origin main
|
||||
@TAG="v$(shell date +%Y.%m.%d-%H%M)" && \
|
||||
echo "🏷 Criando tag $$TAG" && \
|
||||
git tag -a $$TAG -m "Release automática em $$TAG" && \
|
||||
git push origin $$TAG || echo "⚠️ Tag já existente ou erro ao criar."
|
||||
|
||||
# ===========================
|
||||
# Teste
|
||||
# ===========================
|
||||
run:
|
||||
@python3 src/manager/manager_main.py
|
||||
|
||||
# ===========================
|
||||
# Limpeza
|
||||
# ===========================
|
||||
clean-local:
|
||||
@echo "[CLEAN] Removendo diretórios temporários..."
|
||||
rm -rf $(BUILD_DIR)
|
||||
find $(DIST_DIR) -type f ! -path "$(DIST_DIR)/releases/*" -delete
|
||||
@echo "[✔] Limpeza concluída (releases preservadas)"
|
||||
40
README
Normal file
40
README
Normal file
@ -0,0 +1,40 @@
|
||||
# NEORICALEX – System Manager
|
||||
|
||||
Este repositório é o núcleo do ecossistema **NEORICALEX**.
|
||||
Ele atua como um **gerenciador modular** capaz de clonar, atualizar e executar
|
||||
outros projetos (como `my_os` e `my_distro`), integrando-os sob uma mesma estrutura.
|
||||
|
||||
🧩 **Build system:** GNU Autotools + Python
|
||||
🧠 **Função:** Sistema de orquestração dos módulos NEORICALEX
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Requerimentos
|
||||
|
||||
Antes de começar, certifique-se de ter instaladas as dependências principais:
|
||||
|
||||
### 🧱 Sistema e Build
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y \
|
||||
autoconf automake libtool \
|
||||
build-essential pkg-config \
|
||||
git python3 python3-venv python3-pip \
|
||||
make
|
||||
```
|
||||
|
||||
## Passos
|
||||
|
||||
1. Execute `aclocal` para criar **aclocal.m4** e o diretório **autom4te.cache/**.
|
||||
2. Execute `autoconf` para gerar o script **configure**.
|
||||
3. Execute `automake --add-missing` para criar os ficheiros **Makefile.in**.
|
||||
4. Execute `./configure` para gerar os ficheiros **Makefile**.
|
||||
5. Execute `make` para compilar e criar o executável.
|
||||
6. Execute `src/neoricalex` para correr o executável.
|
||||
|
||||
## Alvos Extras
|
||||
make git # commit + push automático
|
||||
make tarball # gera dist/neoricalex-src.tar.gz
|
||||
make release # publica release e cria tag automática
|
||||
|
||||
|
||||
16
configure.ac
Normal file
16
configure.ac
Normal file
@ -0,0 +1,16 @@
|
||||
AC_INIT([NEORICALEX], [0.1], [https://gitea.neoricalex.com/neo/neoricalex.git])
|
||||
AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip])
|
||||
AM_PATH_PYTHON([3.0])
|
||||
|
||||
# Diretórios base
|
||||
AC_SUBST([BUILD_DIR], [${abs_top_builddir}/build])
|
||||
AC_SUBST([DIST_DIR], [${abs_top_builddir}/dist])
|
||||
AC_SUBST([SRC_TAR], [${abs_top_builddir}/dist/neoricalex-${PACKAGE_VERSION}-src.tar.gz])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
src/Makefile
|
||||
src/manager/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
14
src/Makefile.am
Normal file
14
src/Makefile.am
Normal file
@ -0,0 +1,14 @@
|
||||
SUBDIRS = manager
|
||||
|
||||
bin_SCRIPTS = neoricalex
|
||||
CLEANFILES = $(bin_SCRIPTS)
|
||||
EXTRA_DIST = neoricalex.in
|
||||
|
||||
do_substitution = sed -e 's,[@]pythondir[@],$(pythondir),g' \
|
||||
-e 's,[@]PACKAGE[@],$(PACKAGE),g' \
|
||||
-e 's,[@]VERSION[@],$(VERSION),g'
|
||||
|
||||
neoricalex: neoricalex.in Makefile
|
||||
@which git >/dev/null || { echo "⚠️ Git não encontrado — instale-o manualmente."; exit 1; }
|
||||
$(do_substitution) < $(srcdir)/neoricalex.in > neoricalex
|
||||
chmod +x neoricalex
|
||||
39
src/bootstrap.py
Normal file
39
src/bootstrap.py
Normal file
@ -0,0 +1,39 @@
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
class Application(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
for key in kwargs:
|
||||
setattr(self, key, kwargs[key])
|
||||
self._hello()
|
||||
|
||||
def _hello(self):
|
||||
print(f"NEORICALEX {getattr(self, 'version', '')} — inicializador de ambiente")
|
||||
|
||||
def run(self):
|
||||
self._ensure_venv()
|
||||
self.launch_welcome()
|
||||
|
||||
def _ensure_venv(self):
|
||||
"""Cria e ativa o ambiente virtual, caso ainda não exista."""
|
||||
base_path = Path(__file__).resolve().parents[1]
|
||||
venv_path = base_path / "venv"
|
||||
os.chdir(base_path)
|
||||
|
||||
if not venv_path.exists():
|
||||
print("[+] Criando ambiente virtual...")
|
||||
subprocess.run([sys.executable, "-m", "venv", str(venv_path)], check=True)
|
||||
else:
|
||||
print("[=] Ambiente virtual já existente.")
|
||||
|
||||
|
||||
def launch_welcome(self):
|
||||
"""Lança o gestor de módulos."""
|
||||
base_path = Path(__file__).resolve().parent
|
||||
manager = base_path / "manager" / "manager_main.py"
|
||||
subprocess.run(["python3", str(manager)])
|
||||
|
||||
|
||||
11
src/manager/Makefile.am
Normal file
11
src/manager/Makefile.am
Normal file
@ -0,0 +1,11 @@
|
||||
# Python sources
|
||||
neoricalex_PYTHON = \
|
||||
manager_main.py \
|
||||
manifest_parser.py \
|
||||
module_loader.py \
|
||||
tui_manager.py \
|
||||
__init__.py \
|
||||
../bootstrap.py
|
||||
|
||||
neoricalexdir = $(pythondir)
|
||||
|
||||
0
src/manager/__init__.py
Normal file
0
src/manager/__init__.py
Normal file
81
src/manager/manager_main.py
Normal file
81
src/manager/manager_main.py
Normal file
@ -0,0 +1,81 @@
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
from pathlib import Path
|
||||
import os, subprocess, json
|
||||
|
||||
console = Console()
|
||||
BASE_DIR = Path(__file__).resolve().parents[2]
|
||||
MODULES_FILE = BASE_DIR / "src" / "modules.json"
|
||||
MODULES_DIR = BASE_DIR / "src" / "modules"
|
||||
|
||||
def load_modules():
|
||||
if MODULES_FILE.exists():
|
||||
with open(MODULES_FILE) as f:
|
||||
data = json.load(f)
|
||||
return data.get("modules", [])
|
||||
return []
|
||||
|
||||
def clone_module(mod):
|
||||
path = Path(mod["path"])
|
||||
if not path.exists():
|
||||
console.print(f"[cyan]📦 Clonando {mod['name']}...[/cyan]")
|
||||
subprocess.run(["git", "clone", mod["repo"], str(path)], check=True)
|
||||
else:
|
||||
console.print(f"[yellow]✔ {mod['name']} já existe localmente.[/yellow]")
|
||||
|
||||
def update_module(mod):
|
||||
path = Path(mod["path"])
|
||||
if path.exists():
|
||||
console.print(f"[blue]🔄 Atualizando {mod['name']}...[/blue]")
|
||||
subprocess.run(["git", "-C", str(path), "pull"], check=True)
|
||||
else:
|
||||
console.print(f"[red]⚠ Módulo {mod['name']} não encontrado![/red]")
|
||||
|
||||
def run_module(mod):
|
||||
path = Path(mod["path"])
|
||||
if not path.exists():
|
||||
console.print(f"[red]❌ Módulo {mod['name']} não encontrado.[/red]")
|
||||
return
|
||||
console.print(f"[green]🚀 Executando {mod['name']}...[/green]")
|
||||
subprocess.run(mod["entrypoint"], cwd=path, shell=True)
|
||||
|
||||
def menu():
|
||||
modules = load_modules()
|
||||
while True:
|
||||
console.clear()
|
||||
table = Table(title="NEORICALEX – System Manager")
|
||||
table.add_column("ID", justify="center")
|
||||
table.add_column("Módulo")
|
||||
table.add_column("Ação")
|
||||
|
||||
for i, mod in enumerate(modules, start=1):
|
||||
table.add_row(str(i), mod["name"], mod["repo"])
|
||||
table.add_row("0", "Sair", "")
|
||||
|
||||
console.print(table)
|
||||
choice = console.input("[cyan]\nSelecione um módulo> [/cyan]")
|
||||
|
||||
if choice == "0":
|
||||
break
|
||||
if not choice.isdigit() or int(choice) > len(modules):
|
||||
continue
|
||||
|
||||
mod = modules[int(choice)-1]
|
||||
console.print(f"[bold yellow]Selecionado:[/bold yellow] {mod['name']}")
|
||||
console.print("[1] Executar [2] Atualizar [3] Reinstalar [0] Voltar")
|
||||
sub = console.input("[cyan]> [/cyan]")
|
||||
|
||||
if sub == "1":
|
||||
run_module(mod)
|
||||
elif sub == "2":
|
||||
update_module(mod)
|
||||
elif sub == "3":
|
||||
if Path(mod["path"]).exists():
|
||||
subprocess.run(["rm", "-rf", mod["path"]])
|
||||
clone_module(mod)
|
||||
else:
|
||||
continue
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.makedirs(MODULES_DIR, exist_ok=True)
|
||||
menu()
|
||||
0
src/manager/manifest_parser.py
Normal file
0
src/manager/manifest_parser.py
Normal file
0
src/manager/module_loader.py
Normal file
0
src/manager/module_loader.py
Normal file
0
src/manager/tui_manager.py
Normal file
0
src/manager/tui_manager.py
Normal file
16
src/modules.json
Normal file
16
src/modules.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"modules": [
|
||||
{
|
||||
"name": "my_os",
|
||||
"repo": "https://gitea.neoricalex.com/neo/my_os.git",
|
||||
"path": "src/modules/my_os",
|
||||
"entrypoint": "python3 tui/menu_main.py"
|
||||
},
|
||||
{
|
||||
"name": "my_distro",
|
||||
"repo": "https://gitea.neoricalex.com/neo/my_distro.git",
|
||||
"path": "src/modules/my_distro",
|
||||
"entrypoint": "bash build.sh"
|
||||
}
|
||||
]
|
||||
}
|
||||
11
src/neoricalex
Executable file
11
src/neoricalex
Executable file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
sys.path.insert(1, '/usr/local/local/lib/python3.12/dist-packages')
|
||||
|
||||
from bootstrap import Application
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application(package="neoricalex", version="0.1")
|
||||
app.run()
|
||||
|
||||
11
src/neoricalex.in
Normal file
11
src/neoricalex.in
Normal file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
sys.path.insert(1, '@pythondir@')
|
||||
|
||||
from bootstrap import Application
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application(package="@PACKAGE@", version="@VERSION@")
|
||||
app.run()
|
||||
|
||||
1
src/requirements.txt
Normal file
1
src/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
rich
|
||||
Loading…
Reference in New Issue
Block a user