Skip to content

Commit 19e94b0

Browse files
committed
Update: Preparing redub to receive target configuration
1 parent fcca3d8 commit 19e94b0

9 files changed

Lines changed: 284 additions & 253 deletions

File tree

source/redub/api.d

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ ProjectDetails resolveDependencies(
792792
DUB_FORCE = either(DUB_FORCE, redub.parsers.environment.str(resolveInfo.force));
793793
}
794794
redub.parsers.environment.setupBuildEnvironmentVariables(dubVars);
795-
CompilationInfo cInfo = CompilationInfo(compiler.d.getCompilerString, compiler.c.getCompilerString, cDetails.arch, osFromArch(cDetails.arch), isaFromArch(cDetails.arch), compiler.d.bin);
795+
CompilationInfo cInfo = CompilationInfo(compiler, cDetails.arch);
796796
if(proj.workingDir == null)
797797
{
798798
import std.file;
@@ -807,8 +807,6 @@ ProjectDetails resolveDependencies(
807807
BuildRequirements.Configuration(proj.configuration, false),
808808
proj.subPackage,
809809
proj.recipe,
810-
true,
811-
null,
812810
cDetails.useExistingObj
813811
);
814812
else
@@ -818,9 +816,6 @@ ProjectDetails resolveDependencies(
818816
BuildRequirements.Configuration(proj.configuration, false),
819817
proj.subPackage,
820818
proj.recipe,
821-
null,
822-
true,
823-
null,
824819
cDetails.useExistingObj,
825820
proj.isDescribeOnly
826821
);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module redub.parsers.adapter.json_cache;
2+
public import hip.data.json;
3+
4+
private __gshared JSONValue[string] jsonCache;
5+
6+
/**
7+
* Params:
8+
* filePath = Uses filePath as the file data for parsing. Better API
9+
* Returns: Same as parseJSONCache
10+
*/
11+
JSONValue parseJSONCached(string filePath)
12+
{
13+
import std.file;
14+
return parseJSONCached(filePath, std.file.readText(filePath));
15+
}
16+
17+
/**
18+
* Optimization to be used when dealing with subPackages.
19+
* Params:
20+
* filePath = The path to use for getting it from cache, used simply as a key to the jsonCache
21+
* fileData = The actual content to be used for parsing
22+
*/
23+
JSONValue parseJSONCached(string filePath, string fileData)
24+
{
25+
synchronized
26+
{
27+
JSONValue* cached = filePath in jsonCache;
28+
if(cached) return *cached;
29+
jsonCache[filePath] = parseJSON(fileData, true);
30+
if(jsonCache[filePath].hasErrorOccurred)
31+
throw new Exception(jsonCache[filePath].error);
32+
return jsonCache[filePath];
33+
}
34+
}
35+
36+
/**
37+
* This function was created since on libraries, they may be reusing multiple times and thus
38+
* storing the cache between runs may trigger errors.
39+
*/
40+
public void clearJsonCache()
41+
{
42+
jsonCache = null;
43+
}

source/redub/parsers/adapter/sdl.d

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module redub.parsers.adapter.sdl;
2+
public import redub.buildapi;
3+
import hip.data.json;
4+
5+
JSONValue sdlToJSONCache(string filePath)
6+
{
7+
import std.file;
8+
return sdlToJSONCache(filePath, readText(filePath));
9+
}
10+
11+
private JSONValue[string] sdlJsonCache;
12+
JSONValue sdlToJSONCache(string filePath, string fileData)
13+
{
14+
import dub_sdl_to_json;
15+
JSONValue* cached = filePath in sdlJsonCache;
16+
if(cached) return *cached;
17+
JSONValue ret = sdlToJSON(parseSDL(filePath, fileData));
18+
if(ret.hasErrorOccurred)
19+
throw new Exception(ret.error);
20+
return sdlJsonCache[filePath] = ret;
21+
}
22+
23+
void clearSdlRecipeCache(){sdlJsonCache = null;}

source/redub/parsers/automatic.d

Lines changed: 126 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,98 @@ import redub.logging;
33
public import redub.buildapi;
44
public import std.system;
55
static import redub.parsers.json;
6-
static import redub.parsers.sdl;
6+
static import redub.parsers.adapter.sdl;
77
static import redub.parsers.environment;
88
import redub.command_generators.commons;
99
import redub.tree_generators.dub;
10+
import hip.data.json;
11+
12+
/**
13+
* Parses an initial directory, not recursively. Currently only .sdl and .json are parsed.
14+
* After the parse happens, it also partially finishes the requirements by using a generalized fix
15+
* for after the parsing stage.
16+
* Params:
17+
* projectWorkingDir = Optional working dir. What is the root being considered for the recipe file
18+
* cInfo = Important compilation info for that project
19+
* subConfiguration = Sub configuration to use
20+
* subPackage = Optional sub package
21+
* recipe = Optional recipe to read. Its path is not used as root.
22+
* version = The actual version of that project, may be null on root
23+
* useExistingObj = Makes the project output dependencies if it is a root project. Disabled by default since compilation may be way slower
24+
* isDescribeOnly = Do not execute preGenerate commands when true
25+
* Returns: The build requirements to the project. Not recursive.
26+
*/
27+
BuildRequirements parseProject(
28+
string projectWorkingDir,
29+
ref CompilationInfo cInfo,
30+
BuildRequirements.Configuration subConfiguration,
31+
string subPackage,
32+
string recipe,
33+
bool useExistingObj = false,
34+
bool isDescribeOnly = false
35+
)
36+
{
37+
import redub.parsers.base;
38+
import std.path;
39+
import std.file;
40+
import redub.package_searching.entry;
41+
string projectFile = findEntryProjectFile(projectWorkingDir, recipe);
42+
if(!projectFile)
43+
throw new Exception("Directory '"~projectWorkingDir~"' has no recipe or does not exists.");
44+
45+
if(getLogLevel() >= LogLevel.verbose)
46+
{
47+
import std.string;
48+
if(projectFile.startsWith(projectWorkingDir))
49+
vlog("Parsing ", projectFile);
50+
else
51+
vlog("Parsing ", projectFile, " at ", projectWorkingDir);
52+
if(subPackage)
53+
vlog("\tSubPackage: ", subPackage);
54+
if(subConfiguration.name)
55+
vlog("\tConfiguration: ", subConfiguration.name);
56+
}
57+
58+
JSONValue projectJSON = getProjectJSON(projectFile, projectWorkingDir);
59+
return parseProject(projectJSON, projectWorkingDir, cInfo, subConfiguration, subPackage, useExistingObj, isDescribeOnly);
60+
}
61+
62+
/**
63+
* Parses an initial directory, not recursively. Currently only .sdl and .json are parsed.
64+
* After the parse happens, it also partially finishes the requirements by using a generalized fix
65+
* for after the parsing stage.
66+
* Params:
67+
* projectWorkingDir = Optional working dir. What is the root being considered for the recipe file
68+
* cInfo = Important compilation info for that project
69+
* subConfiguration = Sub configuration to use
70+
* subPackage = Optional sub package
71+
* version = The actual version of that project, may be null on root
72+
* useExistingObj = Makes the project output dependencies if it is a root project. Disabled by default since compilation may be way slower
73+
* isDescribeOnly = Do not execute preGenerate commands when true
74+
* Returns: The build requirements to the project. Not recursive.
75+
*/
76+
BuildRequirements parseProject(
77+
JSONValue projectJSON,
78+
string projectWorkingDir,
79+
ref CompilationInfo cInfo,
80+
BuildRequirements.Configuration subConfiguration,
81+
string subPackage,
82+
bool useExistingObj = false,
83+
bool isDescribeOnly = false
84+
)
85+
{
86+
import redub.parsers.base;
87+
88+
ParseConfig cfg = getParseConfig(projectWorkingDir, cInfo, null, null, subConfiguration, subPackage, null, isDescribeOnly);
89+
//Get target
90+
91+
// cfg = redub.parsers.json.getTarget(projectJSON, null, cfg);
92+
BuildConfiguration pending;
93+
BuildRequirements req = redub.parsers.json.parse(projectJSON, cfg, pending, true);
94+
return postProcessBuildRequirements(req, pending, cInfo, true, useExistingObj);
95+
}
96+
97+
1098

1199
/**
12100
* Parses an initial directory, not recursively. Currently only .sdl and .json are parsed.
@@ -25,9 +113,9 @@ import redub.tree_generators.dub;
25113
* isDescribeOnly = Do not execute preGenerate commands when true
26114
* Returns: The build requirements to the project. Not recursive.
27115
*/
28-
BuildRequirements parseProject(
116+
BuildRequirements parseProjectCommon(
29117
string projectWorkingDir,
30-
CompilationInfo cInfo,
118+
const ref CompilationInfo cInfo,
31119
BuildRequirements.Configuration subConfiguration,
32120
string subPackage,
33121
string recipe,
@@ -38,7 +126,7 @@ BuildRequirements parseProject(
38126
bool isDescribeOnly = false
39127
)
40128
{
41-
import std.path;
129+
import redub.parsers.base;
42130
import std.file;
43131
import redub.package_searching.entry;
44132
string projectFile = findEntryProjectFile(projectWorkingDir, recipe);
@@ -60,15 +148,29 @@ BuildRequirements parseProject(
60148
}
61149

62150
BuildConfiguration pending;
151+
ParseConfig cfg = getParseConfig(projectWorkingDir, cInfo, null, version_, subConfiguration, subPackage, parentName, isDescribeOnly);
152+
153+
JSONValue parseData = getProjectJSON(projectFile, projectWorkingDir);
154+
155+
req = redub.parsers.json.parse(parseData, cfg, pending, false);
156+
return postProcessBuildRequirements(req, pending, cInfo, isRoot, useExistingObj);
157+
}
158+
159+
JSONValue getProjectJSON(string projectFile, string projectWorkingDir)
160+
{
161+
import std.path;
63162
switch(extension(projectFile))
64163
{
65-
case ".sdl": req = redub.parsers.sdl.parse(projectFile, projectWorkingDir, cInfo, null, version_, subConfiguration, subPackage, pending, parentName, isDescribeOnly, isRoot); break;
66-
case ".json": req = redub.parsers.json.parse(projectFile, projectWorkingDir, cInfo, null, version_, subConfiguration, subPackage, pending, parentName, isDescribeOnly, isRoot); break;
164+
case ".sdl":
165+
return redub.parsers.adapter.sdl.sdlToJSONCache(projectFile);
166+
case ".json":
167+
import redub.parsers.adapter.json_cache;
168+
return parseJSONCached(projectFile);
67169
default: throw new Exception("Unsupported project type "~projectFile~" at dir "~projectWorkingDir);
68170
}
69-
return postProcessBuildRequirements(req, pending, cInfo, isRoot, useExistingObj);
70171
}
71172

173+
72174
/**
73175
* Used mostly to check the name of a package in the local directory and decide what to build
74176
* Params:
@@ -83,10 +185,24 @@ string getPackageName(string projectWorkingDir, string recipe)
83185
string projectFile = findEntryProjectFile(projectWorkingDir, recipe);
84186
if(!projectFile)
85187
throw new Exception("Directory '"~projectWorkingDir~"' has no recipe or does not exists.");
188+
189+
JSONValue parseData;
190+
bool hasInitData;
191+
86192
switch(extension(projectFile))
87193
{
88-
case ".sdl": return redub.parsers.sdl.getPackageName(projectFile); break;
89-
case ".json": return redub.parsers.json.getPackageName(projectFile); break;
194+
case ".sdl":
195+
import redub.parsers.adapter.sdl;
196+
parseData = sdlToJSONCache(projectFile);
197+
hasInitData = true;
198+
goto case ".json";
199+
case ".json":
200+
if(!hasInitData)
201+
{
202+
import redub.parsers.adapter.json_cache;
203+
parseData = parseJSONCached(projectFile);
204+
}
205+
return redub.parsers.json.getPackageName(parseData);
90206
default: throw new Exception("Unsupported project type "~projectFile);
91207
}
92208
}
@@ -214,5 +330,5 @@ private void partiallyFinishBuildRequirements(ref BuildRequirements req, BuildCo
214330
void clearRecipeCaches()
215331
{
216332
redub.parsers.json.clearJsonRecipeCache();
217-
redub.parsers.sdl.clearSdlRecipeCache();
333+
redub.parsers.adapter.sdl.clearSdlRecipeCache();
218334
}

source/redub/parsers/base.d

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,30 @@ struct ParseConfig
2828
bool isRoot = false;
2929
}
3030

31+
/**
32+
* projectWorkingDir = Working directory to parse with it
33+
* cInfo = Compilation Info for being used as filters while parsing
34+
* defaultPackageName = Package name to use if no name is found inside the recipe
35+
* version_ = Version of the current one being parsed. May be used to decide which version to use
36+
* subConfiguration = The configuration that was specified in the parsing process
37+
* subPackage = The subpackage that is actually being used
38+
* parentName = Used as metadata
39+
* isDescribeOnly = Whether or not to do a preGenerateRun
40+
*/
41+
ParseConfig getParseConfig(
42+
string projectWorkingDir,
43+
CompilationInfo cInfo,
44+
string defaultPackageName,
45+
string version_,
46+
BuildRequirements.Configuration subConfiguration,
47+
string subPackage,
48+
string parentName,
49+
bool isDescribeOnly = false)
50+
{
51+
return ParseConfig(projectWorkingDir, subConfiguration, subPackage, version_, cInfo, defaultPackageName, ParseSubConfig(null, parentName), preGenerateRun: !isDescribeOnly);
52+
}
53+
54+
3155
///Supplemental information for ParseConfig
3256
struct ParseSubConfig
3357
{

0 commit comments

Comments
 (0)