Basics

Metro CLI Araci

Giris

Metro, Nylo Website framework'unun arka planinda calisan bir CLI aracidir. Gelistirmeyi hizlandirmak icin bircok yararli arac saglar.

Kurulum

nylo init kullanarak yeni bir Nylo projesi olusturdugunuzda, metro komutu terminaliniz icin otomatik olarak yapilandirilir. Herhangi bir Nylo projesinde hemen kullanmaya baslayabilirsiniz.

Tum kullanilabilir komutlari gormek icin proje dizininizden metro komutunu calistirin:

metro

Asagidakine benzer bir cikti gormelisiniz.

Metro - Nylo's Companion to Build Flutter apps by Anthony Gordon

Usage:
    command [options] [arguments]

Options
    -h

All commands:

[Widget Commands]
  make:page
  make:stateful_widget
  make:stateless_widget
  make:state_managed_widget
  make:navigation_hub
  make:journey_widget
  make:bottom_sheet_modal
  make:button
  make:form

[Helper Commands]
  make:model
  make:provider
  make:api_service
  make:controller
  make:event
  make:theme
  make:route_guard
  make:config
  make:interceptor
  make:command
  make:env
  make:key

Controller olusturma

Yeni bir controller olusturma

Terminalde asagidaki komutu calistirarak yeni bir controller olusturabilirsiniz.

metro make:controller profile_controller

Bu, lib/app/controllers/ dizininde mevcut degilse yeni bir controller olusturacaktir.

Zorunlu controller olusturma

Argumenler:

--force veya -f bayragi kullanildiginda, mevcut bir controller varsa uzerine yazilacaktir.

metro make:controller profile_controller --force

Model olusturma

Yeni bir model olusturma

Terminalde asagidaki komutu calistirarak yeni bir model olusturabilirsiniz.

metro make:model product

Yeni olusturulan model lib/app/models/ dizinine yerlestirilecektir.

JSON'dan model olusturma

Argumenler:

--json veya -j bayragi kullanildiginda, bir JSON verisi uzerinden yeni bir model olusturulacaktir.

metro make:model product --json

Ardindan JSON verinizi terminale yapistirabilirsiniz ve sizin icin bir model olusturulacaktir.

Zorunlu model olusturma

Argumenler:

--force veya -f bayragi kullanildiginda, mevcut bir model varsa uzerine yazilacaktir.

metro make:model product --force

Sayfa olusturma

Yeni bir sayfa olusturma

Terminalde asagidaki komutu calistirarak yeni bir sayfa olusturabilirsiniz.

metro make:page product_page

Bu, lib/resources/pages/ dizininde mevcut degilse yeni bir sayfa olusturacaktir.

Controller ile sayfa olusturma

Terminalde asagidaki komutu calistirarak controller'li yeni bir sayfa olusturabilirsiniz.

Argumenler:

--controller veya -c bayragi kullanildiginda, controller'li yeni bir sayfa olusturulacaktir.

metro make:page product_page -c

Auth sayfasi olusturma

Terminalde asagidaki komutu calistirarak yeni bir auth sayfasi olusturabilirsiniz.

Argumenler:

--auth veya -a bayragi kullanildiginda, yeni bir auth sayfasi olusturulacaktir.

metro make:page login_page -a

Baslangic sayfasi olusturma

Terminalde asagidaki komutu calistirarak yeni bir baslangic sayfasi olusturabilirsiniz.

Argumenler:

--initial veya -i bayragi kullanildiginda, yeni bir baslangic sayfasi olusturulacaktir.

metro make:page home_page -i

Zorunlu sayfa olusturma

Argumenler:

--force veya -f bayragi kullanildiginda, mevcut bir sayfa varsa uzerine yazilacaktir.

metro make:page product_page --force

Stateless widget olusturma

Yeni bir stateless widget olusturma

Terminalde asagidaki komutu calistirarak yeni bir stateless widget olusturabilirsiniz.

metro make:stateless_widget product_rating_widget

Yukaridaki komut, lib/resources/widgets/ dizininde mevcut degilse yeni bir widget olusturacaktir.

Zorunlu stateless widget olusturma

Argumenler:

--force veya -f bayragi kullanildiginda, mevcut bir widget varsa uzerine yazilacaktir.

metro make:stateless_widget product_rating_widget --force

Stateful widget olusturma

Yeni bir stateful widget olusturma

Terminalde asagidaki komutu calistirarak yeni bir stateful widget olusturabilirsiniz.

metro make:stateful_widget product_rating_widget

Yukaridaki komut, lib/resources/widgets/ dizininde mevcut degilse yeni bir widget olusturacaktir.

Zorunlu stateful widget olusturma

Argumenler:

--force veya -f bayragi kullanildiginda, mevcut bir widget varsa uzerine yazilacaktir.

metro make:stateful_widget product_rating_widget --force

Journey widget olusturma

Yeni bir journey widget olusturma

Terminalde asagidaki komutu calistirarak yeni bir journey widget olusturabilirsiniz.

metro make:journey_widget product_journey --parent="[NAVIGATION_HUB]"

# Full example if you have a BaseNavigationHub
metro make:journey_widget welcome,user_dob,user_photos --parent="Base"

Yukaridaki komut, lib/resources/widgets/ dizininde mevcut degilse yeni bir widget olusturacaktir.

--parent argumani, yeni journey widget'in eklenmesi gereken ust widget'i belirtmek icin kullanilir.

Ornek

metro make:navigation_hub onboarding

Ardindan, yeni journey widget'leri ekleyin.

