@@ -1933,41 +1933,46 @@ test "install: all systemctl calls route through helpers" {
19331933 const testing = std .testing ;
19341934 const allocator = testing .allocator ;
19351935
1936- // Read our own source to verify every systemctl invocation goes through
1937- // a named helper. runSystemctlUser covers user-scope (daemon-reload,
1938- // enable, start for the per- user unit) ; runSystemctlSystem covers
1939- // system-scope (legacy unit stop/disable during migration) .
1936+ // Scan production modules (not this test file) to verify every systemctl
1937+ // invocation goes through a named helper. runSystemctlUser covers
1938+ // user-scope ; runSystemctlSystem covers system-scope (migration).
1939+ // These live in the same directory as this file after the install/ split .
19401940 const src_path = @src ().file ;
1941- var file = if (std .fs .path .isAbsolute (src_path ))
1942- std .fs .openFileAbsolute (src_path , .{}) catch return
1943- else
1944- std .fs .cwd ().openFile (src_path , .{}) catch return ;
1945- defer file .close ();
1946- const src = try file .readToEndAlloc (allocator , 1 << 20 );
1947- defer allocator .free (src );
1941+ const src_dir = std .fs .path .dirname (src_path ) orelse "." ;
1942+ const prod_files = [_ ][]const u8 { "services.zig" , "phase.zig" , "migration.zig" };
19481943
1949- var iter = std .mem .splitScalar (u8 , src , '\n ' );
19501944 var helper_calls : usize = 0 ;
1951- while (iter .next ()) | line | {
1952- // Ignore the test itself (which mentions these names in strings).
1953- if (std .mem .indexOf (u8 , line , "test \" install: all systemctl" ) != null ) continue ;
1954- // Skip pure comment lines — a code comment that quotes the
1955- // forbidden pattern as a documentation example shouldn't trip it.
1956- const trimmed = std .mem .trimLeft (u8 , line , " \t " );
1957- if (std .mem .startsWith (u8 , trimmed , "//" )) continue ;
1958-
1959- if (std .mem .indexOf (u8 , line , "runSystemctlUser" ) != null ) helper_calls += 1 ;
1960-
1961- // No raw generic-runCmd + systemctl literal on the same line outside
1962- // the helpers; see runSystemctlUser / runSystemctlSystem above.
1963- const has_runcmd = std .mem .indexOf (u8 , line , "runCmd(&.{" ) != null ;
1964- const has_systemctl_literal = std .mem .indexOf (u8 , line , "\" systemctl\" " ) != null ;
1965- if (has_runcmd and has_systemctl_literal ) {
1966- try testing .expect (false );
1945+ for (prod_files ) | name | {
1946+ const full = try std .fs .path .join (allocator , &.{ src_dir , name });
1947+ defer allocator .free (full );
1948+ var file = if (std .fs .path .isAbsolute (full ))
1949+ std .fs .openFileAbsolute (full , .{}) catch continue
1950+ else
1951+ std .fs .cwd ().openFile (full , .{}) catch continue ;
1952+ defer file .close ();
1953+ const src = try file .readToEndAlloc (allocator , 1 << 20 );
1954+ defer allocator .free (src );
1955+
1956+ var iter = std .mem .splitScalar (u8 , src , '\n ' );
1957+ while (iter .next ()) | line | {
1958+ const trimmed = std .mem .trimLeft (u8 , line , " \t " );
1959+ if (std .mem .startsWith (u8 , trimmed , "//" )) continue ;
1960+
1961+ if (std .mem .indexOf (u8 , line , "runSystemctlUser" ) != null or
1962+ std .mem .indexOf (u8 , line , "runSystemctlSystem" ) != null )
1963+ {
1964+ helper_calls += 1 ;
1965+ }
1966+
1967+ // No raw runCmd(&.{ ... }) with a "systemctl" literal on the same
1968+ // line — all systemctl calls must go through the named helpers.
1969+ const has_runcmd = std .mem .indexOf (u8 , line , "runCmd(&.{" ) != null ;
1970+ const has_systemctl_literal = std .mem .indexOf (u8 , line , "\" systemctl\" " ) != null ;
1971+ if (has_runcmd and has_systemctl_literal ) {
1972+ try testing .expect (false );
1973+ }
19671974 }
19681975 }
1969- // Each of the 5+ call sites is one source line referencing a helper,
1970- // plus the helper fn definitions and at least one internal call.
19711976 try testing .expect (helper_calls >= 5 );
19721977}
19731978
0 commit comments