avrotize 2.20.3__py3-none-any.whl → 2.20.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,149 @@
1
+ #!/bin/bash
2
+ # Shell script to run tests with code coverage and generate reports
3
+ # Generated for project: {{ project_name }}
4
+
5
+ # Default values
6
+ THRESHOLD=85
7
+ HTML_REPORT=false
8
+ OPEN_REPORT=false
9
+ FAIL_ON_LOW_COVERAGE=true
10
+
11
+ # Parse command line arguments
12
+ while [[ $# -gt 0 ]]; do
13
+ case $1 in
14
+ --threshold)
15
+ THRESHOLD="$2"
16
+ shift 2
17
+ ;;
18
+ --html-report)
19
+ HTML_REPORT=true
20
+ shift
21
+ ;;
22
+ --open-report)
23
+ OPEN_REPORT=true
24
+ HTML_REPORT=true
25
+ shift
26
+ ;;
27
+ --no-fail)
28
+ FAIL_ON_LOW_COVERAGE=false
29
+ shift
30
+ ;;
31
+ *)
32
+ echo "Unknown option: $1"
33
+ echo "Usage: $0 [--threshold N] [--html-report] [--open-report] [--no-fail]"
34
+ exit 1
35
+ ;;
36
+ esac
37
+ done
38
+
39
+ echo "🧪 Running tests with code coverage for {{ project_name }}..."
40
+
41
+ # Clean previous coverage results
42
+ COVERAGE_DIR="./coverage"
43
+ if [ -d "$COVERAGE_DIR" ]; then
44
+ rm -rf "$COVERAGE_DIR"
45
+ echo "🧹 Cleaned previous coverage results"
46
+ fi
47
+
48
+ # Run tests with coverage collection
49
+ echo "📊 Collecting code coverage..."
50
+ dotnet test --collect:"XPlat Code Coverage" --results-directory:"$COVERAGE_DIR" --logger:"console;verbosity=detailed"
51
+ TEST_EXIT_CODE=$?
52
+
53
+ if [ $TEST_EXIT_CODE -ne 0 ]; then
54
+ echo "❌ Tests failed!"
55
+ exit $TEST_EXIT_CODE
56
+ fi
57
+
58
+ # Find coverage file
59
+ COVERAGE_FILE=$(find "$COVERAGE_DIR" -name "*.cobertura.xml" | head -n 1)
60
+ if [ -z "$COVERAGE_FILE" ]; then
61
+ echo "❌ No coverage file found!"
62
+ exit 1
63
+ fi
64
+
65
+ echo "📄 Coverage file: $COVERAGE_FILE"
66
+
67
+ # Parse coverage percentage using grep and sed
68
+ COVERAGE_LINE_RATE=$(grep -o 'line-rate="[0-9.]*"' "$COVERAGE_FILE" | head -n 1 | sed 's/line-rate="//;s/"//')
69
+ COVERAGE_PERCENT=$(echo "$COVERAGE_LINE_RATE * 100" | bc -l | xargs printf "%.2f")
70
+
71
+ # Parse branch coverage
72
+ BRANCH_LINE_RATE=$(grep -o 'branch-rate="[0-9.]*"' "$COVERAGE_FILE" | head -n 1 | sed 's/branch-rate="//;s/"//')
73
+ BRANCH_PERCENT=$(echo "$BRANCH_LINE_RATE * 100" | bc -l | xargs printf "%.2f")
74
+
75
+ # Color codes
76
+ GREEN='\033[0;32m'
77
+ RED='\033[0;31m'
78
+ BLUE='\033[0;34m'
79
+ YELLOW='\033[1;33m'
80
+ CYAN='\033[0;36m'
81
+ WHITE='\033[1;37m'
82
+ NC='\033[0m' # No Color
83
+
84
+ # Determine colors based on threshold
85
+ LINE_COLOR=$GREEN
86
+ if (( $(echo "$COVERAGE_PERCENT < $THRESHOLD" | bc -l) )); then
87
+ LINE_COLOR=$RED
88
+ fi
89
+
90
+ BRANCH_COLOR=$GREEN
91
+ if (( $(echo "$BRANCH_PERCENT < $THRESHOLD" | bc -l) )); then
92
+ BRANCH_COLOR=$RED
93
+ fi
94
+
95
+ echo -e "📈 Line Coverage: ${LINE_COLOR}${COVERAGE_PERCENT}%${NC}"
96
+ echo -e "🌿 Branch Coverage: ${BRANCH_COLOR}${BRANCH_PERCENT}%${NC}"
97
+
98
+ # Generate HTML report if requested
99
+ if [ "$HTML_REPORT" = true ]; then
100
+ echo -e "${BLUE}📊 Generating HTML coverage report...${NC}"
101
+
102
+ # Check if reportgenerator is installed
103
+ if ! command -v reportgenerator &> /dev/null; then
104
+ echo -e "${YELLOW}⬇️ Installing ReportGenerator...${NC}"
105
+ dotnet tool install -g dotnet-reportgenerator-globaltool
106
+ fi
107
+
108
+ HTML_REPORT_PATH="$COVERAGE_DIR/html"
109
+ reportgenerator "-reports:$COVERAGE_FILE" "-targetdir:$HTML_REPORT_PATH" "-reporttypes:Html"
110
+
111
+ echo -e "${GREEN}📊 HTML report generated: $HTML_REPORT_PATH/index.html${NC}"
112
+
113
+ if [ "$OPEN_REPORT" = true ]; then
114
+ if command -v xdg-open &> /dev/null; then
115
+ xdg-open "$HTML_REPORT_PATH/index.html"
116
+ elif command -v open &> /dev/null; then
117
+ open "$HTML_REPORT_PATH/index.html"
118
+ else
119
+ echo "Cannot auto-open browser. Please open: $HTML_REPORT_PATH/index.html"
120
+ fi
121
+ echo -e "${GREEN}🌐 Opened coverage report in browser${NC}"
122
+ fi
123
+ fi
124
+
125
+ # Coverage summary
126
+ echo ""
127
+ echo -e "${CYAN}📊 Coverage Summary:${NC}"
128
+ echo -e " Line Coverage: ${WHITE}${COVERAGE_PERCENT}%${NC} (Threshold: ${THRESHOLD}%)"
129
+ echo -e " Branch Coverage: ${WHITE}${BRANCH_PERCENT}%${NC}"
130
+
131
+ # Determine status
132
+ if (( $(echo "$COVERAGE_PERCENT >= $THRESHOLD" | bc -l) )); then
133
+ echo -e " Status: ${GREEN}✅ PASSED${NC}"
134
+ STATUS_CODE=0
135
+ else
136
+ echo -e " Status: ${RED}❌ FAILED${NC}"
137
+ STATUS_CODE=1
138
+ fi
139
+
140
+ # Fail if coverage is below threshold and FAIL_ON_LOW_COVERAGE is set
141
+ if [ "$FAIL_ON_LOW_COVERAGE" = true ] && [ $STATUS_CODE -eq 1 ]; then
142
+ echo ""
143
+ echo -e "${RED}❌ Coverage ${COVERAGE_PERCENT}% is below the required threshold of ${THRESHOLD}%${NC}"
144
+ exit 1
145
+ fi
146
+
147
+ echo ""
148
+ echo -e "${GREEN}✅ Coverage analysis completed successfully!${NC}"
149
+ exit 0
@@ -11,5 +11,9 @@
11
11
  <PackageReference Include="NUnit" Version="{{ NUNIT_VERSION }}" />
