<commit_before>/**
 * Appcelerator Kroll - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2009 Appcelerator, Inc. All Rights Reserved.
 */
#include "utils.h"

using std::string;
using std::vector;
using std::pair;

namespace UTILS_NS
{
namespace BootUtils
{
	// These are also used in application.cpp
	void ScanBundledComponents(string, vector<SharedComponent>&);

	static void ScanRuntimesAtPath(string, vector<SharedComponent>&);
	static void ScanModulesAtPath(string, vector<SharedComponent>&);
	static void ScanSDKsAtPath(string, vector<SharedComponent>&);
	static void ScanMobileSDKsAtPath(string, vector<SharedComponent>&);
	static void AddToComponentVector(vector<SharedComponent>&, SharedComponent);

	static void AddToComponentVector(vector<SharedComponent>& components,
		SharedComponent c)
	{
		// Avoid adding duplicate components to a component vector
		vector<SharedComponent>::iterator i = components.begin();
		while (i != components.end())
		{
			SharedComponent e = *i++;
			if (e->type == c->type && e->path == c->path)
			{
				return;
			}
		}

		components.push_back(c);
	}

	vector<SharedComponent>& GetInstalledComponents(bool force)
	{
		static std::vector<SharedComponent> installedComponents;
		if (installedComponents.empty() || force)
		{
			installedComponents.clear();
			vector<string>& paths = GetComponentSearchPaths();
			vector<string>::iterator i = paths.begin();
			while (i != paths.end())
			{
				string path(*i++);
				ScanRuntimesAtPath(path, installedComponents);
				ScanSDKsAtPath(path, installedComponents);
				ScanMobileSDKsAtPath(path, installedComponents);
				ScanModulesAtPath(path, installedComponents);
			}

			// Sort components by version here so that the latest version of
			// any component will always be chosen. Use a stable_sort because we
			// want to give preference to components earlier on the search path.
			std::stable_sort(
				installedComponents.begin(),
				installedComponents.end(),
				BootUtils::WeakCompareComponents);
		}
		return installedComponents;
	}

	static void ScanRuntimesAtPath(string path, vector<SharedComponent>& results)
	{
		vector<string> paths;
		SharedComponent c;
		if (!FileUtils::IsDirectory(path))
		{
			return;
		}

		// Read everything that looks like <searchpath>/runtime/<os>/*
		string rtPath(FileUtils::Join(path.c_str(), "runtime", OS_NAME, NULL));
		FileUtils::ListDir(rtPath, paths);

		vector<string>::iterator runtimeVersion = paths.begin();
		while (runtimeVersion != paths.end())
		{
			string version(*runtimeVersion++);
			string fullPath(FileUtils::Join(rtPath.c_str(), version.c_str(), NULL));
			c = KComponent::NewComponent(RUNTIME, "runtime", version, fullPath);
			AddToComponentVector(results, c);
		}
	}

	static void ScanSDKsAtPath(string path, vector<SharedComponent>& results)
	{
		vector<string> paths;
		SharedComponent c;
		if (!FileUtils::IsDirectory(path))
		{
			return;
		}

		// Read everything that looks like <searchpath>/sdk/<os>/*
		string sdkPath(FileUtils::Join(path.c_str(), "sdk", OS_NAME, NULL));
		FileUtils::ListDir(sdkPath, paths);

		vector<string>::iterator sdkVersion = paths.begin();
		while (sdkVersion != paths.end())
		{
			string version(*sdkVersion++);
			string fullPath(FileUtils::Join(
				sdkPath.c_str(), version.c_str(), NULL));
			c = KComponent::NewComponent(SDK, "sdk", version, fullPath);
			AddToComponentVector(results, c);
		}
	}

	static void ScanMobileSDKsAtPath(string path, vector<SharedComponent>& results)
	{
		vector<string> paths;
		SharedComponent c;
		if (!FileUtils::IsDirectory(path))
		{
			return;
		}

		// Read everything that looks like <searchpath>/mobilesdk/<os>/*
		string sdkPath(FileUtils::Join(path.c_str(), "mobilesdk", OS_NAME, NULL));
		FileUtils::ListDir(sdkPath, paths);

		vector<string>::iterator sdkVersion = paths.begin();
		while (sdkVersion != paths.end())
		{
			string version(*sdkVersion++);
			string fullPath(FileUtils::Join(
				sdkPath.c_str(), version.c_str(), NULL));
			c = KComponent::NewComponent(MOBILESDK, "mobilesdk", version, fullPath);
			AddToComponentVector(results, c);
		}
	}