metro make:journey_widget welcome,user_dob,user_photos --parent="onboarding"

Zorunlu journey widget olusturma

Argumenler: --force veya -f bayragi kullanildiginda, mevcut bir widget varsa uzerine yazilacaktir.

metro make:journey_widget product_journey --force --parent="[YOUR_NAVIGATION_HUB]"

API Servisi olusturma

Yeni bir API Servisi olusturma

Terminalde asagidaki komutu calistirarak yeni bir API servisi olusturabilirsiniz.

metro make:api_service user_api_service

Yeni olusturulan API servisi lib/app/networking/ dizinine yerlestirilecektir.

Model ile yeni bir API Servisi olusturma

Terminalde asagidaki komutu calistirarak model'li yeni bir API servisi olusturabilirsiniz.

Argumenler:

--model veya -m secenegi kullanildiginda, model'li yeni bir API servisi olusturulacaktir.

metro make:api_service user --model="User"

Yeni olusturulan API servisi lib/app/networking/ dizinine yerlestirilecektir.

Zorunlu API Servisi olusturma

Argumenler:

--force veya -f bayragi kullanildiginda, mevcut bir API Servisi varsa uzerine yazilacaktir.

metro make:api_service user --force

Event olusturma

Yeni bir event olusturma

Terminalde asagidaki komutu calistirarak yeni bir event olusturabilirsiniz.

metro make:event login_event

Bu, lib/app/events dizininde yeni bir event olusturacaktir.

Zorunlu event olusturma

Argumenler:

--force veya -f bayragi kullanildiginda, mevcut bir event varsa uzerine yazilacaktir.

metro make:event login_event --force

Provider olusturma

Yeni bir provider olusturma

Asagidaki komutu kullanarak uygulamanizda yeni provider'lar olusturun.

metro make:provider firebase_provider

Yeni olusturulan provider lib/app/providers/ dizinine yerlestirilecektir.

Zorunlu provider olusturma

Argumenler:

--force veya -f bayragi kullanildiginda, mevcut bir provider varsa uzerine yazilacaktir.

metro make:provider firebase_provider --force

Tema olusturma

Yeni bir tema olusturma

Terminalde asagidaki komutu calistirarak tema olusturabilirsiniz.

metro make:theme bright_theme

Bu, lib/resources/themes/ dizininde yeni bir tema olusturacaktir.

Zorunlu tema olusturma

Argumenler:

--force veya -f bayragi kullanildiginda, mevcut bir tema varsa uzerine yazilacaktir.

metro make:theme bright_theme --force

Form olusturma

Yeni bir form olusturma

Terminalde asagidaki komutu calistirarak yeni bir form olusturabilirsiniz.

metro make:form car_advert_form

Bu, lib/app/forms dizininde yeni bir form olusturacaktir.

Zorunlu form olusturma

Argumenler:

--force veya -f bayragi kullanildiginda, mevcut bir form varsa uzerine yazilacaktir.

metro make:form login_form --force

Route Guard olusturma

Yeni bir route guard olusturma

Terminalde asagidaki komutu calistirarak bir route guard olusturabilirsiniz.

metro make:route_guard premium_content

Bu, lib/app/route_guards dizininde yeni bir route guard olusturacaktir.

Zorunlu route guard olusturma

Argumenler:

--force veya -f bayragi kullanildiginda, mevcut bir route guard varsa uzerine yazilacaktir.

metro make:route_guard premium_content --force

Config dosyasi olusturma

Yeni bir config dosyasi olusturma

Terminalde asagidaki komutu calistirarak yeni bir config dosyasi olusturabilirsiniz.

metro make:config shopping_settings

Bu, lib/app/config dizininde yeni bir config dosyasi olusturacaktir.

Zorunlu config dosyasi olusturma

Argumenler:

--force veya -f bayragi kullanildiginda, mevcut bir config dosyasi varsa uzerine yazilacaktir.

metro make:config app_config --force

Komut olusturma

Yeni bir komut olusturma

Terminalde asagidaki komutu calistirarak yeni bir komut olusturabilirsiniz.

metro make:command my_command

Bu, lib/app/commands dizininde yeni bir komut olusturacaktir.

Zorunlu komut olusturma

Argumenler: --force veya -f bayragi kullanildiginda, mevcut bir komut varsa uzerine yazilacaktir.

metro make:command my_command --force

State Managed Widget olusturma

Terminalde asagidaki komutu calistirarak yeni bir state managed widget olusturabilirsiniz.

metro make:state_managed_widget product_rating_widget

Yukaridaki komut lib/resources/widgets/ dizininde yeni bir widget olusturacaktir.

--force veya -f bayragi kullanildiginda, mevcut bir widget varsa uzerine yazilacaktir.

metro make:state_managed_widget product_rating_widget --force

Navigation Hub olusturma

Terminalde asagidaki komutu calistirarak yeni bir navigation hub olusturabilirsiniz.

metro make:navigation_hub dashboard

Bu, lib/resources/pages/ dizininde yeni bir navigation hub olusturacak ve route'u otomatik olarak ekleyecektir.

Argumenler:

Bayrak Kisaltma Aciklama
--auth -a Auth sayfasi olarak olustur
--initial -i Baslangic sayfasi olarak olustur
--force -f Mevcutsa uzerine yaz
# Create as the initial page
metro make:navigation_hub dashboard --initial

Bottom Sheet Modal olusturma

Terminalde asagidaki komutu calistirarak yeni bir bottom sheet modal olusturabilirsiniz.

metro make:bottom_sheet_modal payment_options

Bu, lib/resources/widgets/ dizininde yeni bir bottom sheet modal olusturacaktir.