12
12
  <PackageReference Include="NUnit3TestAdapter" Version="{{ NUNIT_ADAPTER_VERSION }}" />
13
13
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="{{ MSTEST_SDK_VERSION }}" />
14
+ <PackageReference Include="coverlet.collector" Version="{{ COVERLET_VERSION }}">
15
+ <PrivateAssets>all</PrivateAssets>
16
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
17
+ </PackageReference>
14
18
  </ItemGroup>
15
19
  </Project>
avrotize/avrotocsharp.py CHANGED
@@ -14,9 +14,12 @@ from avrotize.constants import (
14
14
  NEWTONSOFT_JSON_VERSION,
15
15
  SYSTEM_TEXT_JSON_VERSION,
16
16
  SYSTEM_MEMORY_DATA_VERSION,
17
+ PROTOBUF_NET_VERSION,
18
+ MSGPACK_VERSION,
17
19
  NUNIT_VERSION,
18
20
  NUNIT_ADAPTER_VERSION,
19
21
  MSTEST_SDK_VERSION,
22
+ COVERLET_VERSION,
20
23
  )
21
24
  import glob
22
25
 
@@ -49,7 +52,9 @@ class AvroToCSharp:
49
52
  self.system_text_json_annotation = False
50
53
  self.newtonsoft_json_annotation = False
