sentry-options 0.0.5__tar.gz → 0.0.6__tar.gz

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.
@@ -31,6 +31,15 @@ version = "0.2.21"
31
31
  source = "registry+https://github.com/rust-lang/crates.io-index"
32
32
  checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
33
33
 
34
+ [[package]]
35
+ name = "android_system_properties"
36
+ version = "0.1.5"
37
+ source = "registry+https://github.com/rust-lang/crates.io-index"
38
+ checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
39
+ dependencies = [
40
+ "libc",
41
+ ]
42
+
34
43
  [[package]]
35
44
  name = "anstream"
36
45
  version = "0.6.21"
@@ -150,12 +159,33 @@ version = "1.11.0"
150
159
  source = "registry+https://github.com/rust-lang/crates.io-index"
151
160
  checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
152
161
 
162
+ [[package]]
163
+ name = "cc"
164
+ version = "1.2.52"
165
+ source = "registry+https://github.com/rust-lang/crates.io-index"
166
+ checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3"
167
+ dependencies = [
168
+ "find-msvc-tools",
169
+ "shlex",
170
+ ]
171
+
153
172
  [[package]]
154
173
  name = "cfg-if"
155
174
  version = "1.0.4"
156
175
  source = "registry+https://github.com/rust-lang/crates.io-index"
157
176
  checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
158
177
 
178
+ [[package]]
179
+ name = "chrono"
180
+ version = "0.4.43"
181
+ source = "registry+https://github.com/rust-lang/crates.io-index"
182
+ checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118"
183
+ dependencies = [
184
+ "iana-time-zone",
185
+ "num-traits",
186
+ "windows-link",
187
+ ]
188
+
159
189
  [[package]]
160
190
  name = "clap"
161
191
  version = "4.5.53"
@@ -202,6 +232,12 @@ version = "1.0.4"
202
232
  source = "registry+https://github.com/rust-lang/crates.io-index"
203
233
  checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
204
234
 
235
+ [[package]]
236
+ name = "core-foundation-sys"
237
+ version = "0.8.7"
238
+ source = "registry+https://github.com/rust-lang/crates.io-index"
239
+ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
240
+
205
241
  [[package]]
206
242
  name = "displaydoc"
207
243
  version = "0.2.5"