--force veya -f bayragi kullanildiginda, mevcut bir modal varsa uzerine yazilacaktir.

metro make:bottom_sheet_modal payment_options --force

Button olusturma

Terminalde asagidaki komutu calistirarak yeni bir button widget'i olusturabilirsiniz.

metro make:button checkout_button

Bu, lib/resources/widgets/ dizininde yeni bir button widget'i olusturacaktir.

--force veya -f bayragi kullanildiginda, mevcut bir button varsa uzerine yazilacaktir.

metro make:button checkout_button --force

Interceptor olusturma

Terminalde asagidaki komutu calistirarak yeni bir ag interceptor'u olusturabilirsiniz.

metro make:interceptor auth_interceptor

Bu, lib/app/networking/dio/interceptors/ dizininde yeni bir interceptor olusturacaktir.

--force veya -f bayragi kullanildiginda, mevcut bir interceptor varsa uzerine yazilacaktir.

metro make:interceptor auth_interceptor --force

Env dosyasi olusturma

Terminalde asagidaki komutu calistirarak yeni bir ortam dosyasi olusturabilirsiniz.

metro make:env .env.staging

Bu, proje kokunde yeni bir .env dosyasi olusturacaktir.

Anahtar olusturma

Ortam sifreleme icin guvenli bir APP_KEY olusturun. Bu, v7'deki sifrelenmis .env dosyalari icin kullanilir.

metro make:key

Argumenler:

Bayrak / Secenek Kisaltma Aciklama
--force -f Mevcut APP_KEY'in uzerine yaz
--file -e Hedef .env dosyasi (varsayilan: .env)
# Generate key and overwrite existing
metro make:key --force

# Generate key for a specific env file
metro make:key --file=.env.production

Uygulama Simgeleri Olusturma

Asagidaki komutu calistirarak IOS ve Android icin tum uygulama simgelerini olusturabilirsiniz.

dart run flutter_launcher_icons:main

Bu, pubspec.yaml dosyanizdaki flutter_icons yapilandirmasini kullanir.

Ozel Komutlar

Ozel komutlar, Nylo'nun CLI'sini kendi projenize ozel komutlarla genisletmenize olanak tanir. Bu ozellik, tekrarlayan gorevleri otomatiklestirmenizi, dagitim is akislarini uygulamanizi veya projenizin komut satiri araclariniza dogrudan herhangi bir ozel islevsellik eklemenizi saglar.

Not: Su anda ozel komutlarinizda nylo_framework.dart'i ice aktaramazsiniz, bunun yerine ny_cli.dart kullanin.

Ozel Komutlar Olusturma

Yeni bir ozel komut olusturmak icin make:command ozelligini kullanabilirsiniz:

metro make:command current_time

Komutunuz icin --category secenegini kullanarak bir kategori belirtebilirsiniz:

# Specify a category
metro make:command current_time --category="project"

Bu, lib/app/commands/current_time.dart yolunda asagidaki yapiyla yeni bir komut dosyasi olusturacaktir:

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");

      // Get the current time
      final now = DateTime.now();
      final DateFormat dateFormat = DateFormat(format);

      // Format the current time
      final formattedTime = dateFormat.format(now);
      info("The current time is " + formattedTime);
  }
}

Komut, tum kayitli komutlarin listesini iceren lib/app/commands/commands.json dosyasina otomatik olarak kaydedilecektir:

[
  {
    "name": "install_firebase",
    "category": "project",
    "script": "install_firebase.dart"
  },
  {
    "name": "current_time",
    "category": "app",
    "script": "current_time.dart"
  }
]

Ozel Komutlari Calistirma

Olusturulduktan sonra, ozel komutunuzu Metro kisayolunu veya tam Dart komutunu kullanarak calistirabilirsiniz:

metro app:current_time

metro'yu arguman olmadan calistirdiginizda, ozel komutlarinizi "Custom Commands" bolumu altinda menude listelendigini goreceksiniz:

[Custom Commands]
  app:app_icon
  app:clear_pub
  project:install_firebase
  project:deploy

Komutunuz icin yardim bilgilerini goruntulemek icin --help veya -h bayragini kullanin:

metro project:install_firebase --help

Komutlara Secenek Ekleme

Secenekler, komutunuzun kullanicilardan ek girdi almasini saglar. builder metodunda komutunuza secenek ekleyebilirsiniz:

@override
CommandBuilder builder(CommandBuilder command) {

  // Add an option with a default value
  command.addOption(
    'environment',     // option name
    abbr: 'e',         // short form abbreviation
    help: 'Target deployment environment', // help text
    defaultValue: 'development',  // default value
    allowed: ['development', 'staging', 'production'] // allowed values
  );

  return command;
}

Ardindan komutunuzun handle metodunda secenek degerine erisin:

@override
Future<void> handle(CommandResult result) async {
  final environment = result.getString('environment');
  info('Deploying to $environment environment...');

  // Command implementation...
}

Ornek kullanim:

metro project:deploy --environment=production
# or using abbreviation
metro project:deploy -e production

Komutlara Bayrak Ekleme

Bayraklar, acilip kapanabilen boole secenekleridir. addFlag metodunu kullanarak komutunuza bayrak ekleyin:

@override
CommandBuilder builder(CommandBuilder command) {

  command.addFlag(
    'verbose',       // flag name
    abbr: 'v',       // short form abbreviation
    help: 'Enable verbose output', // help text
    defaultValue: false  // default to off
  );

  return command;
}

Ardindan komutunuzun handle metodunda bayrak durumunu kontrol edin:

@override
Future<void> handle(CommandResult result) async {
  final verbose = result.getBool('verbose');

  if (verbose) {
    info('Verbose mode enabled');
    // Additional logging...
  }

  // Command implementation...
}

Ornek kullanim:

metro project:deploy --verbose
# or using abbreviation
metro project:deploy -v

Yardimci Metotlar

NyCustomCommand temel sinifi, yaygin gorevlere yardimci olmak icin cesitli yardimci metotlar saglar:

Mesaj Yazdirma

Farkli renklerde mesaj yazdirmak icin bazi metotlar:

info Mavi metin ile bilgi mesaji yazdir
error Kirmizi metin ile hata mesaji yazdir
success Yesil metin ile basari mesaji yazdir
warning Sari metin ile uyari mesaji yazdir

Islem Calistirma

Islemleri calistirin ve ciktilarini konsolda goruntulen:

addPackage pubspec.yaml'a paket ekle
addPackages pubspec.yaml'a birden fazla paket ekle
runProcess Harici bir islem calistir ve ciktiyi konsolda goruntule
prompt Kullanici girdisini metin olarak topla
confirm Evet/hayir sorusu sor ve boole sonuc dondur
select Secenekler listesi sun ve kullanicinin birini secmesine izin ver
multiSelect Kullanicinin listeden birden fazla secenek secmesine izin ver

Ag Istekleri

Konsol uzerinden ag istekleri yapma:

api Nylo API istemcisini kullanarak API cagrisi yap

Yukleme Spinner'i

Bir fonksiyon calistirilirken yukleme spinner'i goruntuler:

withSpinner Bir fonksiyon calistirilirken yukleme spinner'i goster
createSpinner Manuel kontrol icin spinner ornegi olustur

Ozel Komut Yardimlari

Komut argumanlarini yonetmek icin asagidaki yardimci metotlari da kullanabilirsiniz:

getString Komut argumanlarindan string deger al
getBool Komut argumanlarindan boole deger al
getInt Komut argumanlarindan tamsayi deger al
sleep Belirtilen sure boyunca calismayi duraklat

Harici Islemleri Calistirma

// Run a process with output displayed in the console
await runProcess('flutter build web --release');

// Run a process silently
await runProcess('flutter pub get', silent: true);

// Run a process in a specific directory
await runProcess('git pull', workingDirectory: './my-project');

Paket Yonetimi

// Add a package to pubspec.yaml
addPackage('firebase_core', version: '^2.4.0');

// Add a dev package to pubspec.yaml
addPackage('build_runner', dev: true);

// Add multiple packages at once
addPackages(['firebase_auth', 'firebase_storage', 'quickalert']);

Cikti Bicimlendirme

// Print status messages with color coding
info('Processing files...');    // Blue text
error('Operation failed');      // Red text
success('Deployment complete'); // Green text
warning('Outdated package');    // Yellow text

Etkilesimli Giris Metotlari

NyCustomCommand temel sinifi, terminalde kullanici girdisi toplamak icin cesitli metotlar saglar. Bu metotlar, ozel komutlariniz icin etkilesimli komut satiri arayuzleri olusturmayi kolaylastirir.

Metin Girdisi

String prompt(String question, {String defaultValue = ''})

Kullaniciya bir soru goruntuleyen ve metin yanitini toplayan metot.

Parametreler:

  • question: Goruntulenmesi gereken soru veya istem
  • defaultValue: Kullanici sadece Enter'a bastiginda opsiyonel varsayilan deger

Dondurur: Kullanicinin girdisini string olarak veya girdi saglanmadiysa varsayilan degeri

Ornek:

final name = prompt('What is your project name?', defaultValue: 'my_app');
final description = prompt('Enter a project description:');

Onay

bool confirm(String question, {bool defaultValue = false})

Kullaniciya evet/hayir sorusu sorar ve boole sonuc dondurur.

Parametreler:

  • question: Sorulacak evet/hayir sorusu
  • defaultValue: Varsayilan cevap (evet icin true, hayir icin false)

Dondurur: Kullanici evet yanit verdiyse true, hayir yanit verdiyse false

Ornek:

if (confirm('Would you like to continue?', defaultValue: true)) {
  // User confirmed or pressed Enter (accepting the default)
  await runProcess('flutter pub get');
} else {
  // User declined
  info('Operation canceled');
}

Tekli Secim

String select(String question, List<String> options, {String? defaultOption})

Secenekler listesi sunar ve kullanicinin birini secmesine izin verir.

Parametreler:

  • question: Secim istemi
  • options: Kullanilabilir secenekler listesi
  • defaultOption: Opsiyonel varsayilan secim

Dondurur: Secilen secenegi string olarak

Ornek:

final environment = select(
  'Select deployment environment:',
  ['development', 'staging', 'production'],
  defaultOption: 'development'
);

info('Deploying to $environment environment...');

Coklu Secim

List<String> multiSelect(String question, List<String> options)

Kullanicinin listeden birden fazla secenek secmesine izin verir.

Parametreler:

  • question: Secim istemi
  • options: Kullanilabilir secenekler listesi

Dondurur: Secilen seceneklerin listesi

Ornek:

final packages = multiSelect(
  'Select packages to install:',
  ['firebase_auth', 'dio', 'provider', 'shared_preferences', 'path_provider']
);

if (packages.isNotEmpty) {
  info('Installing ${packages.length} packages...');
  addPackages(packages);
  await runProcess('flutter pub get');
}

API Yardimci Metodu

