Skip to content

Commit c25dab1

Browse files
committed
提供批量格式化和批量诊断,批量操作也允许自动检测配置
1 parent 2d43a90 commit c25dab1

File tree

6 files changed

+277
-49
lines changed

6 files changed

+277
-49
lines changed

CodeFormat/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ target_sources(CodeFormat
1515
PUBLIC
1616
${CodeFormat_SOURCE_DIR}/src/CodeFormat.cpp
1717
${CodeFormat_SOURCE_DIR}/src/LuaFormat.cpp
18+
${CodeFormat_SOURCE_DIR}/src/LuaWorkspaceFormat.cpp
1819
)
1920

2021
target_link_libraries(CodeFormat CodeService Util)

CodeFormat/src/CodeFormat.cpp

Lines changed: 82 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "Util/format.h"
99
#include "CodeService/LuaFormatter.h"
1010
#include "Util/CommandLine.h"
11+
#include "LuaWorkspaceFormat.h"
1112

1213
// https://stackoverflow.com/questions/1598985/c-read-binary-stdin
1314
#ifdef _WIN32
@@ -26,81 +27,119 @@ int main(int argc, char** argv)
2627

2728
cmd.AddTarget("format")
2829
.Add<std::string>("file", "f", "Specify the input file")
30+
.Add<std::string>("workspace", "w",
31+
"Specify workspace directory perform batch formatting")
2932
.Add<int>("stdin", "i", "Read from stdin and specify read size")
3033
.Add<std::string>("config", "c",
3134
"Specify .editorconfig file, it decides on the effect of formatting")
32-
.Add<std::string>("detect-config-root", "d",
33-
"Set the root directory for automatic detection of config,\n"
34-
" If this option is set, the config option has no effect ")
35+
.Add<bool>("detect-config", "d",
36+
"Configuration will be automatically detected,\n"
37+
" If this option is set, the config option has no effect ")
3538
.Add<std::string>("outfile", "o",
3639
"Specify output file")
3740
.EnableKeyValueArgs();
3841
cmd.AddTarget("check")
3942
.Add<std::string>("file", "f", "Specify the input file")
43+
.Add<std::string>("workspace", "w",
44+
"Specify workspace directory perform batch checking")
4045
.Add<std::string>("config", "c",
4146
"Specify editorconfig file, it decides on the effect of formatting or diagnosis")
42-
.Add<bool>("diagnosis-as-error", "diagnosis-as-error", "if exist error or diagnosis info , return -1");
47+
.Add<bool>("detect-config", "d",
48+
"Configuration will be automatically detected,\n"
49+
" If this option is set, the config option has no effect")
50+
.Add<bool>("diagnosis-as-error", "DAE", "if exist error or diagnosis info , return -1")
51+
.EnableKeyValueArgs();
52+
4353

4454
if (!cmd.Parse(argc, argv))
4555
{
4656
cmd.PrintUsage();
4757
return -1;
4858
}
4959

50-
std::shared_ptr<LuaParser> parser = nullptr;
51-
auto luaFormat = std::make_shared<LuaFormat>();
52-
if (cmd.HasOption("file"))
60+
if (!cmd.HasOption("workspace"))
5361
{
54-
if(!luaFormat->SetInputFile(cmd.Get<std::string>("file")))
62+
auto luaFormat = std::make_shared<LuaFormat>();
63+
if (cmd.HasOption("file"))
5564
{
56-
std::cerr << format("Can not find file {}", cmd.Get<std::string>("file")) << std::endl;
57-
return -1;
65+
if (!luaFormat->SetInputFile(cmd.Get<std::string>("file")))
66+
{
67+
std::cerr << format("Can not find file {}", cmd.Get<std::string>("file")) << std::endl;
68+
return -1;
69+
}
5870
}
59-
}
60-
else if (cmd.HasOption("stdin"))
61-
{
62-
SET_BINARY_MODE();
63-
std::size_t size = cmd.Get<int>("stdin");
64-
if(!luaFormat->ReadFromStdin(size))
71+
else if (cmd.HasOption("stdin"))
6572
{
73+
SET_BINARY_MODE();
74+
std::size_t size = cmd.Get<int>("stdin");
75+
if (!luaFormat->ReadFromStdin(size))
76+
{
77+
return -1;
78+
}
79+
}
80+
else
81+
{
82+
std::cerr << "not special input file" << std::endl;
6683
return -1;
6784
}
68-
}
69-
else
70-
{
71-
std::cerr << "not special input file" << std::endl;
72-
return -1;
73-
}
7485

75-
if (cmd.HasOption("output"))
76-
{
77-
luaFormat->SetOutputFile(cmd.Get<std::string>("output"));
78-
}
86+
if (cmd.HasOption("output"))
87+
{
88+
luaFormat->SetOutputFile(cmd.Get<std::string>("output"));
89+
}
7990

