Skip to content

Commit f86691d

Browse files
author
CI
committed
Sync to GitHub
1 parent c02f875 commit f86691d

6 files changed

Lines changed: 231 additions & 5 deletions

File tree

.credo.exs

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# This file contains the configuration for Credo and you are probably reading
2+
# this after creating it with `mix credo.gen.config`.
3+
#
4+
# If you find anything wrong or unclear in this file, please report an
5+
# issue on GitHub: https://github.com/rrrene/credo/issues
6+
#
7+
%{
8+
#
9+
# You can have as many configs as you like in the `configs:` field.
10+
configs: [
11+
%{
12+
#
13+
# Run any config using `mix credo -C <name>`. If no config name is given
14+
# "default" is used.
15+
#
16+
name: "default",
17+
#
18+
# These are the files included in the analysis:
19+
files: %{
20+
#
21+
# You can give explicit globs or simply directories.
22+
# In the latter case `**/*.{ex,exs}` will be used.
23+
#
24+
included: ["lib/"],
25+
excluded: [~r"/_build/", ~r"/deps/", ~r"/node_modules/"]
26+
},
27+
#
28+
# Load and configure plugins here:
29+
#
30+
plugins: [],
31+
#
32+
# If you create your own checks, you must specify the source files for
33+
# them here, so they can be loaded by Credo before running the analysis.
34+
#
35+
requires: [],
36+
#
37+
# If you want to enforce a style guide and need a more traditional linting
38+
# experience, you can change `strict` to `true` below:
39+
#
40+
strict: false,
41+
#
42+
# To modify the timeout for parsing files, change this value:
43+
#
44+
parse_timeout: 5000,
45+
#
46+
# If you want to use uncolored output by default, you can change `color`
47+
# to `false` below:
48+
#
49+
color: true,
50+
#
51+
# You can customize the parameters of any check by adding a second element
52+
# to the tuple.
53+
#
54+
# To disable a check put `false` as second element:
55+
#
56+
# {Credo.Check.Design.DuplicatedCode, false}
57+
#
58+
checks: [
59+
#
60+
## Consistency Checks
61+
#
62+
{Credo.Check.Consistency.ExceptionNames, []},
63+
{Credo.Check.Consistency.LineEndings, [force: :unix]},
64+
{Credo.Check.Consistency.ParameterPatternMatching, []},
65+
{Credo.Check.Consistency.SpaceAroundOperators, []},
66+
{Credo.Check.Consistency.SpaceInParentheses, []},
67+
{Credo.Check.Consistency.TabsOrSpaces, []},
68+
69+
#
70+
## Design Checks
71+
#
72+
# You can customize the priority of any check
73+
# Priority values are: `low, normal, high, higher`
74+
#
75+
{Credo.Check.Design.AliasUsage,
76+
[priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 2]},
77+
78+
# You can also customize the exit_status of each check.
79+
# If you don't want TODO comments to cause `mix credo` to fail, just
80+
# set this value to 0 (zero).
81+
#
82+
{Credo.Check.Design.TagTODO, [exit_status: 0]},
83+
{Credo.Check.Design.TagFIXME, []},
84+
85+
#
86+
## Readability Checks
87+
#
88+
{Credo.Check.Readability.AliasOrder, []},
89+
{Credo.Check.Readability.FunctionNames, []},
90+
{Credo.Check.Readability.LargeNumbers, []},
91+
{Credo.Check.Readability.MaxLineLength, [priority: :low, max_length: 120]},
92+
{Credo.Check.Readability.ModuleAttributeNames, []},
93+
# ModuleDoc is covered by Doctor in a better way
94+
{Credo.Check.Readability.ModuleDoc, false},
95+
{Credo.Check.Readability.ModuleNames, []},
96+
{Credo.Check.Readability.ParenthesesInCondition, []},
97+
{Credo.Check.Readability.ParenthesesOnZeroArityDefs, parens: true},
98+
{Credo.Check.Readability.PredicateFunctionNames, false},
99+
{Credo.Check.Readability.PreferImplicitTry, []},
100+
{Credo.Check.Readability.RedundantBlankLines, []},
101+
{Credo.Check.Readability.Semicolons, []},
102+
{Credo.Check.Readability.SpaceAfterCommas, []},
103+
{Credo.Check.Readability.StringSigils, []},
104+
{Credo.Check.Readability.TrailingBlankLine, []},
105+
{Credo.Check.Readability.TrailingWhiteSpace, []},
106+
{Credo.Check.Readability.UnnecessaryAliasExpansion, []},
107+
{Credo.Check.Readability.VariableNames, []},
108+
109+
#
110+
## Refactoring Opportunities
111+
#
112+
{Credo.Check.Refactor.CondStatements, []},
113+
{Credo.Check.Refactor.CyclomaticComplexity, [max_complexity: 20]},
114+
{Credo.Check.Refactor.FunctionArity, [max_arity: 10]},
115+
{Credo.Check.Refactor.LongQuoteBlocks, []},
116+
# significant performance improvement since Elixir v1.8
117+
{Credo.Check.Refactor.MapInto, false},
118+
{Credo.Check.Refactor.MatchInCondition, []},
119+
{Credo.Check.Refactor.NegatedConditionsInUnless, []},
120+
{Credo.Check.Refactor.NegatedConditionsWithElse, []},
121+
{Credo.Check.Refactor.Nesting, [max_nesting: 6]},
122+
{Credo.Check.Refactor.UnlessWithElse, []},
123+
{Credo.Check.Refactor.WithClauses, []},
124+
125+
#
126+
## Warnings
127+
#
128+
{Credo.Check.Warning.BoolOperationOnSameValues, []},
129+
{Credo.Check.Warning.ExpensiveEmptyEnumCheck, []},
130+
{Credo.Check.Warning.IExPry, []},
131+
{Credo.Check.Warning.IoInspect, []},
132+
{Credo.Check.Warning.LazyLogging, false},
133+
{Credo.Check.Warning.MixEnv, false},
134+
{Credo.Check.Warning.OperationOnSameValues, []},
135+
{Credo.Check.Warning.OperationWithConstantResult, []},
136+
{Credo.Check.Warning.RaiseInsideRescue, []},
137+
{Credo.Check.Warning.UnusedEnumOperation, []},
138+
{Credo.Check.Warning.UnusedFileOperation, []},
139+
{Credo.Check.Warning.UnusedKeywordOperation, []},
140+
{Credo.Check.Warning.UnusedListOperation, []},
141+
{Credo.Check.Warning.UnusedPathOperation, []},
142+
{Credo.Check.Warning.UnusedRegexOperation, []},
143+
{Credo.Check.Warning.UnusedStringOperation, []},
144+
{Credo.Check.Warning.UnusedTupleOperation, []},
145+
{Credo.Check.Warning.UnsafeExec, []},
146+
147+
#
148+
# Checks scheduled for next check update (opt-in for now, just replace `false` with `[]`)
149+
150+
#
151+
# Controversial and experimental checks (opt-in, just replace `false` with `[]`)
152+
#
153+
{Credo.Check.Readability.StrictModuleLayout, false},
154+
{Credo.Check.Consistency.MultiAliasImportRequireUse, false},
155+
{Credo.Check.Consistency.UnusedVariableNames, []},
156+
{Credo.Check.Design.DuplicatedCode, false},
157+
{Credo.Check.Readability.AliasAs, false},
158+
{Credo.Check.Readability.MultiAlias, []},
159+
# disable for now (ErrorView.template_not_found raises dialyzer)
160+
{Credo.Check.Readability.Specs, false},
161+
{Credo.Check.Readability.SinglePipe, []},
162+
{Credo.Check.Readability.WithCustomTaggedTuple, []},
163+
{Credo.Check.Refactor.ABCSize, false},
164+
{Credo.Check.Refactor.AppendSingleItem, []},
165+
{Credo.Check.Refactor.DoubleBooleanNegation, false},
166+
{Credo.Check.Refactor.ModuleDependencies, false},
167+
{Credo.Check.Refactor.NegatedIsNil, false},
168+
{Credo.Check.Refactor.PipeChainStart, []},
169+
{Credo.Check.Refactor.VariableRebinding, false},
170+
{Credo.Check.Warning.LeakyEnvironment, false},
171+
{Credo.Check.Warning.MapGetUnsafePass, []},
172+
{Credo.Check.Warning.UnsafeToAtom, []}
173+
174+
#
175+
# Custom checks can be created using `mix credo.gen.check`.
176+
#
177+
]
178+
}
179+
]
180+
}

