Komutlar
Giriş
Komutlar, Nylo Website'nun CLI'sını projeye özel araçlarla genişletmenizi sağlar. NyCustomCommand alt sınıfını oluşturarak tekrarlayan görevleri otomatikleştirebilir, dağıtım iş akışları oluşturabilir, kod üretebilir veya ihtiyaç duyduğunuz herhangi bir işlevi doğrudan terminalinize ekleyebilirsiniz.
Her özel komut; dosya G/Ç, JSON/YAML, etkileşimli istemler, döndürücüler, ilerleme çubukları, API istekleri ve daha fazlası için zengin bir yerleşik yardımcı setine erişim sağlar -- ekstra paket içe aktarmaya gerek kalmadan.
Not: Özel komutlar Flutter çalışma zamanı dışında çalışır. Komutlarınızda
nylo_framework.dartdosyasını içe aktaramazsınız. Bunun yerineny_cli.dartkullanın.
Komut Oluşturma
Metro veya Dart CLI kullanarak yeni bir komut oluşturun:
metro make:command current_time
--category seçeneğini kullanarak komutunuz için bir kategori belirleyebilirsiniz:
metro make:command current_time --category="project"
Bu, lib/app/commands/current_time.dart konumunda yeni bir dosya oluşturur ve komut kaydına kaydeder.
Komut Yapısı
Her komut NyCustomCommand sınıfını genişletir ve iki temel metodu uygular:
builder()-- seçenekleri ve bayrakları yapılandırırhandle()-- komut mantığını yürütür
import 'package:nylo_framework/metro/ny_cli.dart';
void main(arguments) => _CurrentTimeCommand(arguments).run();
/// Current Time Command
///
/// Usage:
/// metro app:current_time
class _CurrentTimeCommand extends NyCustomCommand {
_CurrentTimeCommand(super.arguments);
@override
CommandBuilder builder(CommandBuilder command) {
command.addOption('format', defaultValue: 'HH:mm:ss');
return command;
}
@override
Future<void> handle(CommandResult result) async {
final format = result.getString("format");
info("Current time format: $format");
}
}
Komutları Çalıştırma
Metro veya Dart kullanarak komutunuzu çalıştırın:
metro app:current_time
Komut adı kategori:isim kalıbını izler. metro komutunu argümansız çalıştırdığınızda, özel komutlar Custom Commands bölümünde görünür:
[Custom Commands]
app:current_time
project:install_firebase
project:deploy
Bir komut için yardım bilgilerini görüntülemek için:
metro app:current_time --help
Komut Kaydı
Tüm özel komutlar lib/app/commands/commands.json dosyasında kayıtlıdır. Bu dosya, make:command kullandığınızda otomatik olarak güncellenir:
[
{
"name": "install_firebase",
"category": "project",
"script": "install_firebase.dart"
},
{
"name": "current_time",
"category": "app",
"script": "current_time.dart"
}
]
Her giriş şunları içerir:
| Alan | Açıklama |
|---|---|
name |
Komut adı (kategori önekinden sonra kullanılır) |
category |
Komut kategorisi (ör. app, project) |
script |
lib/app/commands/ içindeki Dart dosyası |
Seçenekler ve Bayraklar
Komutunuzun seçeneklerini ve bayraklarını builder() metodu içinde CommandBuilder kullanarak yapılandırın.
Seçenek Ekleme
Seçenekler kullanıcıdan bir değer kabul eder:
@override
CommandBuilder builder(CommandBuilder command) {
command.addOption(
'environment',
abbr: 'e',
help: 'Target deployment environment',
defaultValue: 'development',
allowed: ['development', 'staging', 'production'],
);
return command;
}
Kullanım:
metro project:deploy --environment=production
# or using abbreviation
metro project:deploy -e production
| Parametre | Tür | Açıklama |
|---|---|---|
name |
String |
Seçenek adı |
abbr |
String? |
Tek karakter kısaltma |
help |
String? |
--help ile gösterilen yardım metni |
allowed |
List<String>? |
İzin verilen değerlerle sınırla |
defaultValue |
String? |
Sağlanmazsa varsayılan değer |
Bayrak Ekleme
Bayraklar boolean değer anahtarlarıdır:
@override
CommandBuilder builder(CommandBuilder command) {
command.addFlag(
'verbose',
abbr: 'v',
help: 'Enable verbose output',
defaultValue: false,
);
return command;
}
Kullanım:
metro project:deploy --verbose
metro project:deploy -v
| Parametre | Tür | Açıklama |
|---|---|---|
name |
String |
Bayrak adı |
abbr |
String? |
Tek karakter kısaltma |
help |
String? |
--help ile gösterilen yardım metni |
defaultValue |
bool |
Varsayılan değer (varsayılan: false) |
Komut Sonucu
handle() metodu, ayrıştırılmış seçenekleri, bayrakları ve argümanları okumak için tipli erişimcilere sahip bir CommandResult nesnesi alır.
@override
Future<void> handle(CommandResult result) async {
// Get a string option
final name = result.getString('name');
// Get a boolean flag
final verbose = result.getBool('verbose');
// Get an integer option
final count = result.getInt('count');
// Generic typed access
final value = result.get<String>('key');
// Built-in flag checks
if (result.hasForceFlag) { /* --force was passed */ }
if (result.hasHelpFlag) { /* --help was passed */ }
// Raw arguments
List<String> allArgs = result.arguments;
List<String> unparsed = result.rest;
}
| Metot / Özellik | Döndürür | Açıklama |
|---|---|---|
getString(String name, {String? defaultValue}) |
String? |
String değer al |
getBool(String name, {bool? defaultValue}) |
bool? |
Boolean değer al |
getInt(String name, {int? defaultValue}) |
int? |
Tamsayı değer al |
get<T>(String name) |
T? |
Tipli değer al |
hasForceFlag |
bool |
--force geçilip geçilmediği |
hasHelpFlag |
bool |
--help geçilip geçilmediği |
arguments |
List<String> |
Tüm komut satırı argümanları |
rest |
List<String> |
Ayrıştırılmamış kalan argümanlar |
Etkileşimli Girdi
NyCustomCommand, terminalde kullanıcı girdisi toplamak için metotlar sağlar.
Metin Girdisi
// Ask a question with optional default
final name = prompt('What is your project name?', defaultValue: 'my_app');
// ask() is an alias for prompt()
final description = ask('Enter a description:');
| Parametre | Tür | Açıklama |
|---|---|---|
question |
String |
Görüntülenecek soru |
defaultValue |
String |
Kullanıcı Enter'a basarsa varsayılan değer (varsayılan: '') |
Onay
if (confirm('Would you like to continue?', defaultValue: true)) {
await runProcess('flutter pub get');
} else {
info('Operation canceled');
}
| Parametre | Tür | Açıklama |
|---|---|---|
question |
String |
Evet/hayır sorusu |
defaultValue |
bool |
Varsayılan yanıt (varsayılan: false) |
Tekli Seçim
final environment = select(
'Select deployment environment:',
['development', 'staging', 'production'],
defaultOption: 'development',
);
| Parametre | Tür | Açıklama |
|---|---|---|
question |
String |
İstem metni |
options |
List<String> |
Mevcut seçenekler |
defaultOption |
String? |
Önceden seçilmiş seçenek |
Çoklu Seçim
final packages = multiSelect(
'Select packages to install:',
['firebase_auth', 'dio', 'provider', 'shared_preferences'],
);
if (packages.isNotEmpty) {
addPackages(packages);
await runProcess('flutter pub get');
}
Kullanıcı virgülle ayrılmış numaralar veya "all" girer.
Gizli Girdi
final apiKey = promptSecret('Enter your API key:');
Girdi terminal ekranında gizlenir. Echo modu desteklenmiyorsa görünür girdiye geri döner.
Çıktı Biçimlendirme
Konsola biçimlendirilmiş çıktı yazdırmak için metotlar:
@override
Future<void> handle(CommandResult result) async {
info('Processing files...'); // Blue text
error('Operation failed'); // Red text
success('Deployment complete'); // Green text
warning('Outdated package'); // Yellow text
line('Plain text output'); // No color
comment('Background note'); // Gray text
alert('Important notice'); // Bordered alert box
newLine(); // One blank line
newLine(3); // Three blank lines
// Exit the command with an error
abort('Fatal error occurred'); // Prints red, exits with code 1
}
| Metot | Açıklama |
|---|---|
info(String message) |
Mavi metin yazdır |
error(String message) |
Kırmızı metin yazdır |
success(String message) |
Yeşil metin yazdır |
warning(String message) |
Sarı metin yazdır |
line(String message) |
Düz metin yazdır (renksiz) |
newLine([int count = 1]) |
Boş satır yazdır |
comment(String message) |
Gri/soluk metin yazdır |
alert(String message) |
Kenarlıklı uyarı kutusu yazdır |
abort([String? message, int exitCode = 1]) |
Komutu bir hata ile sonlandır |
Döndürücü ve İlerleme
Döndürücüler ve ilerleme çubukları, uzun süren işlemler sırasında görsel geri bildirim sağlar.
withSpinner Kullanımı
Eşzamansız bir görevi otomatik döndürücü ile sarın:
final projectFiles = await withSpinner(
task: () async {
await sleep(2);
return ['pubspec.yaml', 'lib/main.dart', 'README.md'];
},
message: 'Analyzing project structure',
successMessage: 'Project analysis complete',
errorMessage: 'Failed to analyze project',
);
info('Found ${projectFiles.length} key files');
| Parametre | Tür | Açıklama |
|---|---|---|
task |
Future<T> Function() |
Yürütülecek eşzamansız fonksiyon |
message |
String |
Döndürücü çalışırken gösterilen metin |
successMessage |
String? |
Başarı durumunda gösterilir |
errorMessage |
String? |
Hata durumunda gösterilir |
Manuel Döndürücü Kontrolü
Çok adımlı iş akışları için bir döndürücü oluşturun ve manuel olarak kontrol edin:
final spinner = createSpinner('Deploying to production');
spinner.start();
try {
await runProcess('flutter clean', silent: true);
spinner.update('Building release version');
await runProcess('flutter build web --release', silent: true);
spinner.update('Uploading to server');
await runProcess('./deploy.sh', silent: true);
spinner.stop(completionMessage: 'Deployment completed', success: true);
} catch (e) {
spinner.stop(completionMessage: 'Deployment failed: $e', success: false);
}
ConsoleSpinner metotları:
| Metot | Açıklama |
|---|---|
start([String? message]) |
Döndürücü animasyonunu başlat |
update(String message) |
Görüntülenen mesajı değiştir |
stop({String? completionMessage, bool success = true}) |
Döndürücüyü durdur |
İlerleme Çubuğu
Manuel olarak bir ilerleme çubuğu oluşturun ve yönetin:
final progress = progressBar(100, message: 'Processing files');
progress.start();
for (int i = 0; i < 100; i++) {
await Future.delayed(Duration(milliseconds: 50));
progress.tick();
}
progress.complete('All files processed');
ConsoleProgressBar metotları:
| Metot / Özellik | Açıklama |
|---|---|
start() |
İlerleme çubuğunu başlat |
tick([int amount = 1]) |
İlerlemeyi artır |
update(int value) |
İlerlemeyi belirli bir değere ayarla |
updateMessage(String newMessage) |
Görüntülenen mesajı değiştir |
complete([String? completionMessage]) |
İsteğe bağlı mesajla tamamla |
stop() |
Tamamlamadan durdur |
current |
Mevcut ilerleme değeri (getter) |
percentage |
0-100 arası yüzde olarak ilerleme (getter) |
İlerleme ile Öğe İşleme
Otomatik ilerleme takibi ile bir öğe listesini işleyin:
// Async processing
final results = await withProgress<File, String>(
items: findFiles('lib/', extension: '.dart'),
process: (file, index) async {
return file.path;
},
message: 'Analyzing Dart files',
completionMessage: 'Analysis complete',
);
// Synchronous processing
final upperItems = withProgressSync<String, String>(
items: ['a', 'b', 'c', 'd', 'e'],
process: (item, index) => item.toUpperCase(),
message: 'Converting items',
);
API Yardımcısı
api yardımcısı, HTTP istekleri yapmak için Dio etrafında basitleştirilmiş bir sarmalayıcı sağlar:
// GET request
final userData = await api((request) =>
request.get('https://api.example.com/users/1')
);
// POST request
final result = await api((request) =>
request.post(
'https://api.example.com/items',
data: {'name': 'New Item', 'price': 19.99},
)
);
// PUT request
final updateResult = await api((request) =>
request.put(
'https://api.example.com/items/42',
data: {'name': 'Updated Item', 'price': 29.99},
)
);
// DELETE request
final deleteResult = await api((request) =>
request.delete('https://api.example.com/items/42')
);
// PATCH request
final patchResult = await api((request) =>
request.patch(
'https://api.example.com/items/42',
data: {'price': 24.99},
)
);
// With query parameters
final searchResults = await api((request) =>
request.get(
'https://api.example.com/search',
queryParameters: {'q': 'keyword', 'limit': 10},
)
);
Daha iyi bir kullanıcı deneyimi için withSpinner ile birleştirin:
final data = await withSpinner(
task: () => api((request) =>
request.get('https://api.example.com/config')
),
message: 'Loading configuration',
);
ApiService; get, post, put, delete ve patch metotlarını destekler. Her biri isteğe bağlı queryParameters, data, options ve cancelToken parametreleri kabul eder.
Dosya Sistemi Yardımcıları
dart:io içe aktarmanıza gerek kalmadan kullanabileceğiniz yerleşik dosya sistemi yardımcıları:
// Check existence
if (fileExists('lib/config/app.dart')) { /* ... */ }
if (directoryExists('lib/app/models')) { /* ... */ }
// Read files
String content = await readFile('pubspec.yaml');
String contentSync = readFileSync('pubspec.yaml');
// Write files
await writeFile('lib/generated/output.dart', 'class Output {}');
writeFileSync('lib/generated/output.dart', 'class Output {}');
// Append to a file
await appendFile('log.txt', 'New log entry\n');
// Ensure a directory exists
await ensureDirectory('lib/generated');
// Delete and copy files
await deleteFile('lib/generated/output.dart');
await copyFile('lib/config/app.dart', 'lib/config/app.bak.dart');
| Metot | Açıklama |
|---|---|
fileExists(String path) |
Dosya varsa true döndürür |
directoryExists(String path) |
Dizin varsa true döndürür |
readFile(String path) |
Dosyayı string olarak oku (eşzamansız) |
readFileSync(String path) |
Dosyayı string olarak oku (eşzamanlı) |
writeFile(String path, String content) |
Dosyaya içerik yaz (eşzamansız) |
writeFileSync(String path, String content) |
Dosyaya içerik yaz (eşzamanlı) |
appendFile(String path, String content) |
Dosyaya içerik ekle |
ensureDirectory(String path) |
Yoksa dizin oluştur |
deleteFile(String path) |
Dosyayı sil |
copyFile(String source, String destination) |
Dosyayı kopyala |
JSON ve YAML Yardımcıları
Yerleşik yardımcılarla JSON ve YAML dosyalarını okuyun ve yazın:
// Read JSON as Map
Map<String, dynamic> config = await readJson('config.json');
// Read JSON as List
List<dynamic> items = await readJsonArray('lib/app/commands/commands.json');
// Write JSON (pretty printed by default)
await writeJson('output.json', {'name': 'MyApp', 'version': '1.0.0'});
// Write compact JSON
await writeJson('output.json', data, pretty: false);
// Append to a JSON array file (with duplicate prevention)
await appendToJsonArray(
'lib/app/commands/commands.json',
{'name': 'my_command', 'category': 'app', 'script': 'my_command.dart'},
uniqueKey: 'name',
);
// Read YAML as Map
Map<String, dynamic> pubspec = await readYaml('pubspec.yaml');
info('Project: ${pubspec['name']}');
| Metot | Açıklama |
|---|---|
readJson(String path) |
JSON dosyasını Map<String, dynamic> olarak oku |
readJsonArray(String path) |
JSON dosyasını List<dynamic> olarak oku |
writeJson(String path, dynamic data, {bool pretty = true}) |
Veriyi JSON olarak yaz |
appendToJsonArray(String path, Map item, {String? uniqueKey}) |
JSON dizi dosyasına ekle |
readYaml(String path) |
YAML dosyasını Map<String, dynamic> olarak oku |
Dart Dosya Manipülasyonu
Dart kaynak dosyalarını programatik olarak düzenlemek için yardımcılar -- iskele araçları oluştururken kullanışlıdır:
// Add an import (skips if already present)
await addImport(
'lib/bootstrap/providers.dart',
"import '/app/providers/firebase_provider.dart';",
);
// Insert code before the last closing brace
await insertBeforeClosingBrace(
'lib/bootstrap/providers.dart',
' FirebaseProvider(),',
);
// Check if a file contains a string
bool hasImport = await fileContains(
'lib/bootstrap/providers.dart',
'firebase_provider',
);
// Check if a file matches a regex pattern
bool hasClass = await fileContainsPattern(
'lib/app/models/user.dart',
RegExp(r'class User'),
);
| Metot | Açıklama |
|---|---|
addImport(String filePath, String importStatement) |
Dart dosyasına import ekle (mevcutsa atla) |
insertBeforeClosingBrace(String filePath, String code) |
Dosyadaki son } işaretinden önce kod ekle |
fileContains(String filePath, String identifier) |
Dosyanın bir string içerip içermediğini kontrol et |
fileContainsPattern(String filePath, Pattern pattern) |
Dosyanın bir kalıpla eşleşip eşleşmediğini kontrol et |
Dizin Yardımcıları
Dizinlerle çalışmak ve dosya bulmak için yardımcılar:
// List directory contents
var entities = listDirectory('lib/app/models');
var allEntities = listDirectory('lib/', recursive: true);
// Find files by extension
List<File> dartFiles = findFiles(
'lib/app/models',
extension: '.dart',
recursive: true,
);
// Find files by name pattern
List<File> testFiles = findFiles(
'test/',
namePattern: RegExp(r'_test\.dart$'),
);
// Delete a directory recursively
await deleteDirectory('build/');
// Copy a directory recursively
await copyDirectory('lib/templates', 'lib/generated');
| Metot | Açıklama |
|---|---|
listDirectory(String path, {bool recursive = false}) |
Dizin içeriğini listele |
findFiles(String directory, {String? extension, Pattern? namePattern, bool recursive = true}) |
Kriterlere uyan dosyaları bul |
deleteDirectory(String path) |
Dizini özyinelemeli olarak sil |
copyDirectory(String source, String destination) |
Dizini özyinelemeli olarak kopyala |
Büyük/Küçük Harf Dönüşüm Yardımcıları
recase paketini içe aktarmadan stringleri adlandırma kuralları arasında dönüştürün:
String input = 'user profile page';
snakeCase(input); // user_profile_page
camelCase(input); // userProfilePage
pascalCase(input); // UserProfilePage
titleCase(input); // User Profile Page
kebabCase(input); // user-profile-page
constantCase(input); // USER_PROFILE_PAGE
| Metot | Çıktı Formatı | Örnek |
|---|---|---|
snakeCase(String input) |
snake_case |
user_profile |
camelCase(String input) |
camelCase |
userProfile |
pascalCase(String input) |
PascalCase |
UserProfile |
titleCase(String input) |
Title Case |
User Profile |
kebabCase(String input) |
kebab-case |
user-profile |
constantCase(String input) |
CONSTANT_CASE |
USER_PROFILE |
Proje Yol Yardımcıları
Standart Nylo Website proje dizinleri için getter'lar, proje köküne göre yollar döndürür:
info(modelsPath); // lib/app/models
info(controllersPath); // lib/app/controllers
info(widgetsPath); // lib/resources/widgets
info(pagesPath); // lib/resources/pages
info(commandsPath); // lib/app/commands
info(configPath); // lib/config
info(providersPath); // lib/app/providers
info(eventsPath); // lib/app/events
info(networkingPath); // lib/app/networking
info(themesPath); // lib/resources/themes
// Build a custom path
String customPath = projectPath('app/services/auth_service.dart');
// Returns: lib/app/services/auth_service.dart
| Özellik | Yol |
|---|---|
modelsPath |
lib/app/models |
controllersPath |
lib/app/controllers |
widgetsPath |
lib/resources/widgets |
pagesPath |
lib/resources/pages |
commandsPath |
lib/app/commands |
configPath |
lib/config |
providersPath |
lib/app/providers |
eventsPath |
lib/app/events |
networkingPath |
lib/app/networking |
themesPath |
lib/resources/themes |
projectPath(String relativePath) |
Proje içinde göreli bir yolu çözümler |
Platform Yardımcıları
Platformu kontrol edin ve ortam değişkenlerine erişin:
if (isWindows) {
info('Running on Windows');
} else if (isMacOS) {
info('Running on macOS');
} else if (isLinux) {
info('Running on Linux');
}
info('Working in: $workingDirectory');
String home = env('HOME', '/default/path');
| Özellik / Metot | Açıklama |
|---|---|
isWindows |
Windows üzerinde çalışıyorsa true |
isMacOS |
macOS üzerinde çalışıyorsa true |
isLinux |
Linux üzerinde çalışıyorsa true |
workingDirectory |
Mevcut çalışma dizini yolu |
env(String key, [String defaultValue = '']) |
Sistem ortam değişkenini oku |
Dart ve Flutter Komutları
Yaygın Dart ve Flutter CLI komutlarını yardımcı metotlar olarak çalıştırın. Her biri işlem çıkış kodunu döndürür:
// Format a Dart file or directory
await dartFormat('lib/app/models/user.dart');
// Run dart analyze
int analyzeResult = await dartAnalyze('lib/');
// Run flutter pub get
await flutterPubGet();
// Run flutter clean
await flutterClean();
// Build for a target with additional args
await flutterBuild('apk', args: ['--release', '--split-per-abi']);
await flutterBuild('web', args: ['--release']);
// Run flutter test
await flutterTest();
await flutterTest('test/unit/');
| Metot | Açıklama |
|---|---|
dartFormat(String path) |
Bir dosya veya dizinde dart format çalıştır |
dartAnalyze([String? path]) |
dart analyze çalıştır |
flutterPubGet() |
flutter pub get çalıştır |
flutterClean() |
flutter clean çalıştır |
flutterBuild(String target, {List<String> args}) |
flutter build <target> çalıştır |
flutterTest([String? path]) |
flutter test çalıştır |
Doğrulama Yardımcıları
Kod üretimi için kullanıcı girdisini doğrulamak ve temizlemek amacıyla yardımcılar:
// Validate a Dart identifier
if (!isValidDartIdentifier('MyClass')) {
error('Invalid Dart identifier');
}
// Require a non-empty first argument (aborts if missing)
String name = requireArgument(result, message: 'Please provide a name');
// Clean a class name (PascalCase, remove suffixes)
String className = cleanClassName('user_model', removeSuffixes: ['_model']);
// Returns: 'User'
// Clean a file name (snake_case with extension)
String fileName = cleanFileName('UserModel', extension: '.dart');
// Returns: 'user_model.dart'
| Metot | Açıklama |
|---|---|
isValidDartIdentifier(String name) |
Dart tanımlayıcı adını doğrula |
requireArgument(CommandResult result, {String? message}) |
Boş olmayan ilk argümanı zorunlu kıl veya iptal et |
cleanClassName(String name, {List<String> removeSuffixes}) |
Sınıf adını temizle ve PascalCase yap |
cleanFileName(String name, {String extension = '.dart'}) |
Dosya adını temizle ve snake_case yap |
Dosya İskelesi
İskele sistemi kullanarak bir veya birden fazla dosyayı içerikle oluşturun.
Tek Dosya
await scaffold(
path: 'lib/app/services/auth_service.dart',
content: '''
class AuthService {
Future<bool> login(String email, String password) async {
return false;
}
}
''',
force: false,
successMessage: 'AuthService created',
);
| Parametre | Tür | Açıklama |
|---|---|---|
path |
String |
Oluşturulacak dosya yolu |
content |
String |
Dosya içeriği |
force |
bool |
Varsa üzerine yaz (varsayılan: false) |
successMessage |
String? |
Başarı durumunda gösterilen mesaj |
Birden Fazla Dosya
await scaffoldMany([
ScaffoldFile(
path: 'lib/app/models/product.dart',
content: 'class Product {}',
successMessage: 'Product model created',
),
ScaffoldFile(
path: 'lib/app/networking/product_api_service.dart',
content: 'class ProductApiService {}',
successMessage: 'Product API service created',
),
], force: false);
ScaffoldFile sınıfı:
| Özellik | Tür | Açıklama |
|---|---|---|
path |
String |
Oluşturulacak dosya yolu |
content |
String |
Dosya içeriği |
successMessage |
String? |
Başarı durumunda gösterilen mesaj |
Görev Çalıştırıcı
Otomatik durum çıktısı ile bir dizi adlandırılmış görevi çalıştırın.
Temel Görev Çalıştırıcı
await runTasks([
CommandTask(
'Clean project',
() => runProcess('flutter clean', silent: true),
),
CommandTask(
'Fetch dependencies',
() => runProcess('flutter pub get', silent: true),
),
CommandTask(
'Run tests',
() => runProcess('flutter test', silent: true),
stopOnError: true,
),
]);
Döndürücülü Görev Çalıştırıcı
await runTasksWithSpinner([
CommandTask(
'Preparing release',
() async {
await flutterClean();
await flutterPubGet();
},
),
CommandTask(
'Building APK',
() => flutterBuild('apk', args: ['--release']),
),
]);
CommandTask sınıfı:
| Özellik | Tür | Varsayılan | Açıklama |
|---|---|---|---|
name |
String |
zorunlu | Çıktıda gösterilen görev adı |
action |
Future<void> Function() |
zorunlu | Yürütülecek eşzamansız fonksiyon |
stopOnError |
bool |
true |
Hata durumunda kalan görevleri durdur |
Tablo Çıktısı
Konsolda biçimlendirilmiş ASCII tabloları görüntüleyin:
table(
['Name', 'Version', 'Status'],
[
['nylo_framework', '7.0.0', 'installed'],
['nylo_support', '7.0.0', 'installed'],
['dio', '5.4.0', 'installed'],
],
);
Çıktı:
┌─────────────────┬─────────┬───────────┐
│ Name │ Version │ Status │
├─────────────────┼─────────┼───────────┤
│ nylo_framework │ 7.0.0 │ installed │
│ nylo_support │ 7.0.0 │ installed │
│ dio │ 5.4.0 │ installed │
└─────────────────┴─────────┴───────────┘
Örnekler
Güncel Saat Komutu
Güncel saati gösteren basit bir komut:
import 'package:nylo_framework/metro/ny_cli.dart';
void main(arguments) => _CurrentTimeCommand(arguments).run();
class _CurrentTimeCommand extends NyCustomCommand {
_CurrentTimeCommand(super.arguments);
@override
CommandBuilder builder(CommandBuilder command) {
command.addOption('format', defaultValue: 'HH:mm:ss');
return command;
}
@override
Future<void> handle(CommandResult result) async {
final format = result.getString("format");
final now = DateTime.now();
info("The current time is ${now.toIso8601String()}");
info("Requested format: $format");
}
}
Font İndirme Komutu
Google Fonts'u projeye indirip yükleyen bir komut:
import 'package:nylo_framework/metro/ny_cli.dart';
void main(arguments) => _DownloadFontsCommand(arguments).run();
class _DownloadFontsCommand extends NyCustomCommand {
_DownloadFontsCommand(super.arguments);
@override
CommandBuilder builder(CommandBuilder command) {
command.addOption('font', abbr: 'f', help: 'Font family name');
command.addFlag('verbose', abbr: 'v', defaultValue: false);
return command;
}
@override
Future<void> handle(CommandResult result) async {
final fontName = result.getString('font') ??
prompt('Enter font family name:', defaultValue: 'Roboto');
final verbose = result.getBool('verbose') ?? false;
await withSpinner(
task: () async {
await ensureDirectory('assets/fonts');
final fontData = await api((request) =>
request.get('https://fonts.google.com/download?family=$fontName')
);
if (fontData != null) {
await writeFile('assets/fonts/$fontName.ttf', fontData.toString());
}
},
message: 'Downloading $fontName font',
successMessage: '$fontName font installed',
errorMessage: 'Failed to download $fontName',
);
if (verbose) {
info('Font saved to: assets/fonts/$fontName.ttf');
}
}
}
Dağıtım Hattı Komutu
Görev çalıştırıcısını kullanarak tam bir dağıtım hattı çalıştıran komut:
import 'package:nylo_framework/metro/ny_cli.dart';
void main(arguments) => _DeployCommand(arguments).run();
class _DeployCommand extends NyCustomCommand {
_DeployCommand(super.arguments);
@override
CommandBuilder builder(CommandBuilder command) {
command.addOption(
'environment',
abbr: 'e',
defaultValue: 'development',
allowed: ['development', 'staging', 'production'],
);
command.addFlag('skip-tests', defaultValue: false);
return command;
}
@override
Future<void> handle(CommandResult result) async {
final env = result.getString('environment') ?? 'development';
final skipTests = result.getBool('skip-tests') ?? false;
alert('Deploying to $env');
newLine();
if (env == 'production') {
if (!confirm('Are you sure you want to deploy to production?')) {
abort('Deployment canceled');
}
}
final tasks = <CommandTask>[
CommandTask('Clean project', () => flutterClean()),
CommandTask('Fetch dependencies', () => flutterPubGet()),
];
if (!skipTests) {
tasks.add(CommandTask(
'Run tests',
() => flutterTest(),
stopOnError: true,
));
}
tasks.add(CommandTask(
'Build for web',
() => flutterBuild('web', args: ['--release']),
));
await runTasksWithSpinner(tasks);
newLine();
success('Deployment to $env completed');
table(
['Step', 'Status'],
tasks.map((t) => [t.name, 'Done']).toList(),
);
}
}