Last active
July 3, 2025 07:46
-
-
Save ilfuriano/7739d6933bac82e780facd1ac3f06e36 to your computer and use it in GitHub Desktop.
Flutter Helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# --- fh.sh - Un helper per i comandi Flutter con FVM e Flavors --- | |
# Versione con ridenominazione, rilevamento FVM e conversione nomi flavor (snake_case -> camelCase) PORTABILE. | |
# | |
# (Il resto dell'intestazione e i colori rimangono invariati) | |
# ... | |
GREEN='\033[0;32m' | |
YELLOW='\033[1;33m' | |
RED='\033[0;31m' | |
NC='\033[0m' | |
# --- Estrazione del nome del progetto da pubspec.yaml --- | |
# (invariato) | |
if [ ! -f "pubspec.yaml" ]; then | |
echo -e "${RED}Errore: file 'pubspec.yaml' non trovato.${NC}" | |
echo "Assicurati di eseguire questo script dalla directory principale del tuo progetto Flutter." | |
exit 1 | |
fi | |
PROJECT_NAME=$(grep '^[[:space:]]*name:' pubspec.yaml | cut -d ':' -f 2 | xargs) | |
if [ -z "$PROJECT_NAME" ]; then | |
echo -e "${RED}Errore: Impossibile estrarre il nome del progetto da pubspec.yaml.${NC}" | |
exit 1 | |
fi | |
echo -e "${GREEN}Progetto rilevato: ${YELLOW}${PROJECT_NAME}${NC}" | |
# --- Rilevamento automatico FVM --- | |
# (invariato) | |
FLUTTER_CMD="flutter" | |
DART_CMD="dart" | |
if [ -d ".fvm" ]; then | |
if command -v fvm &> /dev/null; then | |
FLUTTER_CMD="fvm flutter" | |
DART_CMD="fvm dart" | |
echo -e "${GREEN}Rilevata configurazione FVM. I comandi useranno '${YELLOW}fvm${GREEN}'.${NC}" | |
else | |
echo -e "${YELLOW}Attenzione: Trovata directory '.fvm' ma il comando 'fvm' non è nel PATH.${NC}" | |
echo -e "Verrà usato il Flutter di sistema." | |
fi | |
else | |
echo -e "${GREEN}Nessuna configurazione FVM rilevata. Verrà usato il Flutter/Dart di sistema.${NC}" | |
fi | |
echo "-----------------------------------------------------" | |
# --- NUOVO: Funzioni di conversione nome (versione portabile) --- | |
# Converte una stringa da snake_case (es. dev_ios) a camelCase (es. devIos) | |
# Usa awk per la massima portabilità (funziona su Linux e macOS) | |
to_camel_case() { | |
echo "$1" | awk -F"_" '{for(i=2;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2); print}' OFS="" | |
} | |
# Converte una stringa da camelCase (es. devIos) a snake_case (es. dev_ios) | |
# Questa funzione con sed è già portabile | |
to_snake_case() { | |
echo "$1" | sed -e 's/\([A-Z]\)/_\1/g' -e 's/^_//' | tr '[:upper:]' '[:lower:]' | |
} | |
# --- Rilevamento automatico dei Flavor con conversione a camelCase --- | |
# (La logica qui rimane invariata, ma ora usa la funzione corretta) | |
if [ ! -d "lib" ]; then | |
echo -e "${RED}Errore: La directory 'lib' non è stata trovata.${NC}" | |
exit 1 | |
fi | |
FLAVORS=() | |
for f in lib/main_*.dart; do | |
[ -e "$f" ] || continue | |
flavor_name_base=$(basename "$f" .dart) | |
snake_case_flavor=${flavor_name_base#main_} | |
camel_case_flavor=$(to_camel_case "$snake_case_flavor") | |
FLAVORS+=("$camel_case_flavor") | |
done | |
# | |
# --- TUTTO IL RESTO DELLO SCRIPT RIMANE IDENTICO --- | |
# Le funzioni usage, rename_artifact, la logica dei comandi, ecc. | |
# non necessitano di modifiche perché si basano sulle funzioni | |
# di conversione che abbiamo appena corretto. | |
# | |
# --- Funzione di aiuto (Usage) --- | |
usage() { | |
echo -e "${GREEN}Flutter Helper (fh) - Gestione comandi, Flavors & Ridenominazione Artefatti${NC}" | |
echo -e "Lo script rileva automaticamente FVM e gestisce i nomi dei flavor in ${YELLOW}camelCase${NC}." | |
echo "" | |
echo -e "${YELLOW}Uso:${NC} ./fh.sh <comando> [flavor] [argomenti_extra...]" | |
echo " Esempio: ./fh.sh run devIos" | |
echo "" | |
echo -e "${YELLOW}Comandi disponibili:${NC}" | |
echo " run <flavor> Esegue 'flutter run' per il flavor specificato." | |
echo " apk <flavor> Crea un APK, poi lo rinomina." | |
echo " appbundle <flavor> Crea un AppBundle, poi lo rinomina." | |
echo " ipa <flavor> Crea un IPA per iOS (non rinominato)." | |
echo " apk-all Crea e rinomina un APK per tutti i flavor." | |
echo " appbundle-all Crea e rinomina un AppBundle per tutti i flavor." | |
echo " runner Esegue 'dart run build_runner build ...'." | |
echo " clean Esegue 'flutter clean'." | |
echo " get Esegue 'flutter pub get'." | |
echo " help Mostra questo messaggio." | |
echo "" | |
if [ ${#FLAVORS[@]} -gt 0 ]; then | |
echo -e "${YELLOW}Flavor rilevati (in notazione camelCase):${NC}" | |
for flavor in "${FLAVORS[@]}"; do | |
original_file="main_$(to_snake_case "$flavor").dart" | |
echo " - ${flavor} (da ${original_file})" | |
done | |
else | |
echo -e "${RED}Attenzione: Nessun flavor (file main_<flavor>.dart) trovato in lib/.${NC}" | |
fi | |
echo "" | |
} | |
# --- Funzione per rinominare l'artefatto di build --- | |
rename_artifact() { | |
local build_type=$1 | |
local camel_case_flavor=$2 | |
local snake_case_flavor=$(to_snake_case "$camel_case_flavor") | |
shift 2 | |
local extra_args_str="$*" | |
local build_mode="debug" | |
if [[ " ${extra_args_str} " =~ " --release " ]]; then | |
build_mode="release" | |
fi | |
local timestamp=$(date +'%Y%m%d-%H%M%S') | |
local original_path="" | |
local extension="" | |
if [ "$build_type" == "apk" ]; then | |
extension="apk" | |
if [ "$build_mode" == "release" ]; then | |
original_path="build/app/outputs/flutter-apk/app-${snake_case_flavor}-${build_mode}.apk" | |
else | |
original_path="build/app/outputs/flutter-apk/app-${build_mode}.apk" | |
fi | |
elif [ "$build_type" == "appbundle" ]; then | |
extension="aab" | |
original_path="build/app/outputs/bundle/${snake_case_flavor}${build_mode^}/app-${snake_case_flavor}-${build_mode}.aab" | |
if [ ! -f "$original_path" ]; then | |
original_path="build/app/outputs/bundle/${snake_case_flavor}Release/app.aab" | |
fi | |
else | |
return | |
fi | |
if [ -f "$original_path" ]; then | |
local new_filename="${PROJECT_NAME}-${camel_case_flavor}-${timestamp}.${extension}" | |
mv "$original_path" "./$new_filename" | |
echo -e "${GREEN}Build completata e artefatto rinominato in: ${YELLOW}${new_filename}${NC}" | |
else | |
echo -e "${RED}Attenzione: Artefatto non trovato in '$original_path'. La ridenominazione è fallita.${NC}" | |
fi | |
} | |
# --- Validazione Input e Logica Principale --- | |
if [ "$#" -lt 1 ] || [ "$1" == "help" ]; then | |
usage | |
exit 0 | |
fi | |
COMMAND=$1 | |
# --- Logica per comandi "all" --- | |
case "$COMMAND" in | |
apk-all|appbundle-all) | |
if [ ${#FLAVORS[@]} -eq 0 ]; then | |
echo -e "${RED}Errore: Nessun flavor trovato. Impossibile eseguire '$COMMAND'.${NC}" | |
exit 1 | |
fi | |
shift 1 | |
EXTRA_ARGS=("$@") | |
BUILD_TYPE=${COMMAND%-all} | |
echo -e "${GREEN}Inizio la build di '$BUILD_TYPE' per tutti i flavor...${NC}" | |
[ ${#EXTRA_ARGS[@]} -gt 0 ] && echo -e "${YELLOW}Argomenti extra:${NC} ${EXTRA_ARGS[*]}" | |
echo "-----------------------------------------------------" | |
for flavor_camel in "${FLAVORS[@]}"; do | |
echo -e "\n${GREEN}>>> Costruzione per il flavor: ${YELLOW}${flavor_camel}${NC}" | |
local flavor_snake=$(to_snake_case "$flavor_camel") | |
CMD_ARRAY=($FLUTTER_CMD build "$BUILD_TYPE" --flavor "$flavor_snake" -t "lib/main_${flavor_snake}.dart" "${EXTRA_ARGS[@]}") | |
echo -e "${YELLOW}Comando:${NC} ${CMD_ARRAY[*]}" | |
echo "---" | |
"${CMD_ARRAY[@]}" | |
if [ $? -eq 0 ]; then | |
rename_artifact "$BUILD_TYPE" "$flavor_camel" "${EXTRA_ARGS[@]}" | |
else | |
echo -e "${RED}Errore durante la build per il flavor '$flavor_camel'. Interruzione.${NC}" | |
exit 1 | |
fi | |
done | |
echo -e "\n${GREEN}Tutte le build sono state completate con successo!${NC}" | |
exit 0 | |
;; | |
esac | |
# --- Logica per comandi singoli --- | |
FLAVOR_CAMEL=$2 | |
shift 2 | |
EXTRA_ARGS=("$@") | |
is_valid_flavor() { | |
[[ " ${FLAVORS[*]} " =~ " $1 " ]] | |
} | |
require_flavor() { | |
if [ -z "$FLAVOR_CAMEL" ]; then | |
echo -e "${RED}Errore: Il comando '$COMMAND' richiede un flavor.${NC}"; usage; exit 1 | |
fi | |
if ! is_valid_flavor "$FLAVOR_CAMEL"; then | |
echo -e "${RED}Errore: Flavor '$FLAVOR_CAMEL' non valido.${NC}"; usage; exit 1 | |
fi | |
} | |
CMD_ARRAY=() | |
BUILD_TYPE="" | |
FLAVOR_SNAKE=$(to_snake_case "$FLAVOR_CAMEL") | |
case "$COMMAND" in | |
run) | |
require_flavor | |
CMD_ARRAY=($FLUTTER_CMD run --flavor "$FLAVOR_SNAKE" -t "lib/main_${FLAVOR_SNAKE}.dart" "${EXTRA_ARGS[@]}") | |
;; | |
apk|appbundle) | |
require_flavor | |
BUILD_TYPE=$COMMAND | |
CMD_ARRAY=($FLUTTER_CMD build "$BUILD_TYPE" --flavor "$FLAVOR_SNAKE" -t "lib/main_${FLAVOR_SNAKE}.dart" "${EXTRA_ARGS[@]}") | |
;; | |
ipa) | |
require_flavor | |
BUILD_TYPE="ipa" | |
CMD_ARRAY=($FLUTTER_CMD build ipa --flavor "$FLAVOR_SNAKE" -t "lib/main_${FLAVOR_SNAKE}.dart" "${EXTRA_ARGS[@]}") | |
;; | |
runner) | |
CMD_ARRAY=($DART_CMD run build_runner build --delete-conflicting-outputs "${EXTRA_ARGS[@]}") | |
;; | |
clean) | |
CMD_ARRAY=($FLUTTER_CMD clean) | |
;; | |
get) | |
CMD_ARRAY=($FLUTTER_CMD pub get) | |
;; | |
*) | |
echo -e "${RED}Errore: Comando '$COMMAND' non riconosciuto.${NC}"; usage; exit 1 | |
;; | |
esac | |
# Esecuzione del comando | |
echo -e "${YELLOW}Comando Eseguito:${NC} ${CMD_ARRAY[*]}" | |
echo "-----------------------------------------------------" | |
"${CMD_ARRAY[@]}" | |
# Ridenominazione artefatto | |
if [[ "$COMMAND" == "apk" || "$COMMAND" == "appbundle" ]]; then | |
if [ $? -eq 0 ]; then | |
rename_artifact "$BUILD_TYPE" "$FLAVOR_CAMEL" "${EXTRA_ARGS[@]}" | |
else | |
echo -e "${RED}Build fallita. Ridenominazione saltata.${NC}" | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Fixed flavor name calculation