80-
if (cmd.HasOption("detect-config-root"))
81-
{
82-
luaFormat->AutoDetectConfigRoot(cmd.Get<std::string>("detect-config-root"));
83-
}
84-
else if(cmd.HasOption("config"))
85-
{
86-
luaFormat->SetConfigPath(cmd.Get<std::string>("config"));
87-
}
91+
if (cmd.Get<bool>("detect-config"))
92+
{
93+
luaFormat->AutoDetectConfig();
94+
}
95+
else if (cmd.HasOption("config"))
96+
{
97+
luaFormat->SetConfigPath(cmd.Get<std::string>("config"));
98+
}
8899

89-
luaFormat->SetDefaultOptions(cmd.GetKeyValueOptions());
100+
luaFormat->SetDefaultOptions(cmd.GetKeyValueOptions());
90101

91-
if (cmd.GetTarget() == "format")
92-
{
93-
if(!luaFormat->Reformat())
102+
if (cmd.GetTarget() == "format")
94103
{
95-
std::cerr << format("Exist lua syntax error") << std::endl;
96-
return -1;
104+
if (!luaFormat->Reformat())
105+
{
106+
std::cerr << format("Exist lua syntax error") << std::endl;
107+
return -1;
108+
}
109+
}
110+
else if (cmd.GetTarget() == "check")
111+
{
112+
if (!luaFormat->Check() && cmd.Get<bool>("diagnosis-as-error"))
113+
{
114+
return -1;
115+
}
97116
}
98117
}
99-
else if (cmd.GetTarget() == "check")
118+
else
100119
{
101-
if (!luaFormat->Check() && cmd.Get<bool>("diagnosis-as-error"))
120+
LuaWorkspaceFormat workspaceFormat(cmd.Get<std::string>("workspace"));
121+
122+
if(cmd.Get<bool>("detect-config"))
102123
{
103-
return -1;
124+
workspaceFormat.SetAutoDetectConfig(true);
125+
}
126+
else if(cmd.HasOption("config"))
127+
{
128+
workspaceFormat.SetConfigPath(cmd.Get<std::string>("config"));
129+
}
130+
131+
workspaceFormat.SetKeyValues(cmd.GetKeyValueOptions());
132+
133+
if(cmd.GetTarget() == "format")
134+
{
135+
workspaceFormat.ReformatWorkspace();
136+
}
137+
else if(cmd.GetTarget() == "check")
138+
{
139+
if(!workspaceFormat.CheckWorkspace() && cmd.Get<bool>("diagnosis-as-error"))
140+
{
141+
return -1;
142+
}
104143
}
105144
}
106145
return 0;

CodeFormat/src/LuaFormat.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,20 @@ bool IsSubRelative(std::filesystem::path& path, std::filesystem::path base)
5252
return !relativeString.starts_with(".");
5353
}
5454

55-
void LuaFormat::AutoDetectConfigRoot(std::string_view root)
55+
void LuaFormat::AutoDetectConfig()
5656
{
5757
if (_inputFile.empty())
5858
{
5959
return;
6060
}
61-
std::filesystem::path workspace(root);
61+
std::filesystem::path workspace(std::filesystem::current_path());
6262
std::filesystem::path inputPath(_inputFile);
6363
if (!IsSubRelative(inputPath, workspace))
6464
{
6565
return;
6666
}
6767

68-
auto directory = inputPath.parent_path();
68+
auto directory = absolute(inputPath.parent_path());
6969
while (IsSubRelative(directory, workspace))
7070
{
7171
auto editorconfigPath = directory / ".editorconfig";
@@ -91,6 +91,11 @@ void LuaFormat::SetConfigPath(std::string_view config)
9191
}
9292
}
9393

