flutter-setup 2.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flutter_setup/__init__.py +0 -0
- flutter_setup/bootstrap.py +904 -0
- flutter_setup/cicd_generator.py +814 -0
- flutter_setup/cli.py +662 -0
- flutter_setup/config.py +135 -0
- flutter_setup/config_manager.py +159 -0
- flutter_setup/core.py +204 -0
- flutter_setup/exceptions.py +37 -0
- flutter_setup/flutter_manager.py +579 -0
- flutter_setup/platform.py +15 -0
- flutter_setup/prerequisites.py +39 -0
- flutter_setup/prerequisites_linux.py +140 -0
- flutter_setup/prerequisites_macos.py +226 -0
- flutter_setup/project_creator.py +82 -0
- flutter_setup-2.1.0.dist-info/METADATA +365 -0
- flutter_setup-2.1.0.dist-info/RECORD +20 -0
- flutter_setup-2.1.0.dist-info/WHEEL +5 -0
- flutter_setup-2.1.0.dist-info/entry_points.txt +2 -0
- flutter_setup-2.1.0.dist-info/licenses/LICENSE +21 -0
- flutter_setup-2.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""Linux prerequisites management for Flutter setup."""
|
|
2
|
+
|
|
3
|
+
import shutil
|
|
4
|
+
import subprocess
|
|
5
|
+
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
|
|
8
|
+
from .config import Config
|
|
9
|
+
from .exceptions import PrerequisitesError
|
|
10
|
+
|
|
11
|
+
console = Console()
|
|
12
|
+
|
|
13
|
+
# Core system utilities
|
|
14
|
+
CORE_PACKAGES = [
|
|
15
|
+
"git",
|
|
16
|
+
"curl",
|
|
17
|
+
"unzip",
|
|
18
|
+
"xz-utils",
|
|
19
|
+
"zip",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
# Linux desktop development requirements
|
|
23
|
+
LINUX_DESKTOP_PACKAGES = [
|
|
24
|
+
"libglu1-mesa",
|
|
25
|
+
"clang",
|
|
26
|
+
"cmake",
|
|
27
|
+
"ninja-build",
|
|
28
|
+
"pkg-config",
|
|
29
|
+
"libgtk-3-dev",
|
|
30
|
+
"libayatana-appindicator3-dev",
|
|
31
|
+
"liblzma-dev",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
# Android development requirements
|
|
35
|
+
ANDROID_PACKAGES = [
|
|
36
|
+
"openjdk-17-jdk",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class LinuxPrerequisites:
|
|
41
|
+
"""Manages Linux prerequisites for Flutter development."""
|
|
42
|
+
|
|
43
|
+
def __init__(self, config: Config):
|
|
44
|
+
"""Initialize Linux prerequisites manager."""
|
|
45
|
+
self.config = config
|
|
46
|
+
self._check_package_manager()
|
|
47
|
+
|
|
48
|
+
def _check_package_manager(self) -> None:
|
|
49
|
+
"""Ensure we are on a supported Debian-based system with APT."""
|
|
50
|
+
if not shutil.which("apt-get") or not shutil.which("dpkg"):
|
|
51
|
+
raise PrerequisitesError(
|
|
52
|
+
"Unsupported Linux distribution. Only Debian-based distributions (using APT) are currently supported for automated prerequisite installation."
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def check_and_install(self) -> None:
|
|
56
|
+
"""Check and install Linux prerequisites."""
|
|
57
|
+
if self.config.dry_run:
|
|
58
|
+
console.print(
|
|
59
|
+
"[yellow]DRY RUN: Would check and install Linux prerequisites[/yellow]"
|
|
60
|
+
)
|
|
61
|
+
console.print(
|
|
62
|
+
f"[yellow]DRY RUN: Would run: {self.install_command()}[/yellow]"
|
|
63
|
+
)
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
missing = self._missing_packages()
|
|
67
|
+
if missing:
|
|
68
|
+
console.print(f" π¦ Missing Linux packages: {', '.join(missing)}")
|
|
69
|
+
console.print(" π§ Installing Linux prerequisites via APT...")
|
|
70
|
+
try:
|
|
71
|
+
subprocess.run(["sudo", "apt-get", "update"], check=True)
|
|
72
|
+
subprocess.run(
|
|
73
|
+
["sudo", "apt-get", "install", "-y", *missing],
|
|
74
|
+
check=True,
|
|
75
|
+
)
|
|
76
|
+
console.print(" β
Linux prerequisites installed")
|
|
77
|
+
except subprocess.CalledProcessError as e:
|
|
78
|
+
raise PrerequisitesError(f"Failed to install Linux prerequisites: {e}")
|
|
79
|
+
else:
|
|
80
|
+
console.print(" β
Linux prerequisites already installed")
|
|
81
|
+
|
|
82
|
+
if "android" in self.config.platforms:
|
|
83
|
+
self._setup_android_tools()
|
|
84
|
+
|
|
85
|
+
def _setup_android_tools(self) -> None:
|
|
86
|
+
"""Additional Android toolchain setup instructions."""
|
|
87
|
+
console.print(" π€ Android JDK installed (openjdk-17-jdk)")
|
|
88
|
+
console.print(
|
|
89
|
+
" βΉοΈ Note: You may still need to install Android Command Line Tools manually"
|
|
90
|
+
)
|
|
91
|
+
console.print(
|
|
92
|
+
" βΉοΈ Download from: https://developer.android.com/studio#command-tools"
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
def _get_required_packages(self) -> list[str]:
|
|
96
|
+
"""Get the full list of required packages based on target platforms."""
|
|
97
|
+
packages = list(CORE_PACKAGES)
|
|
98
|
+
|
|
99
|
+
if "linux" in self.config.platforms:
|
|
100
|
+
packages.extend(LINUX_DESKTOP_PACKAGES)
|
|
101
|
+
|
|
102
|
+
if "android" in self.config.platforms:
|
|
103
|
+
packages.extend(ANDROID_PACKAGES)
|
|
104
|
+
|
|
105
|
+
return sorted(list(set(packages)))
|
|
106
|
+
|
|
107
|
+
def install_command(self) -> str:
|
|
108
|
+
"""Return the APT command users can run manually."""
|
|
109
|
+
packages = self._get_required_packages()
|
|
110
|
+
return f"sudo apt-get update && sudo apt-get install -y {' '.join(packages)}"
|
|
111
|
+
|
|
112
|
+
def _missing_packages(self) -> list[str]:
|
|
113
|
+
"""Return missing APT packages."""
|
|
114
|
+
required = self._get_required_packages()
|
|
115
|
+
missing: list[str] = []
|
|
116
|
+
for package in required:
|
|
117
|
+
if not self._is_package_installed(package):
|
|
118
|
+
missing.append(package)
|
|
119
|
+
return missing
|
|
120
|
+
|
|
121
|
+
def _is_package_installed(self, package: str) -> bool:
|
|
122
|
+
"""Check whether a package is installed via dpkg."""
|
|
123
|
+
result = subprocess.run(
|
|
124
|
+
["dpkg", "-s", package],
|
|
125
|
+
capture_output=True,
|
|
126
|
+
text=True,
|
|
127
|
+
check=False,
|
|
128
|
+
)
|
|
129
|
+
return result.returncode == 0
|
|
130
|
+
|
|
131
|
+
def check_only(self) -> bool:
|
|
132
|
+
"""Check Linux prerequisites without installing."""
|
|
133
|
+
missing = self._missing_packages()
|
|
134
|
+
if not missing:
|
|
135
|
+
console.print(" β
Linux prerequisites found")
|
|
136
|
+
return True
|
|
137
|
+
|
|
138
|
+
console.print(f" β Missing Linux prerequisites: {', '.join(missing)}")
|
|
139
|
+
console.print(f" βΉοΈ Install with: {self.install_command()}")
|
|
140
|
+
return False
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"""macOS prerequisites management for Flutter setup."""
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
|
|
8
|
+
from .config import Config
|
|
9
|
+
from .exceptions import PrerequisitesError
|
|
10
|
+
|
|
11
|
+
console = Console()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MacOSPrerequisites:
|
|
15
|
+
"""Manages macOS prerequisites for Flutter development."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, config: Config):
|
|
18
|
+
"""Initialize macOS prerequisites manager."""
|
|
19
|
+
self.config = config
|
|
20
|
+
self.home = Path.home()
|
|
21
|
+
|
|
22
|
+
def check_and_install(self) -> None:
|
|
23
|
+
"""Check and install all required prerequisites."""
|
|
24
|
+
if self.config.dry_run:
|
|
25
|
+
console.print(
|
|
26
|
+
"[yellow]DRY RUN: Would check and install macOS prerequisites[/yellow]"
|
|
27
|
+
)
|
|
28
|
+
return
|
|
29
|
+
|
|
30
|
+
self._check_xcode_tools()
|
|
31
|
+
self._check_homebrew()
|
|
32
|
+
self._install_packages()
|
|
33
|
+
self._setup_platform_tools()
|
|
34
|
+
|
|
35
|
+
def _check_xcode_tools(self) -> None:
|
|
36
|
+
"""Check and install Xcode Command Line Tools."""
|
|
37
|
+
console.print(" π± Checking Xcode Command Line Tools...")
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
result = subprocess.run(
|
|
41
|
+
["xcode-select", "-p"], capture_output=True, text=True, check=False
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
if result.returncode != 0:
|
|
45
|
+
console.print(" β οΈ Xcode Command Line Tools not found, installing...")
|
|
46
|
+
subprocess.run(["xcode-select", "--install"], check=True)
|
|
47
|
+
console.print(" β
Xcode Command Line Tools installation initiated")
|
|
48
|
+
console.print(
|
|
49
|
+
" βΉοΈ Please complete the installation in the popup window"
|
|
50
|
+
)
|
|
51
|
+
console.print(
|
|
52
|
+
" βΉοΈ You may need to restart the setup after installation"
|
|
53
|
+
)
|
|
54
|
+
raise PrerequisitesError(
|
|
55
|
+
"Xcode Command Line Tools installation required"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
console.print(" β
Xcode Command Line Tools found")
|
|
59
|
+
except subprocess.CalledProcessError as e:
|
|
60
|
+
raise PrerequisitesError(f"Failed to check Xcode tools: {e}")
|
|
61
|
+
|
|
62
|
+
def _check_homebrew(self) -> None:
|
|
63
|
+
"""Check and install Homebrew."""
|
|
64
|
+
console.print(" πΊ Checking Homebrew...")
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
result = subprocess.run(
|
|
68
|
+
["brew", "--version"], capture_output=True, text=True, check=False
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if result.returncode != 0:
|
|
72
|
+
console.print(" β οΈ Homebrew not found, installing...")
|
|
73
|
+
self._install_homebrew()
|
|
74
|
+
else:
|
|
75
|
+
console.print(" β
Homebrew found")
|
|
76
|
+
self._ensure_homebrew_path()
|
|
77
|
+
except subprocess.CalledProcessError as e:
|
|
78
|
+
raise PrerequisitesError(f"Failed to check Homebrew: {e}")
|
|
79
|
+
|
|
80
|
+
def _install_homebrew(self) -> None:
|
|
81
|
+
"""Install Homebrew."""
|
|
82
|
+
try:
|
|
83
|
+
install_script = (
|
|
84
|
+
"https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh"
|
|
85
|
+
)
|
|
86
|
+
subprocess.run(
|
|
87
|
+
["/bin/bash", "-c", f'curl -fsSL "{install_script}" | bash'],
|
|
88
|
+
env={"NONINTERACTIVE": "1"},
|
|
89
|
+
check=True,
|
|
90
|
+
)
|
|
91
|
+
console.print(" β
Homebrew installed")
|
|
92
|
+
self._ensure_homebrew_path()
|
|
93
|
+
except subprocess.CalledProcessError as e:
|
|
94
|
+
raise PrerequisitesError(f"Failed to install Homebrew: {e}")
|
|
95
|
+
|
|
96
|
+
def _ensure_homebrew_path(self) -> None:
|
|
97
|
+
"""Ensure Homebrew is in PATH."""
|
|
98
|
+
try:
|
|
99
|
+
if Path("/opt/homebrew/bin/brew").exists():
|
|
100
|
+
subprocess.run(["/opt/homebrew/bin/brew", "shellenv"], check=True)
|
|
101
|
+
console.print(" β
Homebrew path configured")
|
|
102
|
+
except subprocess.CalledProcessError:
|
|
103
|
+
console.print(
|
|
104
|
+
" β οΈ Homebrew path configuration failed (may need manual setup)"
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
def _install_packages(self) -> None:
|
|
108
|
+
"""Install required packages via Homebrew."""
|
|
109
|
+
required_packages = ["git", "cocoapods"]
|
|
110
|
+
|
|
111
|
+
for package in required_packages:
|
|
112
|
+
console.print(f" π¦ Installing {package}...")
|
|
113
|
+
try:
|
|
114
|
+
subprocess.run(
|
|
115
|
+
["brew", "install", package], check=True, capture_output=True
|
|
116
|
+
)
|
|
117
|
+
console.print(f" β
{package} installed")
|
|
118
|
+
except subprocess.CalledProcessError as e:
|
|
119
|
+
result = subprocess.run(
|
|
120
|
+
["brew", "list", package],
|
|
121
|
+
capture_output=True,
|
|
122
|
+
text=True,
|
|
123
|
+
check=False,
|
|
124
|
+
)
|
|
125
|
+
if result.returncode == 0:
|
|
126
|
+
console.print(f" β
{package} already installed")
|
|
127
|
+
else:
|
|
128
|
+
raise PrerequisitesError(f"Failed to install {package}: {e}")
|
|
129
|
+
|
|
130
|
+
def _setup_platform_tools(self) -> None:
|
|
131
|
+
"""Setup platform-specific development tools."""
|
|
132
|
+
if "android" in self.config.platforms:
|
|
133
|
+
self._setup_android_tools()
|
|
134
|
+
if "ios" in self.config.platforms:
|
|
135
|
+
self._setup_ios_tools()
|
|
136
|
+
|
|
137
|
+
def _setup_android_tools(self) -> None:
|
|
138
|
+
"""Setup Android development tools."""
|
|
139
|
+
console.print(" π€ Setting up Android development tools...")
|
|
140
|
+
|
|
141
|
+
android_packages = [
|
|
142
|
+
("--cask", "temurin"),
|
|
143
|
+
("--cask", "android-commandlinetools"),
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
for args in android_packages:
|
|
147
|
+
package = args[1]
|
|
148
|
+
try:
|
|
149
|
+
subprocess.run(
|
|
150
|
+
["brew", "install"] + list(args), check=True, capture_output=True
|
|
151
|
+
)
|
|
152
|
+
console.print(f" β
{package} installed")
|
|
153
|
+
except subprocess.CalledProcessError as e:
|
|
154
|
+
result = subprocess.run(
|
|
155
|
+
["brew", "list", "--cask", package],
|
|
156
|
+
capture_output=True,
|
|
157
|
+
text=True,
|
|
158
|
+
check=False,
|
|
159
|
+
)
|
|
160
|
+
if result.returncode == 0:
|
|
161
|
+
console.print(f" β
{package} already installed")
|
|
162
|
+
else:
|
|
163
|
+
console.print(f" β οΈ Failed to install {package}: {e}")
|
|
164
|
+
|
|
165
|
+
def _setup_ios_tools(self) -> None:
|
|
166
|
+
"""Setup iOS development tools."""
|
|
167
|
+
console.print(" π Setting up iOS development tools...")
|
|
168
|
+
|
|
169
|
+
try:
|
|
170
|
+
subprocess.run(["pod", "repo", "update"], check=False, capture_output=True)
|
|
171
|
+
console.print(" β
iOS tools configured")
|
|
172
|
+
except Exception as e:
|
|
173
|
+
console.print(f" β οΈ iOS tools configuration warning: {e}")
|
|
174
|
+
|
|
175
|
+
def check_only(self) -> bool:
|
|
176
|
+
"""Check prerequisites without installing."""
|
|
177
|
+
all_ok = True
|
|
178
|
+
|
|
179
|
+
console.print(" π± Checking Xcode Command Line Tools...")
|
|
180
|
+
try:
|
|
181
|
+
result = subprocess.run(
|
|
182
|
+
["xcode-select", "-p"], capture_output=True, text=True, check=False
|
|
183
|
+
)
|
|
184
|
+
if result.returncode == 0:
|
|
185
|
+
console.print(" β
Xcode Command Line Tools found")
|
|
186
|
+
else:
|
|
187
|
+
console.print(" β Xcode Command Line Tools not found")
|
|
188
|
+
all_ok = False
|
|
189
|
+
except Exception as e:
|
|
190
|
+
console.print(f" β Failed to check Xcode tools: {e}")
|
|
191
|
+
all_ok = False
|
|
192
|
+
|
|
193
|
+
console.print(" πΊ Checking Homebrew...")
|
|
194
|
+
try:
|
|
195
|
+
result = subprocess.run(
|
|
196
|
+
["brew", "--version"], capture_output=True, text=True, check=False
|
|
197
|
+
)
|
|
198
|
+
if result.returncode == 0:
|
|
199
|
+
console.print(" β
Homebrew found")
|
|
200
|
+
else:
|
|
201
|
+
console.print(" β Homebrew not found")
|
|
202
|
+
all_ok = False
|
|
203
|
+
except Exception as e:
|
|
204
|
+
console.print(f" β Failed to check Homebrew: {e}")
|
|
205
|
+
all_ok = False
|
|
206
|
+
|
|
207
|
+
required_packages = ["git", "cocoapods"]
|
|
208
|
+
for package in required_packages:
|
|
209
|
+
console.print(f" π¦ Checking {package}...")
|
|
210
|
+
try:
|
|
211
|
+
result = subprocess.run(
|
|
212
|
+
["brew", "list", package],
|
|
213
|
+
capture_output=True,
|
|
214
|
+
text=True,
|
|
215
|
+
check=False,
|
|
216
|
+
)
|
|
217
|
+
if result.returncode == 0:
|
|
218
|
+
console.print(f" β
{package} installed")
|
|
219
|
+
else:
|
|
220
|
+
console.print(f" β {package} not installed")
|
|
221
|
+
all_ok = False
|
|
222
|
+
except Exception as e:
|
|
223
|
+
console.print(f" β Failed to check {package}: {e}")
|
|
224
|
+
all_ok = False
|
|
225
|
+
|
|
226
|
+
return all_ok
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""Project creation for Flutter setup."""
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
from typing import List
|
|
5
|
+
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
|
|
8
|
+
from .config import Config
|
|
9
|
+
from .exceptions import ProjectCreationError
|
|
10
|
+
|
|
11
|
+
console = Console()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ProjectCreator:
|
|
15
|
+
"""Creates Flutter projects with specified configuration."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, config: Config):
|
|
18
|
+
"""Initialize ProjectCreator."""
|
|
19
|
+
self.config = config
|
|
20
|
+
self.flutter_root = config.flutter_location
|
|
21
|
+
|
|
22
|
+
def create_project(self) -> None:
|
|
23
|
+
"""Create the Flutter project."""
|
|
24
|
+
if self.config.dry_run:
|
|
25
|
+
console.print("[yellow]DRY RUN: Would create Flutter project[/yellow]")
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
# Check if project already exists
|
|
29
|
+
if self.config.project_path.exists():
|
|
30
|
+
console.print(
|
|
31
|
+
f" β οΈ Directory '{self.config.project_path}' existsβskipping create."
|
|
32
|
+
)
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
# Create output directory
|
|
36
|
+
self.config.output_dir.mkdir(parents=True, exist_ok=True)
|
|
37
|
+
|
|
38
|
+
# Build flutter create command
|
|
39
|
+
create_cmd = self._build_create_command()
|
|
40
|
+
|
|
41
|
+
# Execute flutter create
|
|
42
|
+
console.print(
|
|
43
|
+
f" ποΈ Creating Flutter project at {self.config.project_path}..."
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
subprocess.run(create_cmd, check=True, capture_output=True, text=True)
|
|
48
|
+
console.print(f" β
Project created at: {self.config.project_path}")
|
|
49
|
+
|
|
50
|
+
except subprocess.CalledProcessError as e:
|
|
51
|
+
raise ProjectCreationError(f"Failed to create project: {e}")
|
|
52
|
+
|
|
53
|
+
def _build_create_command(self) -> List[str]:
|
|
54
|
+
"""Build the flutter create command."""
|
|
55
|
+
cmd = [
|
|
56
|
+
str(self.flutter_root / "bin" / "flutter"),
|
|
57
|
+
"create",
|
|
58
|
+
"--org",
|
|
59
|
+
self.config.org,
|
|
60
|
+
"--project-name",
|
|
61
|
+
self.config.package_name,
|
|
62
|
+
"--platforms",
|
|
63
|
+
self.config.platforms_csv,
|
|
64
|
+
"--template",
|
|
65
|
+
self.config.template,
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
# Add template-specific options
|
|
69
|
+
if self.config.template == "plugin":
|
|
70
|
+
cmd.extend(
|
|
71
|
+
[
|
|
72
|
+
"--ios-language",
|
|
73
|
+
self.config.ios_language,
|
|
74
|
+
"--android-language",
|
|
75
|
+
self.config.android_language,
|
|
76
|
+
]
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Add output path
|
|
80
|
+
cmd.append(str(self.config.project_path))
|
|
81
|
+
|
|
82
|
+
return cmd
|