Skip to content

Commit

Permalink
fix(developer): projects 2.0 internal path enumeration
Browse files Browse the repository at this point in the history
Restricts enumeration of files for the project to the project folder and
the SourcePath folder. This prevents problems where a project may be in
a folder with many subfolders which would take a long time to enumerate,
and avoids confusion where there are source-type files in other folders.

At the same time, sorts out forward slash vs backslash in paths. While
forward slash works in many scenarios, there are several filename
manipulation functions, such as ExpandFileName, which would build valid
but non-optimal paths when forward slashes were encountered, which
cascaded into files appearing to be different and presentation issues.
  • Loading branch information
mcdurdin committed Nov 16, 2023
1 parent 8ebb725 commit 55c0c6f
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 30 deletions.
8 changes: 7 additions & 1 deletion common/windows/delphi/general/utildir.pas
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,19 @@ function KGetTempPath: string;

function GetLongFileName(const fname: string): string;

function DosSlashes(const filename: string): string;

implementation

uses
System.StrUtils,
System.SysUtils,
Winapi.Windows;


function DosSlashes(const filename: string): string;
begin
Result := ReplaceStr(filename, '/', '\');
end;

function DirectoryEmpty(dir: WideString): Boolean;
var
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ TProjectOptions = class
ProjectType: ptKeyboard;
Version: pv10
), ( // 2.0
BuildPath: '$PROJECTPATH/build';
SourcePath: '$PROJECTPATH/source';
BuildPath: '$PROJECTPATH\build';
SourcePath: '$PROJECTPATH\source';
CompilerWarningsAsErrors: False;
WarnDeprecatedCode: True;
CheckFilenameConventions: False;
Expand Down Expand Up @@ -621,8 +621,8 @@ function TProjectFile.IsSourceFile: Boolean;
Exit(True);

// Only return true if the file is directly in the ProjectOptions.SourcePath folder
SourcePath := ReplaceStr(IncludeTrailingPathDelimiter(FProject.ResolveProjectPath(FProject.Options.SourcePath)), '/', '\');
FilePath := ReplaceStr(ExtractFilePath(FFileName), '/', '\');
SourcePath := DosSlashes(FProject.ResolveProjectPath(FProject.Options.SourcePath));
FilePath := DosSlashes(ExtractFilePath(FFileName));
Result := SameFileName(SourcePath, FilePath);
end;

Expand Down Expand Up @@ -662,7 +662,7 @@ procedure TProjectFile.Save(node: IXMLNode); // I4698
begin
node.AddChild('ID').NodeValue := FID;
node.AddChild('Filename').NodeValue := ExtractFileName(FFileName);
node.AddChild('Filepath').NodeValue := ExtractRelativePath(FProject.FileName, FFileName);
node.AddChild('Filepath').NodeValue := ExtractRelativePath(FProject.FileName, DosSlashes(FFileName));
node.AddChild('FileVersion').NodeValue := FFileVersion; // I4701

// Note: FileType is only ever written in Delphi code; it is used by xsl
Expand Down Expand Up @@ -978,18 +978,21 @@ function TProject.IsDefaultProject(Version: TProjectVersion): Boolean;
///
function TProject.PopulateFiles: Boolean;
var
ProjectPath: string;
SourcePath, ProjectPath: string;
begin
if FOptions.Version <> pv20 then
raise EProjectLoader.Create('PopulateFiles can only be called on a v2.0 project');

FFiles.Clear;

ProjectPath := ExtractFilePath(FileName);
ProjectPath := ExpandFileName(ExtractFilePath(FileName));
if not DirectoryExists(ProjectPath) then
Exit(False);

PopulateFolder(ProjectPath);
SourcePath := ResolveProjectPath(FOptions.SourcePath);
if not SameFileName(ProjectPath, SourcePath) and DirectoryExists(SourcePath) then
PopulateFolder(SourcePath);

Result := True;
end;
Expand All @@ -999,7 +1002,7 @@ procedure TProject.PopulateFolder(const path: string);
ff: string;
f: TSearchRec;
begin
if FindFirst(path + '*', faDirectory, f) = 0 then
if FindFirst(path + '*', 0, f) = 0 then
begin
repeat
ff := path + f.Name;
Expand All @@ -1009,12 +1012,6 @@ procedure TProject.PopulateFolder(const path: string);
Continue;
end;

if (f.Attr and faDirectory) = faDirectory then
begin
PopulateFolder(ff + '\');
Continue;
end;

CreateProjectFile(Self, ff, nil);
until FindNext(f) <> 0;
System.SysUtils.FindClose(f);
Expand Down Expand Up @@ -1231,7 +1228,7 @@ function TProject.GetUserFileName: string;

function TProject.ResolveProjectPath(APath: string): string;
begin
Result := ReplaceText(APath, '$PROJECTPATH', ExtractFileDir(ExpandFileName(FFileName)));
Result := IncludeTrailingPathDelimiter(ReplaceText(APath, '$PROJECTPATH', ExtractFileDir(ExpandFileName(FFileName))));
end;

function TProject.GetTargetFilename10(ATargetFile, ASourceFile, AVersion: string): string; // I4688
Expand All @@ -1256,7 +1253,6 @@ function TProject.GetTargetFilename20(ATargetFile, ASourceFile, AVersion: string
Exit(ExtractFilePath(ExpandFileName(ASourceFile)) + ExtractFileName(ATargetFile));
end;

Result := IncludeTrailingPathDelimiter(Result);
Result := ResolveProjectPath(Result);
Result := Result + ExtractFileName(ATargetFile);
end;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ implementation
Keyman.Developer.System.Project.ProjectFiles,
Keyman.Developer.System.Project.ProjectFileType,

utildir,
utilfiletypes;

{ TProjectLoader }
Expand Down Expand Up @@ -131,10 +132,10 @@ procedure TProjectLoader.LoadProjectFromFile;
FProject.Options.Assign(DefaultProjectOptions[FProject.Options.Version]);

if not VarIsNull(node.ChildValues['BuildPath']) then
FProject.Options.BuildPath := VarToStr(node.ChildValues['BuildPath']);
FProject.Options.BuildPath := DosSlashes(VarToStr(node.ChildValues['BuildPath']));

if not VarIsNull(node.ChildValues['SourcePath']) then
FProject.Options.SourcePath := VarToStr(node.ChildValues['SourcePath']);
FProject.Options.SourcePath := DosSlashes(VarToStr(node.ChildValues['SourcePath']));

if not VarIsNull(node.ChildValues['CompilerWarningsAsErrors']) then
FProject.Options.CompilerWarningsAsErrors := node.ChildValues['CompilerWarningsAsErrors'];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
(*
Name: Keyman.Developer.UI.Project.UfrmProjectSettings
Copyright: Copyright (C) SIL International.
Documentation:
Description:
Documentation:
Description:
Create Date: 4 May 2015
Modified Date: 24 Aug 2015
Authors: mcdurdin
Related Files:
Dependencies:
Related Files:
Dependencies:
Bugs:
Todo:
Notes:
Bugs:
Todo:
Notes:
History: 04 May 2015 - mcdurdin - I4688 - V9.0 - Add build path to project settings
24 Aug 2015 - mcdurdin - I4865 - Add treat hints and warnings as errors into project
24 Aug 2015 - mcdurdin - I4866 - Add warn on deprecated features to project and compile
*)
unit Keyman.Developer.UI.Project.UfrmProjectSettings20; // I4688

Expand Down Expand Up @@ -54,12 +54,13 @@ implementation
{$R *.dfm}

uses
Keyman.Developer.System.Project.Project;
Keyman.Developer.System.Project.Project,
utildir;

procedure TfrmProjectSettings20.cmdOKClick(Sender: TObject);
begin
FGlobalProject.Options.BuildPath := Trim(editOutputPath.Text);
FGlobalProject.Options.SourcePath := Trim(editSourcePath.Text);
FGlobalProject.Options.BuildPath := Trim(DosSlashes(editOutputPath.Text));
FGlobalProject.Options.SourcePath := Trim(DosSlashes(editSourcePath.Text));
FGlobalProject.Options.SkipMetadataFiles := not chkBuildMetadataFiles.Checked;
FGlobalProject.Options.CompilerWarningsAsErrors := chkCompilerWarningsAsErrors.Checked; // I4865
FGlobalProject.Options.WarnDeprecatedCode := chkWarnDeprecatedCode.Checked; // I4866
Expand Down

0 comments on commit 55c0c6f

Please sign in to comment.