Skip to content

Commit 811a3e5

Browse files
authored
Merge pull request #10 from codacy/bump-to-1-17-0-and-i18n
Bump to 1.17.0 and some new i18n patterns
2 parents 09fe7b8 + 2ce7f0b commit 811a3e5

File tree

6 files changed

+249
-2
lines changed

6 files changed

+249
-2
lines changed

.tool_version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.16.4
1+
1.17.0

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
ARG OPENGREP_VERSION=v1.16.4
1+
ARG OPENGREP_VERSION=v1.17.0
22

33
# Build codacy-opengrep wrapper
44
FROM golang:1.23-alpine3.21 AS builder

docs/codacy-rules-i18n.yaml

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,3 +432,109 @@ rules:
432432
impact: MEDIUM
433433
confidence: LOW
434434
likelihood: HIGH
435+
436+
- id: codacy.python.i18n.no-hardcoded-print-concat
437+
severity: WARNING
438+
languages:
439+
- python
440+
pattern-either:
441+
- pattern: print("..." + ...)
442+
- pattern: print(... + "...")
443+
message: >-
444+
Avoid hardcoded or concatenated strings in print. Use an i18n translation function (e.g., _("key")) with .format() or f-strings.
445+
metadata:
446+
category: codestyle
447+
subcategory: i18n
448+
description: Flags hardcoded string literals concatenated in print calls to enforce localization
449+
technology:
450+
- python
451+
impact: MEDIUM
452+
confidence: LOW
453+
likelihood: HIGH
454+
455+
- id: codacy.python.i18n.no-hardcoded-strftime
456+
severity: WARNING
457+
languages:
458+
- python
459+
pattern: $X.strftime("...")
460+
message: >-
461+
Avoid hardcoded date format strings in strftime. Use locale.nl_langinfo(locale.D_FMT) or similar locale-aware formatting.
462+
metadata:
463+
category: codestyle
464+
subcategory: i18n
465+
description: Flags hardcoded date format strings passed to strftime to enforce locale-aware date formatting
466+
technology:
467+
- python
468+
impact: MEDIUM
469+
confidence: HIGH
470+
likelihood: HIGH
471+
472+
- id: codacy.python.i18n.no-hardcoded-number-format
473+
severity: WARNING
474+
languages:
475+
- python
476+
pattern-regex: ":\\.[0-9]+f"
477+
message: >-
478+
Avoid using :.Nf format specifiers for user-visible number formatting. Use locale.currency() or locale.format_string() for locale-aware formatting.
479+
metadata:
480+
category: codestyle
481+
subcategory: i18n
482+
description: Flags :.Nf format specifiers in f-strings used for user-visible numbers instead of locale-aware formatting
483+
technology:
484+
- python
485+
impact: MEDIUM
486+
confidence: LOW
487+
likelihood: HIGH
488+
489+
- id: codacy.cpp.i18n.no-hardcoded-cout
490+
severity: WARNING
491+
languages:
492+
- cpp
493+
pattern: std::cout << "$MSG"
494+
message: >-
495+
Avoid hardcoded strings in std::cout. Use a localization function or resource bundle for user-facing output.
496+
metadata:
497+
category: codestyle
498+
subcategory: i18n
499+
description: Flags hardcoded string literals streamed directly to std::cout to enforce localization
500+
technology:
501+
- cpp
502+
impact: MEDIUM
503+
confidence: LOW
504+
likelihood: HIGH
505+
506+
- id: codacy.cpp.i18n.no-hardcoded-strftime
507+
severity: WARNING
508+
languages:
509+
- cpp
510+
pattern-either:
511+
- pattern: std::strftime($BUF, $SIZE, "$FMT", $TIME);
512+
- pattern: strftime($BUF, $SIZE, "$FMT", $TIME);
513+
message: >-
514+
Avoid hardcoded date format strings in strftime. Use locale-aware date formatting (e.g., std::put_time with a locale-imbued stream).
515+
metadata:
516+
category: codestyle
517+
subcategory: i18n
518+
description: Flags hardcoded date format strings passed to strftime to enforce locale-aware date formatting
519+
technology:
520+
- cpp
521+
impact: MEDIUM
522+
confidence: HIGH
523+
likelihood: HIGH
524+
525+
- id: codacy.cpp.i18n.no-hardcoded-number-format
526+
severity: WARNING
527+
languages:
528+
- cpp
529+
pattern: std::setprecision($N)
530+
message: >-
531+
Avoid using std::setprecision for user-visible number formatting. Imbue the stream with a locale and use std::use_facet<std::numpunct> for locale-aware output.
532+
metadata:
533+
category: codestyle
534+
subcategory: i18n
535+
description: Flags std::setprecision used for user-visible number formatting instead of locale-aware alternatives
536+
technology:
537+
- cpp
538+
impact: MEDIUM
539+
confidence: LOW
540+
likelihood: HIGH

docs/multiple-tests/i18n/patterns.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,10 @@
1616
<module name="codacy.js.i18n.no-hardcoded-throw-error" />
1717
<module name="codacy.java.i18n.no-hardcoded-map-put" />
1818
<module name="codacy.java.i18n.no-hardcoded-map-of" />
19+
<module name="codacy.python.i18n.no-hardcoded-print-concat" />
20+
<module name="codacy.python.i18n.no-hardcoded-strftime" />
21+
<module name="codacy.python.i18n.no-hardcoded-number-format" />
22+
<module name="codacy.cpp.i18n.no-hardcoded-cout" />
23+
<module name="codacy.cpp.i18n.no-hardcoded-strftime" />
24+
<module name="codacy.cpp.i18n.no-hardcoded-number-format" />
1925
</module>