51
54
  self.system_xml_annotation = False
55
+ self.msgpack_annotation = False
52
56
  self.avro_annotation = False
57
+ self.protobuf_net_annotation = False
53
58
  self.generated_types: Dict[str,str] = {}
54
59
  self.generated_avro_types: Dict[str, Dict[str, Union[str, Dict, List]]] = {}
55
60
  self.type_dict: Dict[str, Dict] = {}
@@ -177,7 +182,14 @@ class AvroToCSharp:
177
182
  else:
178
183
  class_definition += f"[XmlRoot(\"{class_name}\")]\n"
179
184
 
180
- fields_str = [self.generate_property(field, class_name, avro_namespace) for field in avro_schema.get('fields', [])]
185
+ if self.protobuf_net_annotation:
186
+ class_definition += "[ProtoContract]\n"
187
+
188
+ # Add MessagePack serialization attribute for the class if enabled
189
+ if self.msgpack_annotation:
190
+ class_definition += "[MessagePackObject]\n"
191
+
192
+ fields_str = [self.generate_property(index + 1, field, class_name, avro_namespace) for index, field in enumerate(avro_schema.get('fields', []))]
181
193
  class_body = "\n".join(fields_str)
182
194
  class_definition += f"public partial class {class_name}"
183
195
  if self.avro_annotation:
@@ -250,9 +262,11 @@ class AvroToCSharp:
250
262
  "avrotocsharp/dataclass_core.jinja",
251
263
  class_name=class_name,
252
264
  avro_annotation=self.avro_annotation,
265
+ protobuf_net_annotation=self.protobuf_net_annotation,
253
266
  system_text_json_annotation=self.system_text_json_annotation,
254
267
  newtonsoft_json_annotation=self.newtonsoft_json_annotation,
255
- system_xml_annotation=self.system_xml_annotation,
268
+ system_xml_annotation=self.system_xml_annotation,
269
+ msgpack_annotation=self.msgpack_annotation,
256
270
  json_match_clauses=self.create_is_json_match_clauses(avro_schema, avro_namespace, class_name)
257
271
  )
258
272
 
@@ -516,14 +530,19 @@ class AvroToCSharp:
516
530
  union_type_name = union_type.rsplit('.', 1)[-1]
517
531
  if self.is_csharp_reserved_word(union_type_name):
518
532
  union_type_name = f"@{union_type_name}"
533
+ proto_member_name = union_type_name[1:] if union_type_name.startswith("@") else union_type_name
519
534
  class_definition_objctr += f"{INDENT*3}if (obj is {union_type})\n{INDENT*3}{{\n{INDENT*4}self.{union_type_name} = ({union_type})obj;\n{INDENT*4}return self;\n{INDENT*3}}}\n"
