feat: fix windows build erros

This commit is contained in:
nathan 2022-02-17 16:32:10 +08:00
parent 33ff6b2f23
commit ceaf1ccc21
15 changed files with 76 additions and 633 deletions

View File

@ -70,6 +70,27 @@
"options": { "options": {
"cwd": "${workspaceFolder}" "cwd": "${workspaceFolder}"
}, },
},
{
"label": "Clean",
"type": "shell",
"command": "sh ./scripts/clean.sh",
"windows": {
"options": {
"shell": {
"executable": "cmd.exe",
"args": [
"/d",
"/c",
".\\scripts\\clean.cmd"
]
}
}
},
"group": "build",
"options": {
"cwd": "${workspaceFolder}"
},
} }
] ]
} }

View File

@ -40,12 +40,5 @@
"preLaunchTask": "Generate Language Files", "preLaunchTask": "Generate Language Files",
"cwd": "${workspaceRoot}" "cwd": "${workspaceRoot}"
}, },
{
"name": "Clean",
"request": "launch",
"type": "dart",
"preLaunchTask": "Clean",
"cwd": "${workspaceRoot}"
}
] ]
} }

View File

@ -72,7 +72,7 @@
}, },
}, },
{ {
"label": "Clean FlowySDK", "label": "Clean",
"type": "shell", "type": "shell",
"command": "sh ./scripts/clean.sh", "command": "sh ./scripts/clean.sh",
"windows": { "windows": {
@ -87,7 +87,10 @@
} }
} }
}, },
"group": "build", "group": {
"kind": "build",
"isDefault": true,
},
"options": { "options": {
"cwd": "${workspaceFolder}/../" "cwd": "${workspaceFolder}/../"
}, },

View File