api yardimci metodu, ozel komutlarinizdan ag istekleri yapmayi kolaylastirir.

Future<T?> api<T>(Future<T?> Function(ApiService) request) async

Temel Kullanim Ornekleri

GET Istegi

// Fetch data
final userData = await api((request) =>
  request.get('https://api.example.com/users/1')
);

POST Istegi

// Create a resource
final result = await api((request) =>
  request.post(
    'https://api.example.com/items',
    data: {'name': 'New Item', 'price': 19.99}
  )
);

PUT Istegi

// Update a resource
final updateResult = await api((request) =>
  request.put(
    'https://api.example.com/items/42',
    data: {'name': 'Updated Item', 'price': 29.99}
  )
);

DELETE Istegi

// Delete a resource
final deleteResult = await api((request) => request.delete('https://api.example.com/items/42'));

PATCH Istegi

// Partially update a resource
final patchResult = await api((request) => request.patch(
    'https://api.example.com/items/42',
    data: {'price': 24.99}
  )
);

Sorgu Parametreleri ile

// Add query parameters
final searchResults = await api((request) => request.get(
    'https://api.example.com/search',
    queryParameters: {'q': 'keyword', 'limit': 10}
  )
);

Spinner ile

// Using with spinner for better UI
final data = await withSpinner(
  task: () async {
    final data = await api((request) => request.get('https://api.example.com/config'));
    // Process the data
  },
  message: 'Loading configuration',
);

Spinner Islevi

Spinner'lar, ozel komutlarinizdaki uzun sureli islemler sirasinda gorsel geri bildirim saglar. Komutunuz asenkron gorevleri yuruturken bir mesajla birlikte animasyonlu bir gosterge goruntuleyerek ilerleme ve durum gostererek kullanici deneyimini iyilestirir.

Spinner ile kullanim

withSpinner metodu, gorev basladiginda otomatik olarak baslayan ve tamamlandiginda veya basarisiz oldugunda duran bir spinner animasyonu ile asenkron bir gorevi sarmalamaniza olanak tanir:

Future<T> withSpinner<T>({
  required Future<T> Function() task,
  required String message,
  String? successMessage,
  String? errorMessage,
}) async

Parametreler:

  • task: Calistirilacak asenkron fonksiyon
  • message: Spinner calisirken goruntulenmesi gereken metin
  • successMessage: Basarili tamamlama durumunda goruntulenmesi gereken opsiyonel mesaj
  • errorMessage: Gorev basarisiz oldugunda goruntulenmesi gereken opsiyonel mesaj

Dondurur: Gorev fonksiyonunun sonucu

Ornek:

@override
Future<void> handle(CommandResult result) async {
  // Run a task with a spinner
  final projectFiles = await withSpinner(
    task: () async {
      // Long-running task (e.g., analyzing project files)
      await sleep(2);
      return ['pubspec.yaml', 'lib/main.dart', 'README.md'];
    },
    message: 'Analyzing project structure',
    successMessage: 'Project analysis complete',
    errorMessage: 'Failed to analyze project',
  );

  // Continue with the results
  info('Found ${projectFiles.length} key files');
}

Manuel Spinner Kontrolu

Spinner durumunu manuel olarak kontrol etmeniz gereken daha karmasik senaryolar icin bir spinner ornegi olusturabilirsiniz:

ConsoleSpinner createSpinner(String message)

Parametreler:

  • message: Spinner calisirken goruntulenmesi gereken metin

Dondurur: Manuel olarak kontrol edebileceginiz bir ConsoleSpinner ornegi

Manuel kontrollu ornek:

@override
Future<void> handle(CommandResult result) async {
  // Create a spinner instance
  final spinner = createSpinner('Deploying to production');
  spinner.start();

  try {
    // First task
    await runProcess('flutter clean', silent: true);
    spinner.update('Building release version');

    // Second task
    await runProcess('flutter build web --release', silent: true);
    spinner.update('Uploading to server');

    // Third task
    await runProcess('./deploy.sh', silent: true);

    // Complete successfully
    spinner.stop(completionMessage: 'Deployment completed successfully', success: true);
  } catch (e) {
    // Handle failure
    spinner.stop(completionMessage: 'Deployment failed: $e', success: false);
    rethrow;
  }
}

Ornekler

Spinner ile Basit Gorev

@override
Future<void> handle(CommandResult result) async {
  await withSpinner(
    task: () async {
      // Install dependencies
      await runProcess('flutter pub get', silent: true);
      return true;
    },
    message: 'Installing dependencies',
    successMessage: 'Dependencies installed successfully',
  );
}

Birden Fazla Ardisik Islem

@override
Future<void> handle(CommandResult result) async {
  // First operation with spinner
  await withSpinner(
    task: () => runProcess('flutter clean', silent: true),
    message: 'Cleaning project',
  );

  // Second operation with spinner
  await withSpinner(
    task: () => runProcess('flutter pub get', silent: true),
    message: 'Updating dependencies',
  );

  // Third operation with spinner
  final buildSuccess = await withSpinner(
    task: () async {
      await runProcess('flutter build apk --release', silent: true);
      return true;
    },
    message: 'Building release APK',
    successMessage: 'Release APK built successfully',
  );

  if (buildSuccess) {
    success('Build process completed');
  }
}

Manuel Kontrollu Karmasik Is Akisi