520
535
  if union_type in self.generated_types and self.generated_types[union_type] == "class":
521
536
  class_definition_genericrecordctor += f"{INDENT*3}if (obj.Schema.Fullname == {union_type}.AvroSchema.Fullname)\n{INDENT*3}{{\n{INDENT*4}this.{union_type_name} = new {union_type}(obj);\n{INDENT*4}return;\n{INDENT*3}}}\n"
522
537
  class_definition_ctors += \
523
538
  f"{INDENT*2}/// <summary>\n{INDENT*2}/// Constructor for {union_type_name} values\n{INDENT*2}/// </summary>\n" + \
524
539
  f"{INDENT*2}public {union_class_name}({union_type}? {union_type_name})\n{INDENT*2}{{\n{INDENT*3}this.{union_type_name} = {union_type_name};\n{INDENT*2}}}\n"
540
+ # Add Key attribute for MessagePack serialization if enabled
541
+ msgpack_key_attr = f"{INDENT*2}[Key({i})]\n" if self.msgpack_annotation else ""
525
542
  class_definition_decls += \
526
543
  f"{INDENT*2}/// <summary>\n{INDENT*2}/// Gets the {union_type_name} value\n{INDENT*2}/// </summary>\n" + \
544
+ (f"{INDENT*2}[ProtoMember({i+1}, Name=\"{proto_member_name}\")]\n" if self.protobuf_net_annotation else "") + \
545
+ msgpack_key_attr + \
527
546
  f"{INDENT*2}public {union_type}? {union_type_name} {{ get; set; }} = null;\n"
528
547
  class_definition_toobject += f"{INDENT*3}if ({union_type_name} != null) {{\n{INDENT*4}return {union_type_name};\n{INDENT*3}}}\n"
529
548
 
@@ -570,9 +589,14 @@ class AvroToCSharp:
570
589
  if self.system_xml_annotation:
571
590
  class_definition += \
572
591
  f"{INDENT}[XmlRoot(\"{union_class_name}\")]\n"
592
+ if self.msgpack_annotation:
593
+ class_definition += \
594
+ f"{INDENT}[MessagePackObject]\n"
573
595
  if self.system_text_json_annotation:
574
596
  class_definition += \
575
597
  f"{INDENT}[System.Text.Json.Serialization.JsonConverter(typeof({union_class_name}))]\n"
598
+ if self.protobuf_net_annotation:
599
+ class_definition += f"{INDENT}[ProtoContract]\n"
576
600
  class_definition += \
577
601
  f"{INDENT}public sealed class {union_class_name}"
578
602
  if self.system_text_json_annotation:
@@ -697,6 +721,8 @@ class AvroToCSharp:
697
721
  def is_enum_type(self, avro_type: Union[str, Dict, List]) -> bool:
698
722
  """ Checks if a type is an enum (including nullable enums) """
699
723
  if isinstance(avro_type, str):
724
+ if avro_type in ('null', 'boolean', 'int', 'long', 'float', 'double', 'bytes', 'string'):
725
+ return False
700
726
  schema = self.schema_doc
701
727
  name = avro_type.split('.')[-1]
702
728
  namespace = ".".join(avro_type.split('.')[:-1])
@@ -711,7 +737,7 @@ class AvroToCSharp:
711
737
  return avro_type.get('type') == 'enum'
712
738
  return False
713
739
 
714
- def generate_property(self, field: Dict, class_name: str, parent_namespace: str) -> str:
740
+ def generate_property(self, field_index: int, field: Dict, class_name: str, parent_namespace: str) -> str:
715
741
  """ Generates a property """
716
742
  is_enum_type = self.is_enum_type(field['type'])