	static void ScanModulesAtPath(string path, vector<SharedComponent>& results)
	{
		vector<string> paths;
		vector<string> subpaths;
		SharedComponent c;

		if (!FileUtils::IsDirectory(path))
		{
			return;
		}

		string namesPath(FileUtils::Join(path.c_str(), "modules", OS_NAME, NULL));

		// Read everything that looks like <searchpath>/modules/<os>/*
		FileUtils::ListDir(namesPath, paths);
		vector<string>::iterator moduleName = paths.begin();
		while (moduleName != paths.end())
		{
			string name(*moduleName++);
			string versionsPath(FileUtils::Join(namesPath.c_str(), name.c_str(), NULL));

			// Read everything that looks like <searchpath>/modules/<os>/<name>/*
			FileUtils::ListDir(versionsPath, subpaths);
			vector<string>::iterator moduleVersion = subpaths.begin();
			while (moduleVersion != subpaths.end())
			{
				string version(*moduleVersion++);
				string fullPath(FileUtils::Join(versionsPath.c_str(), version.c_str(), NULL));
				c = KComponent::NewComponent(MODULE, name, version, fullPath);
				AddToComponentVector(results, c);
			}
		}
	}

	void ScanBundledComponents(string path, vector<SharedComponent>& results)
	{
		vector<string> paths;
		SharedComponent c;

		// Find a directory like <appdir>/runtime/
		string rtPath(FileUtils::Join(path.c_str(), "runtime", NULL));
		if (FileUtils::IsDirectory(rtPath))
		{
			c = KComponent::NewComponent(RUNTIME, "runtime", "", rtPath, true);
			results.push_back(c);
		}

		// Find all directories like <appdir>/modules/*
		string modulesPath(FileUtils::Join(path.c_str(), "modules", NULL));
		FileUtils::ListDir(modulesPath, paths);
		for (size_t i = 0; i < paths.size(); i++)
		{
			string name(paths[i]);
			string path(FileUtils::Join(modulesPath.c_str(), name.c_str(), NULL));
			c = KComponent::NewComponent(MODULE, name, "", path, true);
			results.push_back(c);
		}
	}

