This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / knot2 / crates / knot-langs / src / linguist.rs
11 kB 196 lines
1use std::sync::LazyLock; 2 3use regex::Regex; 4 5static VENDOR: LazyLock<Regex> = LazyLock::new(|| { 6 Regex::new(r"(?:^(?:(?:[Dd]ependencies/)|(?:debian/)|(?:deps/)|(?:rebar$)))|(?:(?:^|/)(?:(?:BuddyBuildSDK\.framework/)|(?:Carthage/)|(?:Chart\.js$)|(?:Control\.FullScreen\.css)|(?:Control\.FullScreen\.js)|(?:Crashlytics\.framework/)|(?:Fabric\.framework/)|(?:Godeps/_workspace/)|(?:Jenkinsfile$)|(?:Leaflet\.Coordinates-\d+\.\d+\.\d+\.src\.js$)|(?:MathJax/)|(?:MochiKit\.js$)|(?:RealmSwift\.framework)|(?:Realm\.framework)|(?:Sparkle/)|(?:Vagrantfile$)|(?:[Bb]ourbon/.*\.(css|less|scss|styl)$)|(?:[Cc]ode[Mm]irror/(\d+\.\d+/)?(lib|mode|theme|addon|keymap|demo))|(?:[Ee]xtern(als?)?/)|(?:[Mm]icrosoft([Mm]vc)?([Aa]jax|[Vv]alidation)(\.debug)?\.js$)|(?:[Pp]ackages/.+\.\d+/)|(?:[Ss]pecs?/fixtures/)|(?:[Tt]ests?/fixtures/)|(?:[Vv]+endor/)|(?:\.[Dd][Ss]_[Ss]tore$)|(?:\.gitattributes$)|(?:\.github/)|(?:\.gitignore$)|(?:\.gitmodules$)|(?:\.gitpod\.Dockerfile$)|(?:\.google_apis/)|(?:\.indent\.pro)|(?:\.mvn/wrapper/)|(?:\.obsidian/)|(?:\.osx$)|(?:\.sublime-project)|(?:\.sublime-workspace)|(?:\.teamcity/)|(?:\.vscode/)|(?:\.yarn/plugins/)|(?:\.yarn/releases/)|(?:\.yarn/sdks/)|(?:\.yarn/unplugged/)|(?:\.yarn/versions/)|(?:_esy$)|(?:ace-builds/)|(?:aclocal\.m4)|(?:activator$)|(?:activator\.bat$)|(?:admin_media/)|(?:angular([^.]*)\.js$)|(?:animate\.(css|less|scss|styl)$)|(?:bootbox\.js)|(?:bootstrap([^/.]*)(\..*)?\.(js|css|less|scss|styl)$)|(?:bootstrap-datepicker/)|(?:bower_components/)|(?:bulma\.(css|sass|scss)$)|(?:cache/)|(?:ckeditor\.js$)|(?:config\.guess$)|(?:config\.sub$)|(?:configure$)|(?:controls\.js$)|(?:cordova([^.]*)\.js$)|(?:cordova\-\d\.\d(\.\d)?\.js$)|(?:cpplint\.py)|(?:custom\.bootstrap([^\s]*)(js|css|less|scss|styl)$)|(?:dist/)|(?:docs?/_?(build|themes?|templates?|static)/)|(?:dojo\.js$)|(?:dotnet-install\.(ps1|sh)$)|(?:dragdrop\.js$)|(?:effects\.js$)|(?:env/)|(?:erlang\.mk)|(?:extjs/.*?\.html$)|(?:extjs/.*?\.js$)|(?:extjs/.*?\.properties$)|(?:extjs/.*?\.txt$)|(?:extjs/.*?\.xml$)|(?:extjs/\.sencha/)|(?:extjs/builds/)|(?:extjs/cmd/)|(?:extjs/docs/)|(?:extjs/examples/)|(?:extjs/locale/)|(?:extjs/packages/)|(?:extjs/plugins/)|(?:extjs/resources/)|(?:extjs/src/)|(?:extjs/welcome/)|(?:fabfile\.py$)|(?:flow-typed/.*\.js$)|(?:font-?awesome/.*\.(css|less|scss|styl)$)|(?:font-?awesome\.(css|less|scss|styl)$)|(?:fontello(.*?)\.css$)|(?:foundation(\..*)?\.js$)|(?:foundation\.(css|less|scss|styl)$)|(?:fuelux\.js)|(?:gradle/wrapper/)|(?:gradlew$)|(?:gradlew\.bat$)|(?:html5shiv\.js$)|(?:inst/extdata/)|(?:jquery([^.]*)\.js$)|(?:jquery([^.]*)\.unobtrusive\-ajax\.js$)|(?:jquery([^.]*)\.validate(\.unobtrusive)?\.js$)|(?:jquery\-\d\.\d+(\.\d+)?\.js$)|(?:jquery\-ui(\-\d\.\d+(\.\d+)?)?(\.\w+)?\.(js|css)$)|(?:jquery\.(ui|effects)\.([^.]*)\.(js|css)$)|(?:jquery\.dataTables\.js)|(?:jquery\.fancybox\.(js|css))|(?:jquery\.fileupload(-\w+)?\.js$)|(?:jquery\.fn\.gantt\.js)|(?:knockout-(\d+\.){3}(debug\.)?js$)|(?:leaflet\.draw-src\.js)|(?:leaflet\.draw\.css)|(?:leaflet\.spin\.js)|(?:libtool\.m4)|(?:ltoptions\.m4)|(?:ltsugar\.m4)|(?:ltversion\.m4)|(?:lt~obsolete\.m4)|(?:materialize\.(css|less|scss|styl|js)$)|(?:modernizr\-\d\.\d+(\.\d+)?\.js$)|(?:modernizr\.custom\.\d+\.js$)|(?:mootools([^.]*)\d+\.\d+.\d+([^.]*)\.js$)|(?:mvnw$)|(?:mvnw\.cmd$)|(?:node_modules/)|(?:normalize\.(css|less|scss|styl)$)|(?:octicons\.css)|(?:pdf\.worker\.js)|(?:proguard-rules\.pro$)|(?:proguard\.pro$)|(?:prototype(.*)\.js$)|(?:puphpet/)|(?:react(-[^.]*)?\.js$)|(?:run\.n$)|(?:select2/.*\.(css|scss|js)$)|(?:shBrush([^.]*)\.js$)|(?:shCore\.js$)|(?:shLegacy\.js$)|(?:skeleton\.(css|less|scss|styl)$)|(?:slick\.\w+.js$)|(?:sprockets-octicons\.scss)|(?:testdata/)|(?:tiny_mce([^.]*)\.js$)|(?:tiny_mce/(langs|plugins|themes|utils))|(?:vendors?/)|(?:waf$)|(?:wicket-leaflet\.js)|(?:xvba_modules/)|(?:yahoo-([^.]*)\.js$)|(?:yui([^.]*)\.js$)))|(?:(.*?)\.d\.ts$)|(?:(3rd|[Tt]hird)[-_]?[Pp]arty/)|(?:([^\s]*)import\.(css|less|scss|styl)$)|(?:(\.|-)min\.(js|css)$)|(?:(^|/)d3(\.v\d+)?([^.]*)\.js$)|(?:-vsdoc\.js$)|(?:\.imageset/)|(?:\.intellisense\.js$)|(?:\.xctemplate/)").expect("enry vendor regex compiles") 7}); 8 9static DOCUMENTATION: LazyLock<Regex> = LazyLock::new(|| { 10 Regex::new(r"(?:^[Dd]ocs?/)|(?:(^|/)[Dd]ocumentation/)|(?:(^|/)[Gg]roovydoc/)|(?:(^|/)[Jj]avadoc/)|(?:^[Mm]an/)|(?:^[Ee]xamples/)|(?:^[Dd]emos?/)|(?:(^|/)inst/doc/)|(?:(^|/)CITATION(\.cff|(S)?(\.(bib|md))?)$)|(?:(^|/)CHANGE(S|LOG)?(\.|$))|(?:(^|/)CONTRIBUTING(\.|$))|(?:(^|/)COPYING(\.|$))|(?:(^|/)INSTALL(\.|$))|(?:(^|/)LICEN[CS]E(\.|$))|(?:(^|/)[Ll]icen[cs]e(\.|$))|(?:(^|/)README(\.|$))|(?:(^|/)[Rr]eadme(\.|$))|(?:^[Ss]amples?/)").expect("enry documentation regex compiles") 11}); 12 13static GENERATED_NAME: LazyLock<Regex> = LazyLock::new(|| { 14 Regex::new(r"(?:(?:^|/)\.idea/)|(?:(^Pods|/Pods)/)|(?:(^|/)Carthage/Build/)|(?:(?i)\.designer\.(cs|vb)$)|(?:(?i)\.feature\.cs$)|(?:vendor/([-0-9A-Za-z]+\.)+(com|edu|gov|in|me|net|org|fm|io))|(?:(^|/)(\w+\.)?esy.lock$)|(?:(^|/)\.pnp\..*$)|(?:.\.zep\.(?:c|h|php)$)|(?:(^|/)flake\.lock$)|(?:(^|/)MODULE\.bazel\.lock$)|(?:(?:^|/)\.terraform\.lock\.hcl$)|(?:(?i)_tlb\.pas$)|(?:(?:^|/)htmlcov/)|(?:(?:^|.*/)\.sqlx/query-.+\.json$)").expect("enry generated-name regex compiles") 15}); 16 17const GENERATED_SUFFIXES: &[&str] = &[ 18 "Gopkg.lock", 19 "glide.lock", 20 "poetry.lock", 21 "pdm.lock", 22 "uv.lock", 23 "deno.lock", 24 "npm-shrinkwrap.json", 25 "package-lock.json", 26 "pnpm-lock.yaml", 27 "composer.lock", 28 "Cargo.lock", 29 "Cargo.toml.orig", 30 "Pipfile.lock", 31 "bun.lock", 32]; 33 34const GENERATED_CONTAINS: &[&str] = &["node_modules/", "Godeps/", "__generated__/"]; 35 36const GENERATED_EXTENSIONS: &[&str] = &[".nib", ".xcworkspacedata", ".xcuserstate"]; 37 38fn is_dotfile(path: &str) -> bool { 39 path.rsplit('/') 40 .next() 41 .is_some_and(|base| base.starts_with('.') && base != ".") 42} 43 44fn is_generated_name(path: &str) -> bool { 45 GENERATED_SUFFIXES 46 .iter() 47 .any(|suffix| path.ends_with(suffix)) 48 || GENERATED_CONTAINS 49 .iter() 50 .any(|needle| path.contains(needle)) 51 || GENERATED_EXTENSIONS 52 .iter() 53 .any(|extension| path.ends_with(extension)) 54 || GENERATED_NAME.is_match(path) 55} 56 57pub(crate) fn is_skipped_path(path: &str) -> bool { 58 is_dotfile(path) 59 || VENDOR.is_match(path) 60 || DOCUMENTATION.is_match(path) 61 || is_generated_name(path) 62} 63 64pub(crate) fn is_vendor_dir(path: &str) -> bool { 65 VENDOR.is_match(&format!("{path}/")) 66} 67 68fn language_group(name: &str) -> Option<&'static str> { 69 match name { 70 "Alpine Abuild" => Some("Shell"), 71 "Apollo Guidance Computer" => Some("Assembly"), 72 "BibTeX" => Some("TeX"), 73 "Bison" => Some("Yacc"), 74 "Bluespec BH" => Some("Bluespec"), 75 "C2hs Haskell" => Some("Haskell"), 76 "Cairo" => Some("Cairo"), 77 "Cairo Zero" => Some("Cairo"), 78 "CameLIGO" => Some("LigoLANG"), 79 "ColdFusion CFC" => Some("ColdFusion"), 80 "Cylc" => Some("INI"), 81 "ECLiPSe" => Some("Prolog"), 82 "Easybuild" => Some("Python"), 83 "Ecere Projects" => Some("JavaScript"), 84 "Ecmarkup" => Some("HTML"), 85 "EditorConfig" => Some("INI"), 86 "Elvish Transcript" => Some("Elvish"), 87 "Filterscript" => Some("RenderScript"), 88 "Fortran" => Some("Fortran"), 89 "Fortran Free Form" => Some("Fortran"), 90 "Gentoo Ebuild" => Some("Shell"), 91 "Gentoo Eclass" => Some("Shell"), 92 "Git Config" => Some("INI"), 93 "Glimmer JS" => Some("JavaScript"), 94 "Glimmer TS" => Some("TypeScript"), 95 "Gradle Kotlin DSL" => Some("Gradle"), 96 "Groovy Server Pages" => Some("Groovy"), 97 "HTML+ECR" => Some("HTML"), 98 "HTML+EEX" => Some("HTML"), 99 "HTML+ERB" => Some("HTML"), 100 "HTML+PHP" => Some("HTML"), 101 "HTML+Razor" => Some("HTML"), 102 "Isabelle ROOT" => Some("Isabelle"), 103 "JFlex" => Some("Lex"), 104 "JSON with Comments" => Some("JSON"), 105 "Java Server Pages" => Some("Java"), 106 "Java Template Engine" => Some("Java"), 107 "JavaScript+ERB" => Some("JavaScript"), 108 "Jison" => Some("Yacc"), 109 "Jison Lex" => Some("Lex"), 110 "Julia REPL" => Some("Julia"), 111 "Lean 4" => Some("Lean"), 112 "LigoLANG" => Some("LigoLANG"), 113 "Literate Agda" => Some("Agda"), 114 "Literate CoffeeScript" => Some("CoffeeScript"), 115 "Literate Haskell" => Some("Haskell"), 116 "M4Sugar" => Some("M4"), 117 "MUF" => Some("Forth"), 118 "Maven POM" => Some("XML"), 119 "Motorola 68K Assembly" => Some("Assembly"), 120 "NPM Config" => Some("INI"), 121 "NumPy" => Some("Python"), 122 "OASv2-json" => Some("OpenAPI Specification v2"), 123 "OASv2-yaml" => Some("OpenAPI Specification v2"), 124 "OASv3-json" => Some("OpenAPI Specification v3"), 125 "OASv3-yaml" => Some("OpenAPI Specification v3"), 126 "OpenCL" => Some("C"), 127 "OpenRC runscript" => Some("Shell"), 128 "Parrot Assembly" => Some("Parrot"), 129 "Parrot Internal Representation" => Some("Parrot"), 130 "Pic" => Some("Roff"), 131 "PostCSS" => Some("CSS"), 132 "Python console" => Some("Python"), 133 "Python traceback" => Some("Python"), 134 "RBS" => Some("Ruby"), 135 "Readline Config" => Some("INI"), 136 "ReasonLIGO" => Some("LigoLANG"), 137 "Roff Manpage" => Some("Roff"), 138 "SSH Config" => Some("INI"), 139 "STON" => Some("Smalltalk"), 140 "Simple File Verification" => Some("Checksums"), 141 "Snakemake" => Some("Python"), 142 "TSX" => Some("TypeScript"), 143 "Tcsh" => Some("Shell"), 144 "Terraform Template" => Some("HCL"), 145 "Unified Parallel C" => Some("C"), 146 "Unix Assembly" => Some("Assembly"), 147 "Wget Config" => Some("INI"), 148 "X BitMap" => Some("C"), 149 "X PixMap" => Some("C"), 150 "XML Property List" => Some("XML"), 151 "cURL Config" => Some("INI"), 152 "fish" => Some("Shell"), 153 "nanorc" => Some("INI"), 154 _ => None, 155 } 156} 157 158pub(crate) fn group(name: &'static str) -> &'static str { 159 language_group(name).unwrap_or(name) 160} 161 162#[cfg(test)] 163mod tests { 164 use super::*; 165 166 #[test] 167 fn enry_matchers_compile_and_match_known_paths() { 168 assert!(is_skipped_path("node_modules/left-pad/index.js")); 169 assert!(is_skipped_path("src/jquery-3.6.0.js")); 170 assert!(is_skipped_path("docs/guide.md")); 171 assert!(is_skipped_path("README.md")); 172 assert!(is_skipped_path("LICENSE")); 173 assert!(is_skipped_path("Cargo.lock")); 174 assert!(is_skipped_path("package-lock.json")); 175 assert!(is_skipped_path("app/main.designer.cs")); 176 assert!(is_skipped_path(".github/workflows/ci.yml")); 177 assert!(is_skipped_path("third_party/zlib/zlib.c")); 178 assert!(is_skipped_path("web/app.min.js")); 179 assert!(!is_skipped_path("src/main.rs")); 180 assert!(!is_skipped_path("internal/server.go")); 181 } 182 183 #[test] 184 fn vendor_dir_pruning_matches_directory_paths() { 185 assert!(is_vendor_dir("node_modules")); 186 assert!(is_vendor_dir("a/b/dist")); 187 assert!(!is_vendor_dir("src")); 188 } 189 190 #[test] 191 fn grouping_folds_known_languages() { 192 assert_eq!(group("TSX"), "TypeScript"); 193 assert_eq!(group("HTML+ERB"), "HTML"); 194 assert_eq!(group("Rust"), "Rust"); 195 } 196}