717
743
  field_type = self.convert_avro_type_to_csharp(
@@ -727,6 +753,9 @@ class AvroToCSharp:
727
753
  prop = ''
728
754
  prop += f"{INDENT}/// <summary>\n{INDENT}/// { field.get('doc', field_name) }\n{INDENT}/// </summary>\n"
729
755
 
756
+ if self.protobuf_net_annotation:
757
+ prop += f"{INDENT}[ProtoMember({field_index}, Name=\"{annotation_name}\")]\n"
758
+
730
759
  # Add XML serialization attribute if enabled
731
760
  if self.system_xml_annotation:
732
761
  xmlkind = field.get('xmlkind', 'element')
@@ -735,6 +764,10 @@ class AvroToCSharp:
735
764
  elif xmlkind == 'attribute':
736
765
  prop += f"{INDENT}[XmlAttribute(\"{annotation_name}\")]\n"
737
766
 
767
+ # Add MessagePack serialization attribute if enabled
768
+ if self.msgpack_annotation:
769
+ prop += f"{INDENT}[Key({field_index})]\n"
770
+
738
771
  if self.system_text_json_annotation:
739
772
  prop += f"{INDENT}[System.Text.Json.Serialization.JsonPropertyName(\"{annotation_name}\")]\n"
740
773
  if is_enum_type:
@@ -743,6 +776,8 @@ class AvroToCSharp:
743
776
  prop += f"{INDENT}[System.Text.Json.Serialization.JsonConverter(typeof({field_type}))]\n"
744
777
  if self.newtonsoft_json_annotation:
745
778
  prop += f"{INDENT}[Newtonsoft.Json.JsonProperty(\"{annotation_name}\")]\n"
779
+ if is_enum_type:
780
+ prop += f"{INDENT}[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]\n"
746
781
 
747
782
  # Determine initialization value
748
783
  initialization = ""
@@ -785,6 +820,8 @@ class AvroToCSharp:
785
820
  # Common using statements (add more as needed)
786
821
  file_content = "using System;\nusing System.Collections.Generic;\n"
787
822
  file_content += "using System.Linq;\n"
823
+ if self.protobuf_net_annotation:
824
+ file_content += "using ProtoBuf;\n"
788
825
  if self.system_text_json_annotation:
789
826
  file_content += "using System.Text.Json;\n"
790
827
  file_content += "using System.Text.Json.Serialization;\n"
@@ -792,6 +829,8 @@ class AvroToCSharp:
792
829
  file_content += "using Newtonsoft.Json;\n"
793
830
  if self.system_xml_annotation: # Add XML serialization using directive
794
831
  file_content += "using System.Xml.Serialization;\n"
832
+ if self.msgpack_annotation: # Add MessagePack serialization using directive
833
+ file_content += "using MessagePack;\n"
795
834
 
796
835
  if namespace:
797
836
  # Namespace declaration with correct indentation for the definition
@@ -833,7 +872,9 @@ class AvroToCSharp:
833
872
  avro_annotation=self.avro_annotation,
834
873
  system_xml_annotation=self.system_xml_annotation,
835
874
  system_text_json_annotation=self.system_text_json_annotation,
836
- newtonsoft_json_annotation=self.newtonsoft_json_annotation
875
+ newtonsoft_json_annotation=self.newtonsoft_json_annotation,
876
+ protobuf_net_annotation=self.protobuf_net_annotation,
877
+ msgpack_annotation=self.msgpack_annotation
837
878
  )
838
879
  elif type_kind == "enum":
839
880
  test_class_definition = process_template(
@@ -845,7 +886,8 @@ class AvroToCSharp:
845
886
  avro_annotation=self.avro_annotation,
846
887
  system_xml_annotation=self.system_xml_annotation,
847
888
  system_text_json_annotation=self.system_text_json_annotation,
848
- newtonsoft_json_annotation=self.newtonsoft_json_annotation
889
+ newtonsoft_json_annotation=self.newtonsoft_json_annotation,
890
+ protobuf_net_annotation=self.protobuf_net_annotation
849
891
  )
850
892
 
851
893
  test_file_path = os.path.join(test_directory_path, f"{test_class_name}.cs")