.doctor.exs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
%Doctor.Config{
2+
ignore_modules: [],
3+
ignore_paths: [~r/test\//],
4+
min_module_doc_coverage: 80,
5+
min_module_spec_coverage: 100,
6+
min_overall_doc_coverage: 80,
7+
min_overall_moduledoc_coverage: 100,
8+
min_overall_spec_coverage: 100,
9+
exception_moduledoc_required: true,
10+
raise: false,
11+
reporter: Doctor.Reporters.Full,
12+
struct_type_spec_required: true,
13+
umbrella: false,
14+
failed: false
15+
}

.formatter.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[
2+
import_deps: [:typedstruct],
3+
inputs: ["*.{ex,exs}", "{config,examples,lib,test}/**/*.{ex,exs}"]
4+
]

lib/bacnet/protocol/services/ack/read_range_ack.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ defmodule BACnet.Protocol.Services.Ack.ReadRangeAck do
5858
{:ok, first_seq_num, _rest} <-
5959
pattern_extract_tags(rest, {:tagged, {6, _t, _l}}, :unsigned_integer, true),
6060
:ok <-
61-
if(ApplicationTags.valid_int?(first_seq_num, 32),
61+
if(first_seq_num == nil or ApplicationTags.valid_int?(first_seq_num, 32),
6262
do: :ok,
6363
else: {:error, :invalid_first_sequence_number_value}
6464
) do
@@ -92,7 +92,9 @@ defmodule BACnet.Protocol.Services.Ack.ReadRangeAck do
9292

9393
def to_apdu(%__MODULE__{} = ack, invoke_id) when invoke_id in 0..255 do
9494
with :ok <-
95-
if(ApplicationTags.valid_int?(ack.first_sequence_number, 32),
95+
if(
96+
ack.first_sequence_number == nil or
97+
ApplicationTags.valid_int?(ack.first_sequence_number, 32),
9698
do: :ok,
9799
else: {:error, :invalid_first_sequence_number_value}
98100
),

lib/bacnet/stack/transport/mstp_transport.ex

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2797,17 +2797,29 @@ if Code.ensure_loaded?(Circuits.UART) do
27972797
@spec update_received_statistics(frame_type() | :invalid_frame, State.t()) :: State.t()
27982798
@spec update_sent_statistics(frame_type(), State.t()) :: State.t()
27992799
if Mix.env() in [:dev, :test] do
2800-
defp update_received_statistics(type, %State{} = state) when is_atom(type) do
2800+
defp update_received_statistics(type, %State{} = state)
2801+
when is_atom(type) or
2802+
(is_tuple(type) and tuple_size(type) == 2 and elem(type, 0) == :proprietary and
2803+
is_integer(elem(type, 1))) do
28012804
update_in(state, [Access.key(:statistics), :received, type], fn num ->
28022805
(num || 0) + 1
28032806
end)
28042807
end
28052808

2806-
defp update_sent_statistics(type, %State{} = state) when is_atom(type) do
2809+
# Ignore invalid types (dont let it crash us)
2810+
defp update_received_statistics(_type, %State{} = state), do: state
2811+
2812+
defp update_sent_statistics(type, %State{} = state)
2813+
when is_atom(type) or
2814+
(is_tuple(type) and tuple_size(type) == 2 and elem(type, 0) == :proprietary and
2815+
is_integer(elem(type, 1))) do
28072816
update_in(state, [Access.key(:statistics), :sent, type], fn num ->
28082817
(num || 0) + 1
28092818
end)
28102819
end
2820+
2821+
# Ignore invalid types (dont let it crash us)
2822+
defp update_sent_statistics(_type, %State{} = state), do: state
28112823
else
28122824
defp update_received_statistics(_type, %State{} = state), do: state
28132825
defp update_sent_statistics(_type, %State{} = state), do: state

lib/bacnet/stack/trend_logger.ex

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ defmodule BACnet.Stack.TrendLogger do
6868
alias BACnet.Protocol.ObjectTypes.EventLog
6969
alias BACnet.Protocol.ObjectTypes.TrendLog
7070
alias BACnet.Protocol.ObjectTypes.TrendLogMultiple
71+
alias BACnet.Protocol.PriorityArray
7172
alias BACnet.Protocol.PropertyValue
7273
alias BACnet.Protocol.Services.ConfirmedCovNotification
7374
alias BACnet.Protocol.Services.ConfirmedEventNotification
@@ -1710,14 +1711,26 @@ defmodule BACnet.Stack.TrendLogger do
17101711
{:ok, term} -> {:ok, {:fun, term}}
17111712
:error -> :cont
17121713
end),
1714+
prop_type_map = mod.get_properties_type_map(),
17131715
:cont <-
1714-
(case mod.get_properties_type_map() do
1716+
(case prop_type_map do
17151717
%{^property => type} ->
17161718
# TODO: Support for more types (i.e. literal - how?)
17171719
case type do
17181720
{:constant, term} ->
17191721
{:ok, {:const, Constants.by_name_atom(term, value)}}
17201722

1723+
# Needs to be explicitely handled (according to Elixir typechecker)
1724+
{:struct, Encoding} ->
1725+
{:ok, {:fun, &Encoding.to_encoding/1}}
1726+
1727+
# Needs to be explicitely handled (according to Elixir typechecker)
1728+
{:struct, PriorityArray} ->
1729+
case Map.fetch(prop_type_map, :present_value) do
1730+
{:ok, type} -> {:ok, {:type, type}}
1731+
:error -> create_invalid_datatype_error()
1732+
end
1733+
17211734
{:struct, term} ->
17221735
{:ok, {:fun, fn value -> term.encode(value) end}}
17231736

0 commit comments

Comments
 (0)