@ -1,413 +1,3 @@
/// Auto generate. Do not edit /// Auto generate. Do not edit
part of '../../dispatch.dart'; part of '../../dispatch.dart';
class FolderEventCreateWorkspace {
CreateWorkspaceRequest request;
FolderEventCreateWorkspace(this.request);
Future<Either<Workspace, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.CreateWorkspace.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(Workspace.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventReadCurWorkspace {
FolderEventReadCurWorkspace();
Future<Either<CurrentWorkspaceSetting, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.ReadCurWorkspace.toString();
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
(okBytes) => left(CurrentWorkspaceSetting.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventReadWorkspaces {
QueryWorkspaceRequest request;
FolderEventReadWorkspaces(this.request);
Future<Either<RepeatedWorkspace, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.ReadWorkspaces.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(RepeatedWorkspace.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventDeleteWorkspace {
QueryWorkspaceRequest request;
FolderEventDeleteWorkspace(this.request);
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.DeleteWorkspace.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventOpenWorkspace {
QueryWorkspaceRequest request;
FolderEventOpenWorkspace(this.request);
Future<Either<Workspace, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.OpenWorkspace.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(Workspace.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventReadWorkspaceApps {
QueryWorkspaceRequest request;
FolderEventReadWorkspaceApps(this.request);
Future<Either<RepeatedApp, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.ReadWorkspaceApps.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(RepeatedApp.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventCreateApp {
CreateAppRequest request;
FolderEventCreateApp(this.request);
Future<Either<App, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.CreateApp.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(App.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventDeleteApp {
QueryAppRequest request;
FolderEventDeleteApp(this.request);
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.DeleteApp.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventReadApp {
QueryAppRequest request;
FolderEventReadApp(this.request);
Future<Either<App, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.ReadApp.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(App.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventUpdateApp {
UpdateAppRequest request;
FolderEventUpdateApp(this.request);
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.UpdateApp.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventCreateView {
CreateViewRequest request;
FolderEventCreateView(this.request);
Future<Either<View, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.CreateView.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(View.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventReadView {
QueryViewRequest request;
FolderEventReadView(this.request);
Future<Either<View, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.ReadView.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(View.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventUpdateView {
UpdateViewRequest request;
FolderEventUpdateView(this.request);
Future<Either<View, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.UpdateView.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(View.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventDeleteView {
QueryViewRequest request;
FolderEventDeleteView(this.request);
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.DeleteView.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventDuplicateView {
QueryViewRequest request;
FolderEventDuplicateView(this.request);
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.DuplicateView.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventCopyLink {
FolderEventCopyLink();
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.CopyLink.toString();
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventOpenDocument {
QueryViewRequest request;
FolderEventOpenDocument(this.request);
Future<Either<DocumentDelta, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.OpenDocument.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(DocumentDelta.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventCloseView {
QueryViewRequest request;
FolderEventCloseView(this.request);
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.CloseView.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventReadTrash {
FolderEventReadTrash();
Future<Either<RepeatedTrash, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.ReadTrash.toString();
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
(okBytes) => left(RepeatedTrash.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventPutbackTrash {
TrashId request;
FolderEventPutbackTrash(this.request);
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.PutbackTrash.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventDeleteTrash {
RepeatedTrashId request;
FolderEventDeleteTrash(this.request);
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.DeleteTrash.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventRestoreAllTrash {
FolderEventRestoreAllTrash();
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.RestoreAllTrash.toString();
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventDeleteAllTrash {
FolderEventDeleteAllTrash();
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.DeleteAllTrash.toString();
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventApplyDocDelta {
DocumentDelta request;
FolderEventApplyDocDelta(this.request);
Future<Either<DocumentDelta, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.ApplyDocDelta.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(DocumentDelta.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class FolderEventExportDocument {
ExportRequest request;
FolderEventExportDocument(this.request);
Future<Either<ExportData, FlowyError>> send() {
final request = FFIRequest.create()
..event = FolderEvent.ExportDocument.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(ExportData.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}

View File

@ -1,20 +1,3 @@
/// Auto generate. Do not edit /// Auto generate. Do not edit
part of '../../dispatch.dart'; part of '../../dispatch.dart';
class NetworkEventUpdateNetworkType {
NetworkState request;
NetworkEventUpdateNetworkType(this.request);
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = NetworkEvent.UpdateNetworkType.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}

View File

@ -1,141 +1,3 @@
/// Auto generate. Do not edit /// Auto generate. Do not edit
part of '../../dispatch.dart'; part of '../../dispatch.dart';
class UserEventInitUser {
UserEventInitUser();
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = UserEvent.InitUser.toString();
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class UserEventSignIn {
SignInRequest request;
UserEventSignIn(this.request);
Future<Either<UserProfile, FlowyError>> send() {
final request = FFIRequest.create()
..event = UserEvent.SignIn.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(UserProfile.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class UserEventSignUp {
SignUpRequest request;
UserEventSignUp(this.request);
Future<Either<UserProfile, FlowyError>> send() {
final request = FFIRequest.create()
..event = UserEvent.SignUp.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(UserProfile.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class UserEventSignOut {
UserEventSignOut();
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = UserEvent.SignOut.toString();
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class UserEventUpdateUser {
UpdateUserRequest request;
UserEventUpdateUser(this.request);
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = UserEvent.UpdateUser.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class UserEventGetUserProfile {
UserEventGetUserProfile();
Future<Either<UserProfile, FlowyError>> send() {
final request = FFIRequest.create()
..event = UserEvent.GetUserProfile.toString();
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
(okBytes) => left(UserProfile.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class UserEventCheckUser {
UserEventCheckUser();
Future<Either<UserProfile, FlowyError>> send() {
final request = FFIRequest.create()
..event = UserEvent.CheckUser.toString();
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
(okBytes) => left(UserProfile.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class UserEventSetAppearanceSetting {
AppearanceSettings request;
UserEventSetAppearanceSetting(this.request);
Future<Either<Unit, FlowyError>> send() {
final request = FFIRequest.create()
..event = UserEvent.SetAppearanceSetting.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class UserEventGetAppearanceSetting {
UserEventGetAppearanceSetting();
Future<Either<AppearanceSettings, FlowyError>> send() {
final request = FFIRequest.create()
..event = UserEvent.GetAppearanceSetting.toString();
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
(okBytes) => left(AppearanceSettings.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}

View File

@ -1,3 +1,3 @@
// Auto-generated, do not edit // Auto-generated, do not edit
export './ffi_response.pb.dart';
export './ffi_request.pb.dart'; export './ffi_request.pb.dart';
export './ffi_response.pb.dart';

View File

@ -1,5 +1,5 @@
// Auto-generated, do not edit // Auto-generated, do not edit
export './folder_info.pb.dart';
export './ws_data.pb.dart';
export './revision.pb.dart';
export './document_info.pb.dart'; export './document_info.pb.dart';
export './folder_info.pb.dart';
export './revision.pb.dart';
export './ws_data.pb.dart';

View File

@ -1,6 +1,6 @@
// Auto-generated, do not edit // Auto-generated, do not edit
export './share.pb.dart';
export './app.pb.dart'; export './app.pb.dart';
export './view.pb.dart'; export './share.pb.dart';
export './trash.pb.dart'; export './trash.pb.dart';
export './view.pb.dart';
export './workspace.pb.dart'; export './workspace.pb.dart';

View File

@ -1,3 +1,3 @@
// Auto-generated, do not edit // Auto-generated, do not edit
export './network_state.pb.dart';
export './event_map.pb.dart'; export './event_map.pb.dart';
export './network_state.pb.dart';

View File

@ -1,5 +1,5 @@
// Auto-generated, do not edit // Auto-generated, do not edit
export './auth.pb.dart';
export './errors.pb.dart'; export './errors.pb.dart';
export './user_profile.pb.dart'; export './user_profile.pb.dart';
export './auth.pb.dart';
export './user_setting.pb.dart'; export './user_setting.pb.dart';

View File

@ -7,8 +7,8 @@ edition = "2018"
[lib] [lib]
name = "dart_ffi" name = "dart_ffi"
# this value will change depending on the target os # this value will change depending on the target os
# default staticlib # default cdylib
crate-type = ["staticlib"] crate-type = ["cdylib"]
[dependencies] [dependencies]

View File

@ -4,4 +4,4 @@ cargo clean
cd ../../shared-lib cd ../../shared-lib
cargo clean cargo clean
rmdir /s/q lib-infra/.cache rmdir /s/q "lib-infra/.cache"

View File

@ -1,5 +1,10 @@
[tasks.install_protobuf] [tasks.install_protobuf]
mac_alias = "install-protobuf"
windows_alias = "install-protobuf-windows"
linux_alias = "install-protobuf"
[tasks.install-protobuf]
condition_script = [ condition_script = [
""" """
if ! command -v protoc-gen-dart if ! command -v protoc-gen-dart
@ -13,21 +18,8 @@ condition_script = [
] ]
run_task = { name = ["install_protobuf_compiler"] } run_task = { name = ["install_protobuf_compiler"] }
[tasks.install_protobuf_compiler]
script = """
echo "Install protoc_plugin (Dart)"
dart pub global activate protoc_plugin
"""
script_runner = "@shell"
[tasks.install_protobuf_compiler.linux] [tasks.install-protobuf-windows]
script = """
echo "Install protoc_plugin (Dart)"
dart pub global activate protoc_plugin
"""
script_runner = "@shell"
[tasks.install_protobuf_compiler.windows]
script = """ script = """
ret = which dart ret = which dart
if is_empty ${ret} if is_empty ${ret}
@ -44,6 +36,22 @@ end
""" """
script_runner = "@duckscript" script_runner = "@duckscript"
[tasks.install_protobuf_compiler]
script = """
echo "Install protoc_plugin (Dart)"
dart pub global activate protoc_plugin
"""
script_runner = "@shell"
[tasks.install_protobuf_compiler.linux]
script = """
echo "Install protoc_plugin (Dart)"
dart pub global activate protoc_plugin
"""
script_runner = "@shell"
[tasks.check_protoc_cmd] [tasks.check_protoc_cmd]
script = [ script = [
""" """

View File

@ -44,14 +44,7 @@ pub fn gen(crate_name: &str, proto_file_dir: &str) {
let protoc_bin_path = protoc_bin_vendored::protoc_bin_path().unwrap(); let protoc_bin_path = protoc_bin_vendored::protoc_bin_path().unwrap();
// 2. generate the protobuf files(Dart) // 2. generate the protobuf files(Dart)
#[cfg(feature = "dart")]
generate_dart_protobuf_files(
crate_name,
proto_file_dir,
&proto_file_paths,
&file_names,
&protoc_bin_path,
);
// 3. generate the protobuf files(Rust) // 3. generate the protobuf files(Rust)
generate_rust_protobuf_files(&protoc_bin_path, &proto_file_paths, proto_file_dir); generate_rust_protobuf_files(&protoc_bin_path, &proto_file_paths, proto_file_dir);
@ -128,37 +121,27 @@ fn generate_dart_protobuf_files(
} }
} }
fn check_pb_compiler() {
assert!(run_command("command -v protoc"), "protoc was not installed correctly");
}
fn check_pb_dart_plugin() { fn check_pb_dart_plugin() {
if cfg!(target_os = "windows") { if cfg!(target_os = "windows") {
if !run_command("command -v protoc-gen-dart") { //Command::new("cmd")
panic!("{}", format!("\n❌ The protoc-gen-dart was not installed correctly.")) // .arg("/C")
} // .arg(cmd)
// .status()
// .expect("failed to execute process");
//panic!("{}", format!("\n❌ The protoc-gen-dart was not installed correctly."))
} else { } else {
if !run_command("command -v protoc-gen-dart") { let is_success = Command::new("sh")
.arg("-c")
.arg("command -v protoc-gen-dart")
.status()
.expect("failed to execute process")
.success();
if !is_success {
panic!("{}", format!("\n❌ The protoc-gen-dart was not installed correctly. \n✅ You can fix that by adding \"{}\" to your shell's config file.(.bashrc, .bash, etc.)", "dart pub global activate protoc_plugin")) panic!("{}", format!("\n❌ The protoc-gen-dart was not installed correctly. \n✅ You can fix that by adding \"{}\" to your shell's config file.(.bashrc, .bash, etc.)", "dart pub global activate protoc_plugin"))
} }
}; }
}
fn run_command(cmd: &str) -> bool {
let output = if cfg!(target_os = "windows") {
Command::new("cmd")
.arg("/C")
.arg(cmd)
.status()
.expect("failed to execute process")
} else {
Command::new("sh")
.arg("-c")
.arg(cmd)
.status()
.expect("failed to execute process")
};
output.success()
} }
#[cfg(feature = "proto_gen")] #[cfg(feature = "proto_gen")]