@override
Future<void> handle(CommandResult result) async {
  final spinner = createSpinner('Starting deployment process');
  spinner.start();

  try {
    // Run multiple steps with status updates
    spinner.update('Step 1: Cleaning project');
    await runProcess('flutter clean', silent: true);

    spinner.update('Step 2: Fetching dependencies');
    await runProcess('flutter pub get', silent: true);

    spinner.update('Step 3: Building release');
    await runProcess('flutter build web --release', silent: true);

    // Complete the process
    spinner.stop(completionMessage: 'Deployment completed successfully', success: true);

  } catch (e) {
    spinner.stop(completionMessage: 'Deployment failed: $e', success: false);
  }
}

Ozel komutlarinizda spinner kullanimi, uzun sureli islemler sirasinda kullanicilara net gorsel geri bildirim saglayarak daha cilali ve profesyonel bir komut satiri deneyimi olusturur.

Seceneklerden string deger alma

String getString(String name, {String defaultValue = ''})

Parametreler:

  • name: Alinacak secenegin adi
  • defaultValue: Secenek saglanmadiysa opsiyonel varsayilan deger

Dondurur: Secenegin degerini string olarak

Ornek:

@override
CommandBuilder builder(CommandBuilder command) {
  command.addOption("name", defaultValue: "Anthony");
  return command;
}

Future<void> handle(CommandResult result) async {
  final name = result.getString('name');
  info('Hello, $name!');
}

Seceneklerden boole deger alma

bool getBool(String name, {bool defaultValue = false})

Parametreler:

  • name: Alinacak secenegin adi
  • defaultValue: Secenek saglanmadiysa opsiyonel varsayilan deger

Dondurur: Secenegin degerini boole olarak

Ornek:

@override
CommandBuilder builder(CommandBuilder command) {
  command.addFlag("verbose", defaultValue: false);
  return command;
}

Future<void> handle(CommandResult result) async {
  final verbose = result.getBool('verbose');
  if (verbose) {
    info('Verbose mode enabled');
  } else {
    info('Verbose mode disabled');
  }
}

Seceneklerden tamsayi deger alma

int getInt(String name, {int defaultValue = 0})

Parametreler:

  • name: Alinacak secenegin adi
  • defaultValue: Secenek saglanmadiysa opsiyonel varsayilan deger

Dondurur: Secenegin degerini tamsayi olarak

Ornek:

@override
CommandBuilder builder(CommandBuilder command) {
  command.addOption("count", defaultValue: 5);
  return command;
}

Future<void> handle(CommandResult result) async {
  final count = result.getInt('count');
  info('Count is set to $count');
}

Belirtilen sure boyunca bekleme

void sleep(int seconds)

Parametreler:

  • seconds: Beklenecek saniye sayisi

Dondurur: Yok

Ornek:

@override
Future<void> handle(CommandResult result) async {
  info('Sleeping for 5 seconds...');
  await sleep(5);
  info('Awake now!');
}

Cikti Bicimlendirme

Temel info, error, success ve warning metotlarinin otesinde, NyCustomCommand ek cikti yardimlari saglar:

@override
Future<void> handle(CommandResult result) async {
  // Print plain text (no color)
  line('Processing your request...');

  // Print blank lines
  newLine();       // one blank line
  newLine(3);      // three blank lines

  // Print a muted comment (gray text)
  comment('This is a background note');

  // Print a prominent alert box
  alert('Important: Please read carefully');

  // Ask is an alias for prompt
  final name = ask('What is your name?');

  // Hidden input for sensitive data (e.g., passwords, API keys)
  final apiKey = promptSecret('Enter your API key:');

  // Abort the command with an error message and exit code
  if (name.isEmpty) {
    abort('Name is required');  // exits with code 1
  }
}
Metot Aciklama
line(String message) Renksiz duz metin yazdir
newLine([int count = 1]) Bos satirlar yazdir
comment(String message) Soluk/gri metin yazdir
alert(String message) Belirgin bir uyari kutusu yazdir
ask(String question, {String defaultValue}) prompt icin takma ad
promptSecret(String question) Hassas veriler icin gizli girdi
abort([String? message, int exitCode = 1]) Komutu hata ile sonlandir

Dosya Sistemi Yardimlari

NyCustomCommand, yaygin islemler icin dart:io'yu manuel olarak ice aktarmaniz gerekmemesi icin yerlesik dosya sistemi yardimlari icerir.

Dosya Okuma ve Yazma

@override
Future<void> handle(CommandResult result) async {
  // Check if a file exists
  if (fileExists('lib/config/app.dart')) {
    info('Config file found');
  }

  // Check if a directory exists
  if (directoryExists('lib/app/models')) {
    info('Models directory found');
  }

  // Read a file (async)
  String content = await readFile('pubspec.yaml');

  // Read a file (sync)
  String contentSync = readFileSync('pubspec.yaml');

  // Write to a file (async)
  await writeFile('lib/generated/output.dart', 'class Output {}');

  // Write to a file (sync)
  writeFileSync('lib/generated/output.dart', 'class Output {}');

  // Append content to a file
  await appendFile('log.txt', 'New log entry\n');

  // Ensure a directory exists (creates it if missing)
  await ensureDirectory('lib/generated');

  // Delete a file
  await deleteFile('lib/generated/output.dart');

  // Copy a file
  await copyFile('lib/config/app.dart', 'lib/config/app.bak.dart');
}
Metot Aciklama
fileExists(String path) Dosya mevcutsa true dondurur
directoryExists(String path) Dizin mevcutsa true dondurur
readFile(String path) Dosyayi string olarak okur (asenkron)
readFileSync(String path) Dosyayi string olarak okur (senkron)
writeFile(String path, String content) Dosyaya icerik yazar (asenkron)
writeFileSync(String path, String content) Dosyaya icerik yazar (senkron)
appendFile(String path, String content) Dosyaya icerik ekler
ensureDirectory(String path) Yoksa dizin olusturur
deleteFile(String path) Dosya siler
copyFile(String source, String destination) Dosya kopyalar

