git_operations 0.0.1 copy "git_operations: ^0.0.1" to clipboard
git_operations: ^0.0.1 copied to clipboard

Git operation workflows built on path_utils command execution.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:git_operations/git_operations.dart';

import 'documentation/git_docs.dart';
import 'git_commands/git_command_demo.dart';
import 'pages/docs_browser_page.dart';

void main() {
  runApp(const GitOperationsExampleApp());
}

class GitOperationsExampleApp extends StatelessWidget {
  const GitOperationsExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'git_operations example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.indigo,
          brightness: Brightness.light,
        ),
        useMaterial3: true,
      ),
      darkTheme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.indigo,
          brightness: Brightness.dark,
        ),
        useMaterial3: true,
      ),
      themeMode: ThemeMode.system,
      home: const DemoPage(),
    );
  }
}

class DemoPage extends StatefulWidget {
  const DemoPage({super.key});

  @override
  State<DemoPage> createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  late Future<_RepoInfo> _repoInfo;
  int _selectedTab = 0;

  @override
  void initState() {
    super.initState();
    _repoInfo = _loadRepoInfo();
  }

  Future<_RepoInfo> _loadRepoInfo() async {
    if (!isGitCommandsAvailable) {
      return const _RepoInfo(
        name: 'git_operations',
        path: '(desktop only)',
        branch: null,
      );
    }

    final path = await resolveRepoPath();
    final branch = await resolveCurrentBranch(path);
    final segments = path.split(RegExp(r'[/\\]'));
    return _RepoInfo(
      name: segments.isEmpty ? path : segments.last,
      path: path,
      branch: branch,
    );
  }

  void _refresh() {
    final refreshedRepoInfo = _loadRepoInfo();
    setState(() {
      _repoInfo = refreshedRepoInfo;
    });
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<_RepoInfo>(
      future: _repoInfo,
      builder: (context, snapshot) {
        final repoInfo = snapshot.data;
        return Scaffold(
          appBar: AppBar(
            title: const Text('git_operations example'),
            actions: [
              IconButton(
                onPressed: _refresh,
                tooltip: 'Refresh',
                icon: const Icon(Icons.refresh),
              ),
            ],
          ),
          body: snapshot.hasError
              ? Center(child: Text('Error: ${snapshot.error}'))
              : repoInfo == null
              ? const Center(child: CircularProgressIndicator())
              : _selectedTab == 0
              ? _RepositoryOverview(repoInfo: repoInfo)
              : DocsBrowserPage(repoPath: repoInfo.path),
          bottomNavigationBar: NavigationBar(
            selectedIndex: _selectedTab,
            onDestinationSelected: (index) {
              setState(() => _selectedTab = index);
            },
            destinations: const [
              NavigationDestination(
                icon: Icon(Icons.home_outlined),
                selectedIcon: Icon(Icons.home),
                label: 'Repository',
              ),
              NavigationDestination(
                icon: Icon(Icons.menu_book_outlined),
                selectedIcon: Icon(Icons.menu_book),
                label: 'Docs',
              ),
            ],
          ),
        );
      },
    );
  }
}

class _RepositoryOverview extends StatelessWidget {
  const _RepositoryOverview({required this.repoInfo});

  final _RepoInfo repoInfo;

  @override
  Widget build(BuildContext context) {
    final repo = _ExampleRepo(
      name: repoInfo.name,
      path: repoInfo.path,
      branch: repoInfo.branch,
    );

    return ListView(
      padding: const EdgeInsets.all(16),
      children: [
        Text(
          'Package overview',
          style: Theme.of(context).textTheme.titleMedium,
        ),
        const SizedBox(height: 12),
        Text(
          'This app demonstrates the GitRepository contract, runs git commands through '
          'git_operations GitCommandRunner, and browses upstream git/git man pages from GitHub.',
          style: Theme.of(context).textTheme.bodyMedium,
        ),
        const SizedBox(height: 24),
        _InfoCard(
          title: 'Repository',
          value: repo.name,
        ),
        _InfoCard(
          title: 'Expanded path',
          value: repo.getExpandedPath((_) {}),
        ),
        _InfoCard(
          title: 'Current branch',
          value: repo.currentBranchOnDisk ?? '(unknown)',
        ),
        _InfoCard(
          title: 'Command docs source',
          value: '${gitDocsSource.repositorySlug} @ ${gitDocsSource.branch}',
        ),
        const SizedBox(height: 16),
        Text(
          'Use the Docs tab to search git/git man pages. Commands with a Run button '
          'can be executed directly against this repository.',
          style: Theme.of(context).textTheme.bodyMedium,
        ),
        const SizedBox(height: 16),
        Text(
          'GitOperationService also provides checkout, stash, and pull workflows with '
          'user dialogs for untracked and dirty working directories.',
          style: Theme.of(context).textTheme.bodyMedium,
        ),
      ],
    );
  }
}

class _RepoInfo {
  const _RepoInfo({
    required this.name,
    required this.path,
    required this.branch,
  });

  final String name;
  final String path;
  final String? branch;
}

class _ExampleRepo implements GitRepository {
  const _ExampleRepo({
    required this.name,
    required this.path,
    this.branch,
  });

  @override
  final String name;
  final String path;
  final String? branch;

  @override
  String? get currentBranchOnDisk => branch;

  @override
  String getExpandedPath(void Function(String message) log) => path;
}

class _InfoCard extends StatelessWidget {
  const _InfoCard({required this.title, required this.value});

  final String title;
  final String value;

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: const EdgeInsets.only(bottom: 8),
      child: ListTile(
        title: Text(title),
        subtitle: SelectableText(
          value,
          style: Theme.of(context).textTheme.bodyMedium?.copyWith(
            fontFamily: 'monospace',
          ),
        ),
      ),
    );
  }
}
1
likes
160
points
84
downloads

Documentation

API reference

Publisher

verified publishergantt-sync.com

Weekly Downloads

Git operation workflows built on path_utils command execution.

Repository (GitHub)
View/report issues

License

Apache-2.0 (license)

Dependencies

path_utils

More

Packages that depend on git_operations