94+
void LuaFormat::SetOptions(std::shared_ptr<LuaCodeStyleOptions> options)
95+
{
96+
_options = options;
97+
}
98+
9499
void LuaFormat::SetDefaultOptions(std::map<std::string, std::string, std::less<>>& keyValues)
95100
{
96101
_defaultOptions.swap(keyValues);

CodeFormat/src/LuaFormat.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,19 @@ class LuaFormat
2020

2121
void SetOutputFile(std::string_view path);
2222

23-
void AutoDetectConfigRoot(std::string_view root);
23+
void AutoDetectConfig();
2424

2525
void SetConfigPath(std::string_view config);
2626

27+
void SetOptions(std::shared_ptr<LuaCodeStyleOptions> options);
28+
2729
void SetDefaultOptions(std::map<std::string, std::string, std::less<>>& keyValues);
2830

2931
bool Reformat();
3032

3133
bool Check();
3234

3335
void DiagnosisInspection(std::string_view message, TextRange range, std::shared_ptr<LuaFile> file);
34-
35-
3636
private:
3737
std::string _inputFile;
3838
std::string _outFile;
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#include "LuaWorkspaceFormat.h"
2+
#include <iostream>
3+
#include "Util/format.h"
4+
#include "Util/FileFinder.h"
5+
6+
LuaWorkspaceFormat::LuaWorkspaceFormat(std::string_view workspace)
7+
: _workspace(absolute(std::filesystem::path(workspace))),
8+
_autoDetectConfig(false),
9+
_defaultOptions(std::make_shared<LuaCodeStyleOptions>())
10+
{
11+
}
12+
13+
bool LuaWorkspaceFormat::SetConfigPath(std::string_view config)
14+
{
15+
auto editorconfig = LuaEditorConfig::LoadFromFile(std::string(config));
16+
if (!editorconfig)
17+
{
18+
return false;
19+
}
20+
_editorConfigVector.push_back({
21+
_workspace.string(), editorconfig
22+
});
23+
_editorConfigVector.back().second->SetWorkspace(_workspace.string());
24+
return true;
25+
}
26+
27+
void LuaWorkspaceFormat::SetAutoDetectConfig(bool detect)
28+
{
29+
_autoDetectConfig = detect;
30+
}
31+
32+
void LuaWorkspaceFormat::SetKeyValues(std::map<std::string, std::string, std::less<>>& keyValues)
33+
{
34+
if (!keyValues.empty())
35+
{
36+
LuaEditorConfig::ParseFromSection(_defaultOptions, keyValues);
37+
}
38+
}
39+
40+
void LuaWorkspaceFormat::ReformatWorkspace()
41+
{
42+
if (_autoDetectConfig)
43+
{
44+
CollectEditorconfig();
45+
}
46+
47+
FileFinder finder(_workspace);
48+
finder.AddFindExtension(".lua");
49+
finder.AddFindExtension(".lua.txt");
50+
finder.AddIgnoreDirectory(".git");
51+
finder.AddIgnoreDirectory(".github");
52+
finder.AddIgnoreDirectory(".svn");
53+
finder.AddIgnoreDirectory(".idea");
54+
finder.AddIgnoreDirectory(".vs");
55+
finder.AddIgnoreDirectory(".vscode");
56+
57+
auto files = finder.FindFiles();
58+
for (auto& file : files)
59+
{
60+
LuaFormat luaFormat;
61+
luaFormat.SetInputFile(file);
62+
luaFormat.SetOptions(GetOptions(file));
63+
luaFormat.SetOutputFile(file);
64+
if (luaFormat.Reformat())
65+
{
66+
std::cerr << format("reformat {} succeed.", file) << std::endl;
67+
}
68+
else
69+
{
70+
std::cerr << format("reformat {} fail.", file) << std::endl;
71+
}
72+
}
73+
}
74+
75+
bool LuaWorkspaceFormat::CheckWorkspace()
76+
{
77+
if (_autoDetectConfig)
78+
{
79+
CollectEditorconfig();
80+
}
81+
82+
FileFinder finder(_workspace);
83+
finder.AddFindExtension(".lua");
84+
finder.AddFindExtension(".lua.txt");
85+
finder.AddIgnoreDirectory(".git");
86+
finder.AddIgnoreDirectory(".github");
87+
finder.AddIgnoreDirectory(".svn");
88+
finder.AddIgnoreDirectory(".idea");
89+
finder.AddIgnoreDirectory(".vs");
90+
finder.AddIgnoreDirectory(".vscode");
91+
92+
auto files = finder.FindFiles();
93+
bool ret = true;
94+
for (auto& file : files)
95+
{
96+
LuaFormat luaFormat;
97+
luaFormat.SetInputFile(file);
98+
luaFormat.SetOptions(GetOptions(file));
99+
ret &= luaFormat.Check();
100+
}
101+
102+
return ret;
103+
}
104+
105+
void LuaWorkspaceFormat::CollectEditorconfig()
106+
{
107+
FileFinder finder(_workspace);
108+
finder.AddFindExtension(".editorconfig");
109+
finder.AddIgnoreDirectory(".git");
110+
finder.AddIgnoreDirectory(".github");
111+
finder.AddIgnoreDirectory(".svn");
112+
finder.AddIgnoreDirectory(".idea");
113+
finder.AddIgnoreDirectory(".vs");
114+
finder.AddIgnoreDirectory(".vscode");
115+
116+
auto files = finder.FindFiles();
117+
118+
for (auto& file : files)
119+
{
120+
auto editorconfig = LuaEditorConfig::LoadFromFile(file);
121+
122+
std::filesystem::path filePath(file);
123+
124+
if (editorconfig == nullptr)
125+
{
126+
continue;
127+
}
128+
129+
_editorConfigVector.push_back({
130+
filePath.parent_path().string(), editorconfig
131+
});
132+
_editorConfigVector.back().second->SetWorkspace(filePath.parent_path().string());
133+
}
134+
}
135+
136+
std::shared_ptr<LuaCodeStyleOptions> LuaWorkspaceFormat::GetOptions(std::string_view path)
137+
{
138+
std::size_t matchLength = 0;
139+
std::shared_ptr<LuaCodeStyleOptions> options = _defaultOptions;
140+
for (auto it = _editorConfigVector.begin(); it != _editorConfigVector.end(); it++)
141+
{
142+
if (path.starts_with(it->first) && it->first.size() > matchLength)
143+
{
144+
matchLength = it->first.size();
145+
options = it->second->Generate(path);
146+
}
147+
}
148+
149+
return options;
150+
}

0 commit comments

Comments
 (0)