gitronics 0.6.0__tar.gz → 0.6.1__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.
- {gitronics-0.6.0 → gitronics-0.6.1}/.github/workflows/ci.yml +19 -1
- {gitronics-0.6.0 → gitronics-0.6.1}/Cargo.lock +1 -1
- {gitronics-0.6.0 → gitronics-0.6.1}/Cargo.toml +1 -1
- {gitronics-0.6.0 → gitronics-0.6.1}/PKG-INFO +1 -1
- {gitronics-0.6.0 → gitronics-0.6.1}/python/tests/test_cli_works.py +6 -2
- {gitronics-0.6.0 → gitronics-0.6.1}/src/project_manager/load_project_files.rs +5 -2
- {gitronics-0.6.0 → gitronics-0.6.1}/src/utils.rs +77 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/.github/workflows/docs.yml +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/.github/workflows/release.yml +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/.gitignore +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/.vscode/settings.json +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/LICENSE +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/README.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/assets/logo.png +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/best_practices.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/examples.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/getting_started/assessments.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/getting_started/building_a_model.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/getting_started/card_id_numbers.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/getting_started/concepts.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/getting_started/configuration_file.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/getting_started/file_types.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/getting_started/migrating.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/getting_started/new_project.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/getting_started/project_structure.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/getting_started.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/hooks/version_from_git.py +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/index.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/installation.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/requirements.txt +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/usage/build.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/docs/usage/migrate.md +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/assessment_specific/filler_model_3.mcnp +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/assessment_specific/filler_model_3.metadata +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/assessment_specific/small_override.yaml +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/configurations/valid_configuration.yaml +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/output/.gitignore +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/data_cards/fine_mesh.tally +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/data_cards/materials.mat +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/data_cards/my_transform.transform +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/data_cards/volumetric_source.source +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/envelope_structure.mcnp +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/envelope_structure.metadata +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/filler_models/filler_model_1.mcnp +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/filler_models/filler_model_1.metadata +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/filler_models/filler_model_2.mcnp +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/filler_models/filler_model_2.metadata +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/mkdocs.yml +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/pyproject.toml +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/python/gitronics/__init__.py +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/python/gitronics/__main__.py +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/python/gitronics/gitronics.pyi +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/python/tests/test_build_model.py +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/resources/simple_model.mcnp +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/build_model.rs +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/build_report.rs +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/cli.rs +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/lib.rs +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/main.rs +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/migrate_model.rs +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/model_config.rs +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/project_manager/load_metadata.rs +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/project_manager/load_model_config.rs +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/project_manager.rs +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/python.rs +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/report.css +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/src/types.rs +0 -0
- {gitronics-0.6.0 → gitronics-0.6.1}/tests/test_example_project.rs +0 -0
|
@@ -22,7 +22,7 @@ jobs:
|
|
|
22
22
|
- name: Install Rust stable
|
|
23
23
|
uses: dtolnay/rust-toolchain@stable
|
|
24
24
|
with:
|
|
25
|
-
components: clippy
|
|
25
|
+
components: clippy, rustfmt
|
|
26
26
|
|
|
27
27
|
- name: Set up Python (Required for PyO3 test linking)
|
|
28
28
|
id: setup-python
|
|
@@ -49,12 +49,30 @@ jobs:
|
|
|
49
49
|
target
|
|
50
50
|
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
51
51
|
|
|
52
|
+
- name: rustfmt
|
|
53
|
+
run: cargo fmt --all --check
|
|
54
|
+
|
|
52
55
|
- name: Test
|
|
53
56
|
run: cargo test --workspace --features pyo3/auto-initialize
|
|
54
57
|
|
|
55
58
|
- name: Clippy
|
|
56
59
|
run: cargo clippy --workspace -- -D warnings
|
|
57
60
|
|
|
61
|
+
ruff:
|
|
62
|
+
name: Python lint (ruff)
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
steps:
|
|
65
|
+
- uses: actions/checkout@v4
|
|
66
|
+
|
|
67
|
+
- uses: astral-sh/setup-uv@v5
|
|
68
|
+
|
|
69
|
+
# Pinned so a new ruff release can't fail CI unexpectedly; bump deliberately.
|
|
70
|
+
- name: ruff lint
|
|
71
|
+
run: uvx ruff@0.15.21 check python
|
|
72
|
+
|
|
73
|
+
- name: ruff format
|
|
74
|
+
run: uvx ruff@0.15.21 format --check python
|
|
75
|
+
|
|
58
76
|
python:
|
|
59
77
|
name: Python tests (${{ matrix.os }})
|
|
60
78
|
runs-on: ${{ matrix.os }}
|
|
@@ -6,8 +6,12 @@ def test_cli_works():
|
|
|
6
6
|
# Run in a subprocess so clap's process::exit(0) on --help doesn't kill pytest.
|
|
7
7
|
# Actual behaviour is covered by the Rust unit tests.
|
|
8
8
|
result = subprocess.run(
|
|
9
|
-
[
|
|
9
|
+
[
|
|
10
|
+
sys.executable,
|
|
11
|
+
"-c",
|
|
12
|
+
"from gitronics import _cli_main; _cli_main()",
|
|
13
|
+
"--help",
|
|
14
|
+
],
|
|
10
15
|
capture_output=True,
|
|
11
16
|
)
|
|
12
17
|
assert result.returncode == 0
|
|
13
|
-
|
|
@@ -10,7 +10,7 @@ use migjorn::Model;
|
|
|
10
10
|
use rayon::prelude::*;
|
|
11
11
|
|
|
12
12
|
use crate::types::{FileName, FillerName};
|
|
13
|
-
use crate::utils::{GitronicsError, parse_model_file, read_data_cards_text};
|
|
13
|
+
use crate::utils::{GitronicsError, parse_model_file, read_data_cards_text, sort_data_card_chunks};
|
|
14
14
|
|
|
15
15
|
use super::ProjectManager;
|
|
16
16
|
|
|
@@ -91,7 +91,9 @@ impl ProjectManager {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
/// Concatenates the data-card text of every file in `names`, one blank-line
|
|
94
|
-
/// separated block per file
|
|
94
|
+
/// separated block per file. Blocks are ordered by the id of each file's
|
|
95
|
+
/// first data card (deterministic output, independent of configuration
|
|
96
|
+
/// order); cards inside a file keep their original order.
|
|
95
97
|
fn load_data_cards_text(&self, names: &[FileName]) -> Result<String, GitronicsError> {
|
|
96
98
|
let mut chunks = Vec::new();
|
|
97
99
|
for name in names {
|
|
@@ -99,6 +101,7 @@ impl ProjectManager {
|
|
|
99
101
|
info!("Loading: {}", path.display());
|
|
100
102
|
chunks.push(read_data_cards_text(path, name)?);
|
|
101
103
|
}
|
|
104
|
+
sort_data_card_chunks(&mut chunks);
|
|
102
105
|
Ok(chunks.join("\n"))
|
|
103
106
|
}
|
|
104
107
|
}
|
|
@@ -158,6 +158,54 @@ pub fn read_data_cards_text(path: &Path, file_name: &FileName) -> Result<String,
|
|
|
158
158
|
Ok(kept.join("\n"))
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
/// Sort key mirroring a data card's id: cards whose mnemonic ends in a number
|
|
162
|
+
/// (`M1`, `F4`, `TR1`) order by that number and come first; mnemonics without a
|
|
163
|
+
/// trailing number (`SDEF`, `MODE`) fall back to alphabetical order and come
|
|
164
|
+
/// last — matching the old `DataCardId::{Int, String}` ordering.
|
|
165
|
+
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
|
166
|
+
enum DataCardKey {
|
|
167
|
+
Int(u32),
|
|
168
|
+
Str(String),
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/// The sort key of a data-card file block, derived from the id of its first
|
|
172
|
+
/// data card. Full-line comments (and blank lines) are skipped so a comment
|
|
173
|
+
/// header does not decide the order.
|
|
174
|
+
fn first_data_card_key(chunk: &str) -> DataCardKey {
|
|
175
|
+
for line in chunk.lines() {
|
|
176
|
+
if is_mcnp_comment(line) {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
// First whitespace token is the mnemonic, minus any leading `*`.
|
|
180
|
+
let mnemonic = line
|
|
181
|
+
.trim_start()
|
|
182
|
+
.split_whitespace()
|
|
183
|
+
.next()
|
|
184
|
+
.unwrap_or("")
|
|
185
|
+
.trim_start_matches('*');
|
|
186
|
+
// Split the trailing id number off the mnemonic letters (`TR1` -> 1,
|
|
187
|
+
// `F4:N` -> 4).
|
|
188
|
+
let digits: String = mnemonic
|
|
189
|
+
.chars()
|
|
190
|
+
.skip_while(|c| !c.is_ascii_digit())
|
|
191
|
+
.take_while(|c| c.is_ascii_digit())
|
|
192
|
+
.collect();
|
|
193
|
+
return match digits.parse::<u32>() {
|
|
194
|
+
Ok(id) => DataCardKey::Int(id),
|
|
195
|
+
Err(_) => DataCardKey::Str(mnemonic.to_ascii_uppercase()),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
DataCardKey::Str(String::new())
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/// Order data-card file blocks by the id of each block's first data card,
|
|
202
|
+
/// keeping the cards inside a block in their original order (a stable sort over
|
|
203
|
+
/// whole blocks). Restores the deterministic output the pre-migjorn-0.2 build
|
|
204
|
+
/// produced via `order_data_cards_groups_by_id`.
|
|
205
|
+
pub fn sort_data_card_chunks(chunks: &mut [String]) {
|
|
206
|
+
chunks.sort_by_key(|chunk| first_data_card_key(chunk));
|
|
207
|
+
}
|
|
208
|
+
|
|
161
209
|
/// True if `line` is an MCNP full-line comment (first non-blank character is
|
|
162
210
|
/// `c`/`C`, followed by whitespace or end of line) or blank.
|
|
163
211
|
fn is_mcnp_comment(line: &str) -> bool {
|
|
@@ -282,6 +330,35 @@ mod tests {
|
|
|
282
330
|
assert!(err.to_string().contains("Duplicate file name `file1`"));
|
|
283
331
|
}
|
|
284
332
|
|
|
333
|
+
#[test]
|
|
334
|
+
fn test_sort_data_card_chunks_by_first_card_id() {
|
|
335
|
+
// Blocks arrive in arbitrary configuration order.
|
|
336
|
+
let mut chunks = vec![
|
|
337
|
+
"m10 1001 1\nm2 8016 1".to_string(), // first card M10 -> 10
|
|
338
|
+
"C header\nm1 6000 1".to_string(), // comment skipped, M1 -> 1
|
|
339
|
+
"sdef pos=0 0 0".to_string(), // no id -> sorts last
|
|
340
|
+
"m3 26000 1".to_string(), // M3 -> 3
|
|
341
|
+
];
|
|
342
|
+
sort_data_card_chunks(&mut chunks);
|
|
343
|
+
assert_eq!(
|
|
344
|
+
chunks,
|
|
345
|
+
vec![
|
|
346
|
+
"C header\nm1 6000 1".to_string(),
|
|
347
|
+
"m3 26000 1".to_string(),
|
|
348
|
+
"m10 1001 1\nm2 8016 1".to_string(),
|
|
349
|
+
"sdef pos=0 0 0".to_string(),
|
|
350
|
+
]
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
#[test]
|
|
355
|
+
fn test_sort_data_card_chunks_is_stable_within_block() {
|
|
356
|
+
// Cards inside a block are never reordered, even if not id-sorted.
|
|
357
|
+
let mut chunks = vec!["m5 1001 1\nm2 8016 1".to_string()];
|
|
358
|
+
sort_data_card_chunks(&mut chunks);
|
|
359
|
+
assert_eq!(chunks, vec!["m5 1001 1\nm2 8016 1".to_string()]);
|
|
360
|
+
}
|
|
361
|
+
|
|
285
362
|
#[test]
|
|
286
363
|
fn test_io_path_normalizes_parent_segments_when_not_canonicalizable() {
|
|
287
364
|
let err = GitronicsError::io_path(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gitronics-0.6.0 → gitronics-0.6.1}/example_project/assessment_specific/filler_model_3.metadata
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/data_cards/fine_mesh.tally
RENAMED
|
File without changes
|
{gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/data_cards/materials.mat
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gitronics-0.6.0 → gitronics-0.6.1}/example_project/reference_model/envelope_structure.metadata
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|