diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 089da16..fcba47f 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -17,18 +17,19 @@ jobs: fail-fast: false steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v1 + - uses: subosito/flutter-action@v1 with: - sdk: dev + channel: dev + flutter-version: "2.6.0-11.0.pre" - name: Install dependencies - run: dart pub get + run: flutter pub get - name: Verify formatting - run: dart format --output=none --set-exit-if-changed . + run: flutter format --output=none --set-exit-if-changed . - name: Analyze source code - run: dart analyze --fatal-infos + run: flutter analyze --fatal-infos test: needs: analyze @@ -45,15 +46,16 @@ jobs: git config --global core.eol lf - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v1 + - uses: subosito/flutter-action@v1 with: - sdk: dev + channel: dev + flutter-version: "2.6.0-11.0.pre" - name: Install dependencies - run: dart pub get + run: flutter pub get - name: Download libgit2 library - run: dart run libgit2dart:setup + run: flutter pub run libgit2dart:setup - name: Run tests - run: dart test --exclude-tags "remote_fetch" --platform vm + run: dart test --exclude-tags "remote_fetch" --platform=vm diff --git a/.gitignore b/.gitignore index ae51c77..2b7c5f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,50 @@ .vscode/ -.packages -.dart_tool -.pub -pubspec.lock # Coverage coverage/ # libgit2 headers for ffigen -libgit2/ \ No newline at end of file +libgit2/ + +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +pubspec.lock +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release \ No newline at end of file diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..e625d09 --- /dev/null +++ b/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 4b330ddbedab445481cc73d50a4695b9154b4e4f + channel: dev + +project_type: plugin diff --git a/bin/setup.dart b/bin/setup.dart index 223a0c6..b8b0b9c 100644 --- a/bin/setup.dart +++ b/bin/setup.dart @@ -36,9 +36,13 @@ Future download(String platform) async { logger.stdout('${ansi.green}libgit2 for $platform is already available.'); } else { logger.stdout( - '${ansi.red}libgit2 for $platform is outdated. Run: \n' + '${ansi.red}libgit2 for $platform is outdated.\n' + 'If it is dart application run: \n' + 'dart run libgit2dart:setup clean\n' + 'dart run libgit2dart:setup\n\n' + 'If it is flutter application run: \n' 'flutter pub run libgit2dart:setup clean\n' - 'flutter pub run libgit2dart:setup', + 'flutter pub run libgit2dart:setup\n\n', ); } } else { diff --git a/lib/src/util.dart b/lib/src/util.dart index b96b7b1..eec9bfd 100644 --- a/lib/src/util.dart +++ b/lib/src/util.dart @@ -67,7 +67,15 @@ DynamicLibrary loadLibrary(String name) { 'To download the library, please run the following command from the ' 'root of your project:', ); - logger.stdout('${ansi.yellow}dart run libgit2dart:setup${ansi.none}'); + logger.stdout( + '${ansi.yellow}dart run libgit2dart:setup${ansi.none} for ' + 'dart application', + ); + logger.stdout(ansi.none); + logger.stdout( + '${ansi.yellow}flutter pub run libgit2dart:setup${ansi.none} for ' + 'flutter application', + ); logger.stdout(ansi.none); rethrow; } diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt new file mode 100644 index 0000000..3cf8332 --- /dev/null +++ b/linux/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.10) +set(PROJECT_NAME "libgit2dart") +project(${PROJECT_NAME} LANGUAGES CXX) + +# This value is used when generating builds using this plugin, so it must +# not be changed +set(PLUGIN_NAME "libgit2dart_plugin") + +add_library(${PLUGIN_NAME} SHARED + "libgit2dart_plugin.cc" +) +apply_standard_settings(${PLUGIN_NAME}) +set_target_properties(${PLUGIN_NAME} PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) +target_include_directories(${PLUGIN_NAME} INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_link_libraries(${PLUGIN_NAME} PRIVATE flutter) +target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK) + +# List of absolute paths to libraries that should be bundled with the plugin +set(libgit2dart_bundled_libraries + "${CMAKE_CURRENT_SOURCE_DIR}/libgit2-1.3.0.so" + PARENT_SCOPE +) diff --git a/linux/include/libgit2dart/libgit2dart_plugin.h b/linux/include/libgit2dart/libgit2dart_plugin.h new file mode 100644 index 0000000..02bed1d --- /dev/null +++ b/linux/include/libgit2dart/libgit2dart_plugin.h @@ -0,0 +1,26 @@ +#ifndef FLUTTER_PLUGIN_LIBGIT2DART_PLUGIN_H_ +#define FLUTTER_PLUGIN_LIBGIT2DART_PLUGIN_H_ + +#include + +G_BEGIN_DECLS + +#ifdef FLUTTER_PLUGIN_IMPL +#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default"))) +#else +#define FLUTTER_PLUGIN_EXPORT +#endif + +typedef struct _Libgit2dartPlugin Libgit2dartPlugin; +typedef struct { + GObjectClass parent_class; +} Libgit2dartPluginClass; + +FLUTTER_PLUGIN_EXPORT GType libgit2dart_plugin_get_type(); + +FLUTTER_PLUGIN_EXPORT void libgit2dart_plugin_register_with_registrar( + FlPluginRegistrar* registrar); + +G_END_DECLS + +#endif // FLUTTER_PLUGIN_LIBGIT2DART_PLUGIN_H_ diff --git a/linux/libgit2-1.3.0.so b/linux/libgit2-1.3.0.so new file mode 100644 index 0000000..d4285d1 Binary files /dev/null and b/linux/libgit2-1.3.0.so differ diff --git a/linux/libgit2dart_plugin.cc b/linux/libgit2dart_plugin.cc new file mode 100644 index 0000000..2b450ea --- /dev/null +++ b/linux/libgit2dart_plugin.cc @@ -0,0 +1,70 @@ +#include "include/libgit2dart/libgit2dart_plugin.h" + +#include +#include +#include + +#include + +#define LIBGIT2DART_PLUGIN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), libgit2dart_plugin_get_type(), \ + Libgit2dartPlugin)) + +struct _Libgit2dartPlugin { + GObject parent_instance; +}; + +G_DEFINE_TYPE(Libgit2dartPlugin, libgit2dart_plugin, g_object_get_type()) + +// Called when a method call is received from Flutter. +static void libgit2dart_plugin_handle_method_call( + Libgit2dartPlugin* self, + FlMethodCall* method_call) { + g_autoptr(FlMethodResponse) response = nullptr; + + const gchar* method = fl_method_call_get_name(method_call); + + if (strcmp(method, "getPlatformVersion") == 0) { + struct utsname uname_data = {}; + uname(&uname_data); + g_autofree gchar *version = g_strdup_printf("Linux %s", uname_data.version); + g_autoptr(FlValue) result = fl_value_new_string(version); + response = FL_METHOD_RESPONSE(fl_method_success_response_new(result)); + } else { + response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new()); + } + + fl_method_call_respond(method_call, response, nullptr); +} + +static void libgit2dart_plugin_dispose(GObject* object) { + G_OBJECT_CLASS(libgit2dart_plugin_parent_class)->dispose(object); +} + +static void libgit2dart_plugin_class_init(Libgit2dartPluginClass* klass) { + G_OBJECT_CLASS(klass)->dispose = libgit2dart_plugin_dispose; +} + +static void libgit2dart_plugin_init(Libgit2dartPlugin* self) {} + +static void method_call_cb(FlMethodChannel* channel, FlMethodCall* method_call, + gpointer user_data) { + Libgit2dartPlugin* plugin = LIBGIT2DART_PLUGIN(user_data); + libgit2dart_plugin_handle_method_call(plugin, method_call); +} + +void libgit2dart_plugin_register_with_registrar(FlPluginRegistrar* registrar) { + Libgit2dartPlugin* plugin = LIBGIT2DART_PLUGIN( + g_object_new(libgit2dart_plugin_get_type(), nullptr)); + + g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new(); + g_autoptr(FlMethodChannel) channel = + fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar), + "libgit2dart", + FL_METHOD_CODEC(codec)); + fl_method_channel_set_method_call_handler(channel, method_call_cb, + g_object_ref(plugin), + g_object_unref); + + g_object_unref(plugin); +} diff --git a/macos/Classes/Libgit2dartPlugin.swift b/macos/Classes/Libgit2dartPlugin.swift new file mode 100644 index 0000000..4c24597 --- /dev/null +++ b/macos/Classes/Libgit2dartPlugin.swift @@ -0,0 +1,19 @@ +import Cocoa +import FlutterMacOS + +public class Libgit2dartPlugin: NSObject, FlutterPlugin { + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel(name: "libgit2dart", binaryMessenger: registrar.messenger) + let instance = Libgit2dartPlugin() + registrar.addMethodCallDelegate(instance, channel: channel) + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + switch call.method { + case "getPlatformVersion": + result("macOS " + ProcessInfo.processInfo.operatingSystemVersionString) + default: + result(FlutterMethodNotImplemented) + } + } +} diff --git a/macos/libgit2-1.3.0.dylib b/macos/libgit2-1.3.0.dylib new file mode 100644 index 0000000..f689fac Binary files /dev/null and b/macos/libgit2-1.3.0.dylib differ diff --git a/macos/libgit2dart.podspec b/macos/libgit2dart.podspec new file mode 100644 index 0000000..35baeb5 --- /dev/null +++ b/macos/libgit2dart.podspec @@ -0,0 +1,23 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint libgit2dart.podspec` to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'libgit2dart' + s.version = '0.0.1' + s.summary = 'Dart bindings to libgit2.' + s.description = <<-DESC +Dart bindings to libgit2. + DESC + s.homepage = 'https://github.com/SkinnyMind/libgit2dart' + s.license = { :file => '../LICENSE' } + s.author = { 'Aleksey Kulikov' => 'skinny.mind@gmail.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'FlutterMacOS' + s.vendored_libraries = 'libgit2-1.3.0.dylib' + + s.platform = :osx, '10.11' + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } + s.swift_version = '5.0' +end diff --git a/pubspec.yaml b/pubspec.yaml index cb6b65f..16c4f59 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,6 +4,7 @@ version: 0.0.1 environment: sdk: ">=2.15.0-82.0.dev <3.0.0" + flutter: ">=2.5.0" dependencies: archive: ^3.1.6 @@ -17,6 +18,16 @@ dev_dependencies: path: ^1.8.0 test: ^1.17.5 +flutter: + plugin: + platforms: + linux: + pluginClass: Libgit2dartPlugin + macos: + pluginClass: Libgit2dartPlugin + windows: + pluginClass: Libgit2dartPlugin + ffigen: output: "lib/src/bindings/libgit2_bindings.dart" headers: diff --git a/windows/.gitignore b/windows/.gitignore new file mode 100644 index 0000000..b3eb2be --- /dev/null +++ b/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt new file mode 100644 index 0000000..79cdea5 --- /dev/null +++ b/windows/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.14) +set(PROJECT_NAME "libgit2dart") +project(${PROJECT_NAME} LANGUAGES CXX) + +# This value is used when generating builds using this plugin, so it must +# not be changed +set(PLUGIN_NAME "libgit2dart_plugin") + +add_library(${PLUGIN_NAME} SHARED + "libgit2dart_plugin.cpp" +) +apply_standard_settings(${PLUGIN_NAME}) +set_target_properties(${PLUGIN_NAME} PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) +target_include_directories(${PLUGIN_NAME} INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin) + +# List of absolute paths to libraries that should be bundled with the plugin +set(libgit2dart_bundled_libraries + "${CMAKE_CURRENT_SOURCE_DIR}/libgit2-1.3.0.dll" + PARENT_SCOPE +) diff --git a/windows/include/libgit2dart/libgit2dart_plugin.h b/windows/include/libgit2dart/libgit2dart_plugin.h new file mode 100644 index 0000000..62e6164 --- /dev/null +++ b/windows/include/libgit2dart/libgit2dart_plugin.h @@ -0,0 +1,23 @@ +#ifndef FLUTTER_PLUGIN_LIBGIT2DART_PLUGIN_H_ +#define FLUTTER_PLUGIN_LIBGIT2DART_PLUGIN_H_ + +#include + +#ifdef FLUTTER_PLUGIN_IMPL +#define FLUTTER_PLUGIN_EXPORT __declspec(dllexport) +#else +#define FLUTTER_PLUGIN_EXPORT __declspec(dllimport) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +FLUTTER_PLUGIN_EXPORT void Libgit2dartPluginRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // FLUTTER_PLUGIN_LIBGIT2DART_PLUGIN_H_ diff --git a/windows/libgit2-1.3.0.dll b/windows/libgit2-1.3.0.dll new file mode 100644 index 0000000..06932ae Binary files /dev/null and b/windows/libgit2-1.3.0.dll differ diff --git a/windows/libgit2dart_plugin.cpp b/windows/libgit2dart_plugin.cpp new file mode 100644 index 0000000..e9d73d8 --- /dev/null +++ b/windows/libgit2dart_plugin.cpp @@ -0,0 +1,82 @@ +#include "include/libgit2dart/libgit2dart_plugin.h" + +// This must be included before many other Windows headers. +#include + +// For getPlatformVersion; remove unless needed for your plugin implementation. +#include + +#include +#include +#include + +#include +#include +#include + +namespace { + +class Libgit2dartPlugin : public flutter::Plugin { + public: + static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar); + + Libgit2dartPlugin(); + + virtual ~Libgit2dartPlugin(); + + private: + // Called when a method is called on this plugin's channel from Dart. + void HandleMethodCall( + const flutter::MethodCall &method_call, + std::unique_ptr> result); +}; + +// static +void Libgit2dartPlugin::RegisterWithRegistrar( + flutter::PluginRegistrarWindows *registrar) { + auto channel = + std::make_unique>( + registrar->messenger(), "libgit2dart", + &flutter::StandardMethodCodec::GetInstance()); + + auto plugin = std::make_unique(); + + channel->SetMethodCallHandler( + [plugin_pointer = plugin.get()](const auto &call, auto result) { + plugin_pointer->HandleMethodCall(call, std::move(result)); + }); + + registrar->AddPlugin(std::move(plugin)); +} + +Libgit2dartPlugin::Libgit2dartPlugin() {} + +Libgit2dartPlugin::~Libgit2dartPlugin() {} + +void Libgit2dartPlugin::HandleMethodCall( + const flutter::MethodCall &method_call, + std::unique_ptr> result) { + if (method_call.method_name().compare("getPlatformVersion") == 0) { + std::ostringstream version_stream; + version_stream << "Windows "; + if (IsWindows10OrGreater()) { + version_stream << "10+"; + } else if (IsWindows8OrGreater()) { + version_stream << "8"; + } else if (IsWindows7OrGreater()) { + version_stream << "7"; + } + result->Success(flutter::EncodableValue(version_stream.str())); + } else { + result->NotImplemented(); + } +} + +} // namespace + +void Libgit2dartPluginRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar) { + Libgit2dartPlugin::RegisterWithRegistrar( + flutter::PluginRegistrarManager::GetInstance() + ->GetRegistrar(registrar)); +}