docs/multiple-tests/i18n/results.xml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,4 +315,56 @@
315315
message="Avoid hardcoded strings in Map.put(). Use ResourceBundle.getString() or a localization key for user-facing messages."
316316
severity="warning" />
317317
</file>
318+
<file name="Order.cpp">
319+
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="25"
320+
message="Avoid hardcoded strings in std::cout."
321+
severity="warning" />
322+
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="31"
323+
message="Avoid hardcoded strings in std::cout."
324+
severity="warning" />
325+
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="34"
326+
message="Avoid hardcoded strings in std::cout."
327+
severity="warning" />
328+
<error source="codacy.cpp.i18n.no-hardcoded-number-format" line="40"
329+
message="Avoid using std::setprecision for user-visible number formatting."
330+
severity="warning" />
331+
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="44"
332+
message="Avoid hardcoded strings in std::cout."
333+
severity="warning" />
334+
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="52"
335+
message="Avoid hardcoded strings in std::cout."
336+
severity="warning" />
337+
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="57"
338+
message="Avoid hardcoded strings in std::cout."
339+
severity="warning" />
340+
<error source="codacy.cpp.i18n.no-hardcoded-strftime" line="64"
341+
message="Avoid hardcoded date format strings in strftime."
342+
severity="warning" />
343+
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="65"
344+
message="Avoid hardcoded strings in std::cout."
345+
severity="warning" />
346+
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="73"
347+
message="Avoid hardcoded strings in std::cout."
348+
severity="warning" />
349+
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="74"
350+
message="Avoid hardcoded strings in std::cout."
351+
severity="warning" />
352+
</file>
353+
<file name="Sample.py">
354+
<error source="codacy.python.i18n.no-hardcoded-print-concat" line="35"
355+
message="Avoid hardcoded or concatenated strings in print."
356+
severity="warning" />
357+
<error source="codacy.python.i18n.no-hardcoded-strftime" line="48"
358+
message="Avoid hardcoded date format strings in strftime."
359+
severity="warning" />
360+
<error source="codacy.python.i18n.no-hardcoded-number-format" line="48"
361+
message="Avoid using :.Nf format specifiers for user-visible number formatting."
362+
severity="warning" />
363+
<error source="codacy.python.i18n.no-hardcoded-print-concat" line="61"
364+
message="Avoid hardcoded or concatenated strings in print."
365+
severity="warning" />
366+
<error source="codacy.python.i18n.no-hardcoded-print-concat" line="62"
367+
message="Avoid hardcoded or concatenated strings in print."
368+
severity="warning" />
369+
</file>
318370
</checkstyle>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import datetime
2+
import locale
3+
import gettext
4+
5+
# Set up gettext (only English & French, but French translations missing some keys)
6+
locales = {
7+
"en": gettext.translation("messages", localedir="locales", languages=["en"], fallback=True),
8+
"fr": gettext.translation("messages", localedir="locales", languages=["fr"], fallback=True),
9+
}
10+
11+
current_locale = "en"
12+
_ = locales[current_locale].gettext
13+
14+
orders = [
15+
{"id": 1, "customer": "Alice", "amount": 1234.56, "date": datetime.date.today()},
16+
{"id": 2, "customer": "Bob", "amount": 98765.43, "date": datetime.date.today()},
17+
]
18+
19+
20+
def switch_language(lang):
21+
global _, current_locale
22+
if lang in locales:
23+
current_locale = lang
24+
_ = locales[lang].gettext
25+
else:
26+
print(f"Language {lang} not supported, falling back to English")
27+
current_locale = "en"
28+
_ = locales["en"].gettext
29+
30+
31+
def add_order(customer, amount):
32+
today = datetime.date.today()
33+
34+
# ❌ BAD: Hardcoded English + concatenation
35+
print("Order for " + customer + " created on " + str(today))
36+
37+
# ✅ GOOD: Proper i18n message
38+
print(_("Order for {customer} created on {date}").format(customer=customer, date=today))
39+
40+
orders.append({"id": len(orders) + 1, "customer": customer, "amount": amount, "date": today})
41+
42+
43+
def list_orders():
44+
print(_("Order List"))
45+
print("------------")
46+
for o in orders:
47+
# ❌ BAD: Hardcoded date format
48+
print(f"{o['customer']} | {o['date'].strftime('%m/%d/%Y')} | ${o['amount']:.2f}")
49+
50+
# ✅ GOOD: Locale-aware formatting
51+
locale.setlocale(locale.LC_ALL, current_locale)
52+
formatted_date = o['date'].strftime(locale.nl_langinfo(locale.D_FMT))
53+
formatted_amount = locale.currency(o['amount'], grouping=True)
54+
print(f"{o['customer']} | {formatted_date} | {formatted_amount}")
55+
56+
57+
def summary():
58+
total = sum(o["amount"] for o in orders)
59+
60+
# ❌ BAD: Hardcoded string
61+
print("Total Orders: " + str(len(orders)))
62+
print("Total Revenue: $" + str(total))
63+
64+
# ✅ GOOD: Localized message
65+
print(_("Total Orders: {count}").format(count=len(orders)))
66+
print(_("Total Revenue: {revenue}").format(revenue=locale.currency(total, grouping=True)))
67+
68+
69+
if __name__ == "__main__":
70+
print(_("Welcome to Order Management System"))
71+
72+
list_orders()
73+
74+
add_order("Charlie", 555.75)
75+
76+
print("\nAfter Adding Order:")
77+
list_orders()
78+
79+
summary()
80+
81+
print("\nSwitching to French (missing translations -> fallback):")
82+
switch_language("fr")
83+
list_orders()

0 commit comments

Comments
 (0)