JSON ve YAML Yardimlari

Yerlesik yardimlarla JSON ve YAML dosyalarini okuyun ve yazin.

@override
Future<void> handle(CommandResult result) async {
  // Read a JSON file as a Map
  Map<String, dynamic> config = await readJson('config.json');

  // Read a JSON file as a List
  List<dynamic> items = await readJsonArray('lib/app/commands/commands.json');

  // Write data to a JSON file (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 an item to a JSON array file
  // If the file contains [{"name": "a"}], this adds to that array
  await appendToJsonArray(
    'lib/app/commands/commands.json',
    {'name': 'my_command', 'category': 'app', 'script': 'my_command.dart'},
    uniqueKey: 'name',  // prevents duplicates by this key
  );

  // Read a YAML file as a Map
  Map<String, dynamic> pubspec = await readYaml('pubspec.yaml');
  info('Project: ${pubspec['name']}');
}
Metot Aciklama
readJson(String path) JSON dosyasini Map<String, dynamic> olarak okur
readJsonArray(String path) JSON dosyasini List<dynamic> olarak okur
writeJson(String path, dynamic data, {bool pretty = true}) Veriyi JSON olarak yazar
appendToJsonArray(String path, Map item, {String? uniqueKey}) JSON dizi dosyasina ekler
readYaml(String path) YAML dosyasini Map<String, dynamic> olarak okur

Buyuk-Kucuk Harf Donusturme Yardimlari

recase paketini ice aktarmadan stringleri adlandirma kurallari arasinda donusturun.

@override
Future<void> handle(CommandResult result) async {
  String input = 'user profile page';

  info(snakeCase(input));    // user_profile_page
  info(camelCase(input));    // userProfilePage
  info(pascalCase(input));   // UserProfilePage
  info(titleCase(input));    // User Profile Page
  info(kebabCase(input));    // user-profile-page
  info(constantCase(input)); // USER_PROFILE_PAGE
}
Metot Cikti Formati Ornek
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 Yardimlari

Standart Nylo Website proje dizinleri icin getter'lar. Bunlar proje kokunue gore goreceli yollar dondurur.

@override
Future<void> handle(CommandResult result) async {
  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 relative to the project root
  String customPath = projectPath('lib/app/services/auth_service.dart');
}
Ozellik 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 icinde goreceli bir yolu cozumler

Platform Yardimlari

Platformu kontrol edin ve ortam degiskenlerine erisin.

@override
Future<void> handle(CommandResult result) async {
  // Platform checks
  if (isWindows) {
    info('Running on Windows');
  } else if (isMacOS) {
    info('Running on macOS');
  } else if (isLinux) {
    info('Running on Linux');
  }

  // Current working directory
  info('Working in: $workingDirectory');

  // Read system environment variables
  String home = env('HOME', '/default/path');
}
Ozellik / Metot Aciklama
isWindows Windows uzerinde calisiyorsa true
isMacOS macOS uzerinde calisiyorsa true
isLinux Linux uzerinde calisiyorsa true
workingDirectory Mevcut calisma dizini yolu
env(String key, [String defaultValue = '']) Sistem ortam degiskenini okur

Dart ve Flutter Komutlari

Yaygin Dart ve Flutter CLI komutlarini yardimci metotlar olarak calistirin. Her biri islem cikis kodunu dondurur.

@override
Future<void> handle(CommandResult result) async {
  // 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/');  // specific directory
}
Metot Aciklama
dartFormat(String path) Dosya veya dizinde dart format calistirir
dartAnalyze([String? path]) dart analyze calistirir
flutterPubGet() flutter pub get calistirir
flutterClean() flutter clean calistirir
flutterBuild(String target, {List<String> args}) flutter build <target> calistirir
flutterTest([String? path]) flutter test calistirir

Dart Dosya Manipulasyonu

Iskele araclari olustururken kullanisli olan Dart dosyalarini programatik olarak duzenleme yardimlari.

@override
Future<void> handle(CommandResult result) async {
  // Add an import statement to a Dart file (avoids duplicates)
  await addImport(
    'lib/bootstrap/providers.dart',
    "import '/app/providers/firebase_provider.dart';",
  );

  // Insert code before the last closing brace in a file
  // Useful for adding entries to registration maps
  await insertBeforeClosingBrace(
    'lib/bootstrap/providers.dart',
    '  FirebaseProvider(),',
  );

  // Check if a file contains a specific 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 Aciklama
addImport(String filePath, String importStatement) Dart dosyasina import ekler (zaten mevcutsa atlar)
insertBeforeClosingBrace(String filePath, String code) Dosyadaki son } oncesine kod ekler
fileContains(String filePath, String identifier) Dosyanin bir string icerip icermedigini kontrol eder
fileContainsPattern(String filePath, Pattern pattern) Dosyanin bir kalipla eslesip eslesmedigini kontrol eder

Dizin Yardimlari

Dizinlerle calisma ve dosya bulma yardimlari.

@override
Future<void> handle(CommandResult result) async {
  // List directory contents
  var entities = listDirectory('lib/app/models');
  for (var entity in entities) {
    info(entity.path);
  }

  // List recursively
  var allEntities = listDirectory('lib/', recursive: true);

  // Find files matching criteria
  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 (recursive)
  await copyDirectory('lib/templates', 'lib/generated');
}
Metot Aciklama
listDirectory(String path, {bool recursive = false}) Dizin iceriklerini listeler
findFiles(String directory, {String? extension, Pattern? namePattern, bool recursive = true}) Kriterlere uyan dosyalari bulur
deleteDirectory(String path) Dizini tekrarli olarak siler
copyDirectory(String source, String destination) Dizini tekrarli olarak kopyalar