	int CompareVersions(string one, string two)
	{
		if (one.empty() && two.empty())
			return 0;
		if (one.empty())
			return -1;
		if (two.empty())
			return 1;

		vector<string> listOne;
		vector<string> listTwo;
		FileUtils::Tokenize(one, listOne, ".");
		FileUtils::Tokenize(two, listTwo, ".");

		size_t min = listOne.size();<commit_msg>Small fixes for component resolution.<commit_after>/**
 * Appcelerator Kroll - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2009 Appcelerator, Inc. All Rights Reserved.
 */
#include "utils.h"

using std::string;
using std::vector;
using std::pair;

namespace UTILS_NS
{
namespace BootUtils
{
	// These are also used in application.cpp
	void ScanBundledComponents(string, vector<SharedComponent>&);

	static void ScanRuntimesAtPath(string, vector<SharedComponent>&);
	static void ScanModulesAtPath(string, vector<SharedComponent>&);
	static void ScanSDKsAtPath(string, vector<SharedComponent>&);
	static void ScanMobileSDKsAtPath(string, vector<SharedComponent>&);
	static void AddToComponentVector(vector<SharedComponent>&, SharedComponent);

	static void AddToComponentVector(vector<SharedComponent>& components,
		SharedComponent c)
	{
		// Avoid adding duplicate components to a component vector
		vector<SharedComponent>::iterator i = components.begin();
		while (i != components.end())
		{
			SharedComponent e = *i++;
			if (e->type == c->type && e->path == c->path)
			{
				return;
			}
		}

		components.push_back(c);
	}

	vector<SharedComponent>& GetInstalledComponents(bool force)
	{
		static std::vector<SharedComponent> installedComponents;
		if (installedComponents.empty() || force)
		{
			installedComponents.clear();
			vector<string>& paths = GetComponentSearchPaths();
			vector<string>::iterator i = paths.begin();
			while (i != paths.end())
			{
				string path(*i++);
				ScanRuntimesAtPath(path, installedComponents);
				ScanSDKsAtPath(path, installedComponents);
				ScanMobileSDKsAtPath(path, installedComponents);
				ScanModulesAtPath(path, installedComponents);
			}

			// Sort components by version here so that the latest version of
			// any component will always be chosen. Use a stable_sort because we
			// want to give preference to components earlier on the search path.
			std::stable_sort(
				installedComponents.begin(),
				installedComponents.end(),
				BootUtils::WeakCompareComponents);
		}
		return installedComponents;
	}

	class PathBits
	{
	public:
		PathBits(const string& name, const string& fullPath) :
			name(name),
			fullPath(fullPath)
		{ }
		std::string name;
		std::string fullPath;
	};

	static vector<PathBits> GetDirectoriesAtPath(std::string& path)
	{
		vector<PathBits> directories;
		vector<string> paths;

		FileUtils::ListDir(path, paths);
		vector<string>::iterator i = paths.begin();
		while (i != paths.end())
		{
			string& subpath(*i++);
			if (subpath[0] == '.')
				continue;

			string fullPath(FileUtils::Join(path.c_str(), subpath.c_str(), NULL));
			if (!FileUtils::IsDirectory(fullPath))
				continue;

			directories.push_back(PathBits(subpath, fullPath));
		}
		return directories;
	}

	static void ScanRuntimesAtPath(string path, vector<SharedComponent>& results)
	{
		if (!FileUtils::IsDirectory(path))
			return;

		// Read everything that looks like <searchpath>/runtime/<os>/*
		string rtPath(FileUtils::Join(path.c_str(), "runtime", OS_NAME, NULL));
		vector<PathBits> versions(GetDirectoriesAtPath(rtPath));
		for (size_t i = 0; i < versions.size(); i++)
		{
			PathBits& b = versions[i];
			AddToComponentVector(results,
				KComponent::NewComponent(RUNTIME, "runtime", b.name, b.fullPath));
		}
	}

	static void ScanSDKsAtPath(string path, vector<SharedComponent>& results)
	{
		if (!FileUtils::IsDirectory(path))
			return;

		// Read everything that looks like <searchpath>/sdk/<os>/*
		string sdkPath(FileUtils::Join(path.c_str(), "sdk", OS_NAME, NULL));
		vector<PathBits> versions(GetDirectoriesAtPath(sdkPath));

		for (size_t i = 0; i < versions.size(); i++)
		{
			PathBits& b = versions[i];
			AddToComponentVector(results,
				KComponent::NewComponent(SDK, "sdk", b.name, b.fullPath));
		}
	}

	static void ScanMobileSDKsAtPath(string path, vector<SharedComponent>& results)
	{
		if (!FileUtils::IsDirectory(path))
			return;

		// Read everything that looks like <searchpath>/mobilesdk/<os>/*
		string sdkPath(FileUtils::Join(path.c_str(), "mobilesdk", OS_NAME, NULL));
		vector<PathBits> versions(GetDirectoriesAtPath(sdkPath));
		for (size_t i = 0; i < versions.size(); i++)
		{
			PathBits& b = versions[i];
			AddToComponentVector(results,
				KComponent::NewComponent(MOBILESDK, "mobilesdk", b.name, b.fullPath));
		}
	}

	static void ScanModulesAtPath(string path, vector<SharedComponent>& results)
	{
		if (!FileUtils::IsDirectory(path))
			return;

		// Read everything that looks like <searchpath>/modules/<os>/*
		string namesPath(FileUtils::Join(path.c_str(), "modules", OS_NAME, NULL));
		vector<PathBits> moduleNames(GetDirectoriesAtPath(namesPath));
		for (size_t i = 0; i < moduleNames.size(); i++)
		{
			PathBits& moduleName = moduleNames[i];

			// Read everything that looks like <searchpath>/modules/<os>/<name>/*
			vector<PathBits> moduleVersions(GetDirectoriesAtPath(moduleName.fullPath));
			for (size_t j = 0; j < moduleVersions.size(); j++)
			{
				PathBits& moduleVersion = moduleVersions[j];
				AddToComponentVector(results, KComponent::NewComponent(
					MODULE, moduleName.name, moduleVersion.name, moduleVersion.fullPath));
			}
		}
	}

	void ScanBundledComponents(string path, vector<SharedComponent>& results)
	{
		// Find a directory like <appdir>/runtime/
		string runtimePath(FileUtils::Join(path.c_str(), "runtime", NULL));
		if (FileUtils::IsDirectory(runtimePath))
		{
			results.push_back(KComponent::NewComponent(
				RUNTIME, "runtime", "", runtimePath, true));
		}

		// Find a directory like <appdir>/mobilesdk/
		string mobileSDKPath(FileUtils::Join(path.c_str(), "mobilesdk", NULL));
		if (FileUtils::IsDirectory(mobileSDKPath))
		{
			results.push_back(KComponent::NewComponent(
				RUNTIME, "mobilesdk", "", mobileSDKPath, true));
		}

		// Find a directory like <appdir>/sdk/
		string sdkPath(FileUtils::Join(path.c_str(), "sdk", NULL));
		if (FileUtils::IsDirectory(sdkPath))
		{
			results.push_back(KComponent::NewComponent(
				RUNTIME, "sdk", "", sdkPath, true));
		}

		// Find all directories like <appdir>/modules/*
		string modulesPath(FileUtils::Join(path.c_str(), "modules", NULL));
		vector<PathBits> moduleNames(GetDirectoriesAtPath(modulesPath));
		for (size_t i = 0; i < moduleNames.size(); i++)
		{
			PathBits& moduleName = moduleNames[i];
			results.push_back(KComponent::NewComponent(MODULE, 
				moduleName.name, "", moduleName.fullPath, true));
		}
	}

	int CompareVersions(string one, string two)
	{
		if (one.empty() && two.empty())
			return 0;
		if (one.empty())
			return -1;
		if (two.empty())
			return 1;

		vector<string> listOne;
		vector<string> listTwo;
		FileUtils::Tokenize(one, listOne, ".");
		FileUtils::Tokenize(two, listTwo, ".");

		size_t min = listOne.size();
{'fraction_non_alphanumeric': 0.14190519460851128, 'fraction_numerical': 0.001817355747387551, 'mean_word_length': 4.836058329650906, 'pattern_counts': {'":': 0, '<': 97, '<?xml version=': 0, '>': 98, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4976672', 'n_tokens_mistral': 4698, 'n_tokens_neox': 4117, 'n_words': 949}