@@ -856,13 +898,14 @@ class AvroToCSharp:
856
898
  """ Retrieves fields for a given class name """
857
899
 
858
900
  class Field:
859
- def __init__(self, fn: str, ft:str, tv:Any, ct: bool, pm: bool, ie: bool):
901
+ def __init__(self, fn: str, ft:str, tv:Any, ct: bool, pm: bool, ie: bool, iu: bool):
860
902
  self.field_name = fn
861
903
  self.field_type = ft
862
904
  self.test_value = tv
863
905
  self.is_const = ct
864
906
  self.is_primitive = pm
865
907
  self.is_enum = ie
908
+ self.is_union = iu
866
909
 
867
910
  fields: List[Field] = []
868
911
  if avro_schema and 'fields' in avro_schema:
@@ -877,16 +920,19 @@ class AvroToCSharp:
877
920
  field_type = self.convert_avro_type_to_csharp(class_name, field_name, field['type'], str(avro_schema.get('namespace', '')))
878
921
  is_class = field_type in self.generated_types and self.generated_types[field_type] == "class"
879
922
  is_enum = self.is_enum_type(field['type'])
923
+ is_union = field_type in self.generated_types and self.generated_types[field_type] == "union"
924
+ test_value = self.get_test_value(field_type, field['type'], str(avro_schema.get('namespace', ''))) if not "const" in field else '\"'+str(field["const"])+'\"'
880
925
  f = Field(field_name,
881
926
  field_type,
882
- (self.get_test_value(field_type) if not "const" in field else '\"'+str(field["const"])+'\"'),
927
+ test_value,
883
928
  "const" in field and field["const"] is not None,
884
929
  not is_class,
885
- is_enum)
930
+ is_enum,
931
+ is_union)
886
932
  fields.append(f)
887
933
  return cast(List[Any], fields)
888
934
 
889
- def get_test_value(self, csharp_type: str) -> str:
935
+ def get_test_value(self, csharp_type: str, avro_type: JsonNode = None, parent_namespace: str = '') -> str:
890
936
  """Returns a default test value based on the Avro type"""
891
937
  # For nullable object types, return typed null to avoid var issues
892
938
  if csharp_type == "object?":
@@ -908,6 +954,19 @@ class AvroToCSharp:
908
954
  }
909
955
  if csharp_type.endswith('?'):
910
956
  csharp_type = csharp_type[:-1]
957
+
958
+ # Check if this is a union type (either by generated_types lookup or by type structure)
959
+ if csharp_type in self.generated_types and self.generated_types[csharp_type] == "union":
960
+ # For union types, we need to initialize with one of the valid options
961
+ # Find the first non-null type in the union and create a value for it
962
+ if isinstance(avro_type, list):
963
+ non_null_types = [t for t in avro_type if t != 'null']
964
+ if non_null_types:
965
+ first_option = non_null_types[0]
966
+ first_option_csharp = self.convert_avro_type_to_csharp('', 'Option0', first_option, parent_namespace)
967
+ first_option_value = self.get_test_value(first_option_csharp, first_option, parent_namespace)
968
+ return f'new {csharp_type}({first_option_value})'
969
+
911
970
  return test_values.get(csharp_type, f'new {csharp_type}()')
912
971
 
913
972
  def convert_schema(self, schema: JsonNode, output_dir: str):
@@ -967,10 +1026,14 @@ class AvroToCSharp:
967
1026
  system_xml_annotation=self.system_xml_annotation,
968
1027
  system_text_json_annotation=self.system_text_json_annotation,
969
1028
  newtonsoft_json_annotation=self.newtonsoft_json_annotation,
1029
+ protobuf_net_annotation=self.protobuf_net_annotation,
1030
+ msgpack_annotation=self.msgpack_annotation,
970
1031
  CSHARP_AVRO_VERSION=CSHARP_AVRO_VERSION,