@@ -240,7 +276,7 @@ dependencies = [
240
276
 
241
277
  [[package]]
242
278
  name = "example"
243
- version = "0.0.5"
279
+ version = "0.0.6"
244
280
  dependencies = [
245
281
  "anyhow",
246
282
  "sentry-options",
@@ -264,6 +300,12 @@ version = "2.3.0"
264
300
  source = "registry+https://github.com/rust-lang/crates.io-index"
265
301
  checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
266
302
 
303
+ [[package]]
304
+ name = "find-msvc-tools"
305
+ version = "0.1.7"
306
+ source = "registry+https://github.com/rust-lang/crates.io-index"
307
+ checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41"
308
+
267
309
  [[package]]
268
310
  name = "fluent-uri"
269
311
  version = "0.4.1"
@@ -472,6 +514,30 @@ dependencies = [
472
514
  "tracing",
473
515
  ]
474
516
 
517
+ [[package]]
518
+ name = "iana-time-zone"
519
+ version = "0.1.64"
520
+ source = "registry+https://github.com/rust-lang/crates.io-index"
521
+ checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
522
+ dependencies = [
523
+ "android_system_properties",
524
+ "core-foundation-sys",
525
+ "iana-time-zone-haiku",
526
+ "js-sys",
527
+ "log",
528
+ "wasm-bindgen",
529
+ "windows-core",
530
+ ]
531
+
532
+ [[package]]
533
+ name = "iana-time-zone-haiku"
534
+ version = "0.1.2"
535
+ source = "registry+https://github.com/rust-lang/crates.io-index"
536
+ checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
537
+ dependencies = [
538
+ "cc",
539
+ ]
540
+
475
541
  [[package]]
476
542
  name = "icu_collections"
477
543
  version = "2.1.1"
@@ -1111,7 +1177,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
1111
1177
 
1112
1178
  [[package]]
1113
1179
  name = "sentry-options"
1114
- version = "0.0.5"
1180
+ version = "0.0.6"
1115
1181
  dependencies = [
1116
1182
  "sentry-options-validation",
1117
1183
  "serde_json",
@@ -1121,8 +1187,9 @@ dependencies = [
1121
1187
 
1122
1188
  [[package]]
1123
1189
  name = "sentry-options-cli"
1124
- version = "0.0.5"
1190
+ version = "0.0.6"
1125
1191
  dependencies = [
1192
+ "chrono",
1126
1193
  "clap",
1127
1194
  "sentry-options-validation",
1128
1195
  "serde",
@@ -1135,7 +1202,7 @@ dependencies = [
1135
1202
 
1136
1203
  [[package]]
1137
1204
  name = "sentry-options-python"
1138
- version = "0.0.5"
1205
+ version = "0.0.6"
1139
1206
  dependencies = [
1140
1207
  "pyo3",
1141
1208
  "sentry-options",
@@ -1144,7 +1211,7 @@ dependencies = [
1144
1211
 
1145
1212
  [[package]]
1146
1213
  name = "sentry-options-validation"
1147
- version = "0.0.5"
1214
+ version = "0.0.6"
1148
1215
  dependencies = [
1149
1216
  "anyhow",
1150
1217
  "jsonschema",
@@ -1222,6 +1289,12 @@ dependencies = [
1222
1289
  "unsafe-libyaml",
1223
1290
  ]
1224
1291
 
1292
+ [[package]]
1293
+ name = "shlex"
1294
+ version = "1.3.0"
1295
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1296
+ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
1297
+
1225
1298
  [[package]]
1226
1299
  name = "slab"
1227
1300
  version = "0.4.11"
@@ -1600,12 +1673,65 @@ dependencies = [
1600
1673
  "windows-sys 0.61.2",
1601
1674
  ]
1602
1675
 
1676
+ [[package]]
1677
+ name = "windows-core"
1678
+ version = "0.62.2"
1679
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1680
+ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
1681
+ dependencies = [
1682
+ "windows-implement",
1683
+ "windows-interface",
1684
+ "windows-link",
1685
+ "windows-result",
1686
+ "windows-strings",
1687
+ ]
1688
+
1689
+ [[package]]
1690
+ name = "windows-implement"
1691
+ version = "0.60.2"
1692
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1693
+ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
1694
+ dependencies = [
1695
+ "proc-macro2",
1696
+ "quote",
1697
+ "syn",
1698
+ ]
1699
+
1700
+ [[package]]
1701
+ name = "windows-interface"
1702
+ version = "0.59.3"
1703
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1704
+ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
1705
+ dependencies = [
1706
+ "proc-macro2",
1707
+ "quote",
1708
+ "syn",
1709
+ ]
1710
+
1603
1711
  [[package]]
1604
1712
  name = "windows-link"
1605
1713
  version = "0.2.1"
1606
1714
  source = "registry+https://github.com/rust-lang/crates.io-index"
1607
1715
  checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
1608
1716
 
1717
+ [[package]]
1718
+ name = "windows-result"
1719
+ version = "0.4.1"
1720
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1721
+ checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
1722
+ dependencies = [
1723
+ "windows-link",
1724
+ ]
1725
+
1726
+ [[package]]
1727
+ name = "windows-strings"
1728
+ version = "0.5.1"
1729
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1730
+ checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
1731
+ dependencies = [
1732
+ "windows-link",
1733
+ ]
1734
+
1609
1735
  [[package]]
1610
1736
  name = "windows-sys"
1611
1737
  version = "0.60.2"
@@ -11,13 +11,13 @@ default-members = [
11
11
  ]
12
12
 
13
13
  [workspace.package]
14
- version = "0.0.5"
14
+ version = "0.0.6"
15
15
  edition = "2024"
16
16
  repository = "https://github.com/getsentry/sentry-options"
17
17
  license = "Apache-2.0"
18
18
 
19
19
  [workspace.dependencies]
20
- sentry-options-validation = { path = "sentry-options-validation", version = "0.0.5" }
20
+ sentry-options-validation = { path = "sentry-options-validation", version = "0.0.6" }
21
21
  serde = { version = "1.0", features = ["derive"] }
22
22
  serde_json = "1.0.145"
23
23
  anyhow = "1.0.100"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_options
3
- Version: 0.0.5
3
+ Version: 0.0.6
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3 :: Only
6
6
  Classifier: Programming Language :: Python :: Implementation :: CPython
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "sentry_options"
7
- version = "0.0.5"
7
+ version = "0.0.6"
8
8
  description = "Python client for sentry-options using Rust validation"
9
9
  license = "Apache-2.0"
10
10
  requires-python = ">=3.11"
@@ -81,6 +81,40 @@ pub enum ValidationError {
81
81
 
82
82
  #[error("{} validation error(s)", .0.len())]
83
83
  ValidationErrors(Vec<ValidationError>),
84
+
85
+ #[error("Invalid {label} '{name}': {reason}")]
86
+ InvalidName {
87
+ label: String,
88
+ name: String,
89
+ reason: String,
90
+ },
91
+ }
92
+
93
+ /// Validate a name component is valid for K8s (lowercase alphanumeric, '-', '.')
94
+ pub fn validate_k8s_name_component(name: &str, label: &str) -> ValidationResult<()> {
95
+ if let Some(c) = name
96
+ .chars()
97
+ .find(|&c| !matches!(c, 'a'..='z' | '0'..='9' | '-' | '.'))
98
+ {
99
+ return Err(ValidationError::InvalidName {
100
+ label: label.to_string(),
101
+ name: name.to_string(),
102
+ reason: format!(
103
+ "character '{}' not allowed. Use lowercase alphanumeric, '-', or '.'",
104
+ c
105
+ ),
106
+ });
107
+ }
108
+ if !name.starts_with(|c: char| c.is_ascii_alphanumeric())
109
+ || !name.ends_with(|c: char| c.is_ascii_alphanumeric())
110
+ {
111
+ return Err(ValidationError::InvalidName {
112
+ label: label.to_string(),
113
+ name: name.to_string(),
114
+ reason: "must start and end with alphanumeric".to_string(),
115
+ });
116
+ }
117
+ Ok(())
84
118
  }
85
119
 
86
120
  /// Metadata for a single option in a namespace schema
@@ -202,6 +236,8 @@ impl SchemaRegistry {
202
236
  message: "Directory name contains invalid UTF-8".to_string(),
203
237
  })?;
204
238
 
239
+ validate_k8s_name_component(&namespace, "namespace name")?;
240
+
205
241
  let schema_file = entry.path().join(SCHEMA_FILE_NAME);
206
242
  let schema = Self::load_schema(&schema_file, &namespace, &namespace_validator)?;
207
243
  schemas.insert(namespace, schema);
@@ -535,6 +571,52 @@ mod tests {
535
571
  schema_file
536
572
  }
537
573
 
574
+ #[test]
575
+ fn test_validate_k8s_name_component_valid() {
576
+ assert!(validate_k8s_name_component("relay", "namespace").is_ok());
577
+ assert!(validate_k8s_name_component("my-service", "namespace").is_ok());
578
+ assert!(validate_k8s_name_component("my.service", "namespace").is_ok());
579
+ assert!(validate_k8s_name_component("a1-b2.c3", "namespace").is_ok());
580
+ }
581
+
582
+ #[test]
583
+ fn test_validate_k8s_name_component_rejects_uppercase() {
584
+ let result = validate_k8s_name_component("MyService", "namespace");
585
+ assert!(matches!(result, Err(ValidationError::InvalidName { .. })));
586
+ assert!(result.unwrap_err().to_string().contains("'M' not allowed"));
587
+ }
588
+
589
+ #[test]
590
+ fn test_validate_k8s_name_component_rejects_underscore() {
591
+ let result = validate_k8s_name_component("my_service", "target");
592
+ assert!(matches!(result, Err(ValidationError::InvalidName { .. })));
593
+ assert!(result.unwrap_err().to_string().contains("'_' not allowed"));
594
+ }
595
+
596
+ #[test]
597
+ fn test_validate_k8s_name_component_rejects_leading_hyphen() {
598
+ let result = validate_k8s_name_component("-service", "namespace");
599
+ assert!(matches!(result, Err(ValidationError::InvalidName { .. })));
600
+ assert!(
601
+ result
602
+ .unwrap_err()
603
+ .to_string()
604
+ .contains("start and end with alphanumeric")
605
+ );
606
+ }
607
+
608
+ #[test]
609
+ fn test_validate_k8s_name_component_rejects_trailing_dot() {
610
+ let result = validate_k8s_name_component("service.", "namespace");
611
+ assert!(matches!(result, Err(ValidationError::InvalidName { .. })));
612
+ assert!(
613
+ result
614
+ .unwrap_err()
615
+ .to_string()
616
+ .contains("start and end with alphanumeric")
617
+ );
618
+ }
619
+
538
620
  #[test]
539
621
  fn test_load_schema_valid() {
540
622
  let temp_dir = TempDir::new().unwrap();
@@ -724,7 +806,7 @@ Error: \"version\" is a required property"
724
806
  fn test_invalid_directory_structure() {
725
807
  let temp_dir = TempDir::new().unwrap();
726
808
  // Create a namespace directory without schema.json file
727
- let schema_dir = temp_dir.path().join("missing_schema");
809
+ let schema_dir = temp_dir.path().join("missing-schema");
728
810
  fs::create_dir_all(&schema_dir).unwrap();
729
811
 
730
812
  let result = SchemaRegistry::from_directory(temp_dir.path());
@@ -940,7 +1022,7 @@ Error: \"version\" is a required property"
940
1022
  let values_dir = temp_dir.path().join("values");
941
1023
 
942
1024
  // Create two schemas
943
- let schema_dir1 = schemas_dir.join("with_values");
1025
+ let schema_dir1 = schemas_dir.join("with-values");
944
1026
  fs::create_dir_all(&schema_dir1).unwrap();
945
1027
  fs::write(
946
1028
  schema_dir1.join("schema.json"),
@@ -954,7 +1036,7 @@ Error: \"version\" is a required property"
954
1036
  )
955
1037
  .unwrap();
956
1038
 
957
- let schema_dir2 = schemas_dir.join("without_values");
1039
+ let schema_dir2 = schemas_dir.join("without-values");
958
1040
  fs::create_dir_all(&schema_dir2).unwrap();
959
1041
  fs::write(
960
1042
  schema_dir2.join("schema.json"),
@@ -969,7 +1051,7 @@ Error: \"version\" is a required property"
969
1051
  .unwrap();
970
1052
 
971
1053
  // Only create values for one namespace
972
- let with_values_dir = values_dir.join("with_values");
1054
+ let with_values_dir = values_dir.join("with-values");
973
1055
  fs::create_dir_all(&with_values_dir).unwrap();
974
1056
  fs::write(with_values_dir.join("values.json"), r#"{"opt": "y"}"#).unwrap();
975
1057
 
@@ -977,8 +1059,8 @@ Error: \"version\" is a required property"
977
1059
  let values = registry.load_values_json(&values_dir).unwrap();
978
1060
 
979
1061
  assert_eq!(values.len(), 1);
980
- assert!(values.contains_key("with_values"));
981
- assert!(!values.contains_key("without_values"));
1062
+ assert!(values.contains_key("with-values"));
1063
+ assert!(!values.contains_key("without-values"));
982
1064
  }
983
1065
 
984
1066
  #[test]