Dogrulama Yardimlari

Kod uretimi icin kullanici girdisini dogrulama ve temizleme yardimlari.

@override
Future<void> handle(CommandResult result) async {
  // Validate a Dart identifier
  if (!isValidDartIdentifier('MyClass')) {
    error('Invalid Dart identifier');
  }

  // Require a non-empty first argument
  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 Aciklama
isValidDartIdentifier(String name) Dart tanimlayici adini dogrular
requireArgument(CommandResult result, {String? message}) Bos olmayan ilk argumani gerektirir veya iptal eder
cleanClassName(String name, {List<String> removeSuffixes}) Sinif adini temizler ve PascalCase'e donusturur
cleanFileName(String name, {String extension = '.dart'}) Dosya adini temizler ve snake_case'e donusturur

Dosya Iskele Sistemi

Iskele sistemini kullanarak icerikli bir veya birden fazla dosya olusturun.

Tekli Dosya

@override
Future<void> handle(CommandResult result) async {
  await scaffold(
    path: 'lib/app/services/auth_service.dart',
    content: '''
class AuthService {
  Future<bool> login(String email, String password) async {
    // TODO: implement login
    return false;
  }
}
''',
    force: false,  // don't overwrite if exists
    successMessage: 'AuthService created',
  );
}

Birden Fazla Dosya

@override
Future<void> handle(CommandResult result) async {
  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 sinifi su degerleri kabul eder:

Ozellik Tip Aciklama
path String Olusturulacak dosya yolu
content String Dosya icerigi
successMessage String? Basari durumunda gosterilen mesaj

Gorev Calistiricisi

Otomatik durum ciktisi ile adlandirilmis bir dizi gorev calistirin.

Temel Gorev Calistiricisi

@override
Future<void> handle(CommandResult result) async {
  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,  // stop pipeline if this fails (default)
    ),
  ]);
}

Spinner'li Gorev Calistiricisi

@override
Future<void> handle(CommandResult result) async {
  await runTasksWithSpinner([
    CommandTask(
      name: 'Preparing release',
      action: () async {
        await flutterClean();
        await flutterPubGet();
      },
    ),
    CommandTask(
      name: 'Building APK',
      action: () => flutterBuild('apk', args: ['--release']),
    ),
  ]);
}

CommandTask sinifi su degerleri kabul eder:

Ozellik Tip Varsayilan Aciklama
name String zorunlu Ciktida gosterilen gorev adi
action Future<void> Function() zorunlu Calistirilacak asenkron fonksiyon
stopOnError bool true Bu basarisiz olursa kalan gorevlerin durdurulup durdurulmayacagi

Tablo Ciktisi

Konsolda bicimlendirilmis ASCII tabloları goruntuleyin.

@override
Future<void> handle(CommandResult result) async {
  table(
    ['Name', 'Version', 'Status'],
    [
      ['nylo_framework', '7.0.0', 'installed'],
      ['nylo_support', '7.0.0', 'installed'],
      ['dio', '5.4.0', 'installed'],
    ],
  );
}

Cikti:

┌─────────────────┬─────────┬───────────┐
│ Name            │ Version │ Status    │
├─────────────────┼─────────┼───────────┤
│ nylo_framework  │ 7.0.0   │ installed │
│ nylo_support    │ 7.0.0   │ installed │
│ dio             │ 5.4.0   │ installed │
└─────────────────┴─────────┴───────────┘

Ilerleme Cubugu

Bilinen oge sayisina sahip islemler icin ilerleme cubugu goruntuleyin.

Manuel Ilerleme Cubugu

@override
Future<void> handle(CommandResult result) async {
  // Create a progress bar for 100 items
  final progress = progressBar(100, message: 'Processing files');
  progress.start();

  for (int i = 0; i < 100; i++) {
    await Future.delayed(Duration(milliseconds: 50));
    progress.tick();  // increment by 1
  }

  progress.complete('All files processed');
}

Ilerleme ile Ogeleri Isleme

@override
Future<void> handle(CommandResult result) async {
  final files = findFiles('lib/', extension: '.dart');

  // Process items with automatic progress tracking
  final results = await withProgress<File, String>(
    items: files,
    process: (file, index) async {
      // process each file
      return file.path;
    },
    message: 'Analyzing Dart files',
    completionMessage: 'Analysis complete',
  );

  info('Processed ${results.length} files');
}

Senkron Ilerleme

@override
Future<void> handle(CommandResult result) async {
  final items = ['a', 'b', 'c', 'd', 'e'];

  final results = withProgressSync<String, String>(
    items: items,
    process: (item, index) {
      // synchronous processing
      return item.toUpperCase();
    },
    message: 'Converting items',
  );

  info('Results: $results');
}

ConsoleProgressBar sinifi su metodlari saglar:

Metot Aciklama
start() Ilerleme cubugunu baslatir
tick([int amount = 1]) Ilerlemeyi arttirir
update(int value) Ilerlemeyi belirli bir degere ayarlar
updateMessage(String newMessage) Goruntulunen mesaji degistirir
complete([String? completionMessage]) Opsiyonel mesajla tamamlar
stop() Tamamlamadan durdurur
current Mevcut ilerleme degeri (getter)
percentage Yuzde olarak ilerleme (getter)