971
1032
  NEWTONSOFT_JSON_VERSION=NEWTONSOFT_JSON_VERSION,
972
1033
  SYSTEM_TEXT_JSON_VERSION=SYSTEM_TEXT_JSON_VERSION,
973
1034
  SYSTEM_MEMORY_DATA_VERSION=SYSTEM_MEMORY_DATA_VERSION,
1035
+ PROTOBUF_NET_VERSION=PROTOBUF_NET_VERSION,
1036
+ MSGPACK_VERSION=MSGPACK_VERSION,
974
1037
  NUNIT_VERSION=NUNIT_VERSION,
975
1038
  NUNIT_ADAPTER_VERSION=NUNIT_ADAPTER_VERSION,
976
1039
  MSTEST_SDK_VERSION=MSTEST_SDK_VERSION))
@@ -988,9 +1051,39 @@ class AvroToCSharp:
988
1051
  system_xml_annotation=self.system_xml_annotation,
989
1052
  system_text_json_annotation=self.system_text_json_annotation,
990
1053
  newtonsoft_json_annotation=self.newtonsoft_json_annotation,
1054
+ protobuf_net_annotation=self.protobuf_net_annotation,
991
1055
  NUNIT_VERSION=NUNIT_VERSION,
992
1056
  NUNIT_ADAPTER_VERSION=NUNIT_ADAPTER_VERSION,
993
- MSTEST_SDK_VERSION=MSTEST_SDK_VERSION))
1057
+ MSTEST_SDK_VERSION=MSTEST_SDK_VERSION,
1058
+ COVERLET_VERSION=COVERLET_VERSION))
1059
+
1060
+ # Generate coverage scripts
1061
+ if not os.path.exists(os.path.join(output_dir, "run_coverage.ps1")):
1062
+ coverage_ps1_file = os.path.join(output_dir, "run_coverage.ps1")
1063
+ with open(coverage_ps1_file, 'w', encoding='utf-8') as file:
1064
+ file.write(process_template(
1065
+ "avrotocsharp/run_coverage.ps1.jinja",
1066
+ project_name=project_name))
1067
+
1068
+ if not os.path.exists(os.path.join(output_dir, "run_coverage.sh")):
1069
+ coverage_sh_file = os.path.join(output_dir, "run_coverage.sh")
1070
+ with open(coverage_sh_file, 'w', encoding='utf-8') as file:
1071
+ file.write(process_template(
1072
+ "avrotocsharp/run_coverage.sh.jinja",
1073
+ project_name=project_name))
1074
+ # Make the shell script executable on Unix-like systems
1075
+ try:
1076
+ os.chmod(coverage_sh_file, 0o755)
1077
+ except:
1078
+ pass # Ignore on Windows
1079
+
1080
+ # Generate README with coverage documentation
1081
+ if not os.path.exists(os.path.join(output_dir, "README.md")):
1082
+ readme_file = os.path.join(output_dir, "README.md")
1083
+ with open(readme_file, 'w', encoding='utf-8') as file:
1084
+ file.write(process_template(
1085
+ "avrotocsharp/README.md.jinja",
1086
+ project_name=project_name))
994
1087
 
995
1088
  self.output_dir = output_dir
996
1089
  for avro_schema in (avs for avs in schema if isinstance(avs, dict)):
@@ -1012,8 +1105,10 @@ def convert_avro_to_csharp(
1012
1105
  pascal_properties=False,
1013
1106
  system_text_json_annotation=False,
1014
1107
  newtonsoft_json_annotation=False,
1015
- system_xml_annotation=False, # New parameter
1016
- avro_annotation=False
1108
+ system_xml_annotation=False,
1109
+ msgpack_annotation=False,
1110
+ avro_annotation=False,
1111
+ protobuf_net_annotation=False
1017
1112
  ):
