class Detector::CSharp::Cli

Overview

Detects C# command-line applications: programs using a CLI library (System.CommandLine, CommandLineParser, CliFx, Spectre.Console.Cli, McMaster.Extensions.CommandLineUtils, Cocona) or a static Main(string[] args) / GetCommandLineArgs entry point. Gates the C# CLI analyzer. A web host (ASP.NET / HttpListener) suppresses the builtin signals so a server's Main/env reads don't masquerade as a CLI.

Defined in:

detector/detectors/csharp/cli.cr

Constant Summary

CLI_LIB = /\busing\s+(?:System\.CommandLine|CommandLine|CliFx|Spectre\.Console\.Cli|McMaster\.Extensions\.CommandLineUtils|Cocona)\b/
GET_ARGS = /\bEnvironment\.GetCommandLineArgs\s*\(/
LIB_USAGE = /\bnew\s+RootCommand\s*\(|\bnew\s+CommandApp\b|\bCliApplicationBuilder\s*\(|\bParser\.Default\.ParseArguments\b|\[\s*Verb\s*\(|\[\s*CommandOption\s*\(|\[\s*CommandArgument\s*\(|\bCommandLineApplication\.Execute\b|\[\s*Subcommand\s*\(|\bCoconaApp\.(?:Create|Run)\b/
MAIN_ARGS = /\bstatic\s+(?:async\s+)?(?:int|void|Task(?:<int>)?)\s+Main\s*\(\s*string\s*\[\s*\]\s+\w+\s*\)/
WEB_HOST = /\bWebApplication\.(?:Create(?:Builder|SlimBuilder|EmptyBuilder)?|CreateDefault)\b|\bnew\s+HttpListener\b|\.MapGet\s*\(|\.MapPost\s*\(|\.MapControllers\s*\(|\[\s*ApiController\s*\]|:\s*ControllerBase\b|\bHost\.CreateDefaultBuilder\b/

Instance Method Summary

Instance methods inherited from class Detector

applicable?(filename : String) : Bool applicable?, detect(filename : String, file_contents : String) : Bool detect, gemfile_dependency?(file_contents : String, gem_name : String) : Bool gemfile_dependency?, gemspec_dependency?(file_contents : String, gem_name : String) : Bool gemspec_dependency?, idempotent? : Bool idempotent?, logger : NoirLogger logger, name : String name, path_sensitive? : Bool path_sensitive?

Constructor methods inherited from class Detector

new(options : Hash(String, YAML::Any)) new

Instance Method Detail

def applicable?(filename : String) : Bool #
Description copied from class Detector

Cheap filename-only filter the detector pass uses to skip #detect on files the detector cannot possibly match. The default true preserves prior behavior (every detector runs on every file). Override with the same predicate the body of #detect starts with — e.g., filename.ends_with?(".py") for a Python framework detector — so the detector loop avoids the #detect dispatch on files outside the detector's language.

On large codebases (saleor's 4255 .py files) this lifts ~100 virtual #detect calls per file out of the hot loop because most detectors' inner first-line is exactly this kind of cheap filename check.


[View source]
def detect(filename : String, file_contents : String) : Bool #

[View source]
def set_name #

[View source]