1018
1113
  """Converts Avro schema to C# classes
1019
1114
 
@@ -1026,7 +1121,9 @@ def convert_avro_to_csharp(
1026
1121
  system_text_json_annotation (bool, optional): Use System.Text.Json annotations. Defaults to False.
1027
1122
  newtonsoft_json_annotation (bool, optional): Use Newtonsoft.Json annotations. Defaults to False.
1028
1123
  system_xml_annotation (bool, optional): Use System.Xml.Serialization annotations. Defaults to False.
1124
+ msgpack_annotation (bool, optional): Use MessagePack annotations. Defaults to False.
1029
1125
  avro_annotation (bool, optional): Use Avro annotations. Defaults to False.
1126
+ protobuf_net_annotation (bool, optional): Use protobuf-net annotations. Defaults to False.
1030
1127
  """
1031
1128
 
1032
1129
  if not base_namespace:
@@ -1036,8 +1133,10 @@ def convert_avro_to_csharp(
1036
1133
  avrotocs.pascal_properties = pascal_properties
1037
1134
  avrotocs.system_text_json_annotation = system_text_json_annotation
1038
1135
  avrotocs.newtonsoft_json_annotation = newtonsoft_json_annotation
1039
- avrotocs.system_xml_annotation = system_xml_annotation # Set the flag
1136
+ avrotocs.system_xml_annotation = system_xml_annotation
1137
+ avrotocs.msgpack_annotation = msgpack_annotation
1040
1138
  avrotocs.avro_annotation = avro_annotation
1139
+ avrotocs.protobuf_net_annotation = protobuf_net_annotation
1041
1140
  avrotocs.convert(avro_schema_path, cs_file_path)
1042
1141
 
1043
1142
 
@@ -1049,8 +1148,10 @@ def convert_avro_schema_to_csharp(
1049
1148
  pascal_properties: bool = False,
1050
1149
  system_text_json_annotation: bool = False,
1051
1150
  newtonsoft_json_annotation: bool = False,
1052
- system_xml_annotation: bool = False, # New parameter
1053
- avro_annotation: bool = False
1151
+ system_xml_annotation: bool = False,
1152
+ msgpack_annotation: bool = False,
1153
+ avro_annotation: bool = False,
1154
+ protobuf_net_annotation: bool = False
1054
1155
  ):
1055
1156
  """Converts Avro schema to C# classes
1056
1157
 
@@ -1063,13 +1164,17 @@ def convert_avro_schema_to_csharp(
1063
1164
  system_text_json_annotation (bool, optional): Use System.Text.Json annotations. Defaults to False.
1064
1165
  newtonsoft_json_annotation (bool, optional): Use Newtonsoft.Json annotations. Defaults to False.
1065
1166
  system_xml_annotation (bool, optional): Use System.Xml.Serialization annotations. Defaults to False.
1167
+ msgpack_annotation (bool, optional): Use MessagePack annotations. Defaults to False.
1066
1168
  avro_annotation (bool, optional): Use Avro annotations. Defaults to False.
1169
+ protobuf_net_annotation (bool, optional): Use protobuf-net annotations. Defaults to False.
1067
1170
  """
1068
1171
  avrotocs = AvroToCSharp(base_namespace)
1069
1172
  avrotocs.project_name = project_name
1070
1173
  avrotocs.pascal_properties = pascal_properties
1071
1174
  avrotocs.system_text_json_annotation = system_text_json_annotation
1072
1175
  avrotocs.newtonsoft_json_annotation = newtonsoft_json_annotation
1073
- avrotocs.system_xml_annotation = system_xml_annotation # Set the flag
1176
+ avrotocs.system_xml_annotation = system_xml_annotation
1177
+ avrotocs.msgpack_annotation = msgpack_annotation
1074
1178
  avrotocs.avro_annotation = avro_annotation
1179
+ avrotocs.protobuf_net_annotation = protobuf_net_annotation
1075
1180
  avrotocs.convert_schema(avro_schema, output_dir)