Пример #1
0
 static FilePath GetProjectVirtualPath(FilePath link, FilePath filePath, Project project)
 {
     if (!link.IsNullOrEmpty)
     {
         return(link);
     }
     if (project != null)
     {
         var rel = project.GetRelativeChildPath(filePath);
         if (!rel.ToString().StartsWith("..", StringComparison.Ordinal))
         {
             return(rel);
         }
     }
     return(filePath.FileName);
 }
Пример #2
0
		public void TransferFiles (IProgressMonitor monitor, Project sourceProject, FilePath sourcePath, Project targetProject,
		                           FilePath targetPath, bool removeFromSource, bool copyOnlyProjectFiles)
		{
			// When transfering directories, targetPath is the directory where the source
			// directory will be transfered, including the destination directory or file name.
			// For example, if sourcePath is /a1/a2/a3 and targetPath is /b1/b2, the
			// new folder or file will be /b1/b2
			
			if (targetProject == null)
				throw new ArgumentNullException ("targetProject");

			if (!targetPath.IsChildPathOf (targetProject.BaseDirectory))
				throw new ArgumentException ("Invalid project folder: " + targetPath);

			if (sourceProject != null && !sourcePath.IsChildPathOf (sourceProject.BaseDirectory))
				throw new ArgumentException ("Invalid project folder: " + sourcePath);
				
			if (copyOnlyProjectFiles && sourceProject == null)
				throw new ArgumentException ("A source project must be specified if copyOnlyProjectFiles is True");
			
			bool sourceIsFolder = Directory.Exists (sourcePath);

			bool movingFolder = (removeFromSource && sourceIsFolder && (
					!copyOnlyProjectFiles ||
					IsDirectoryHierarchyEmpty (sourcePath)));

			// We need to remove all files + directories from the source project
			// but when dealing with the VCS addins we need to process only the
			// files so we do not create a 'file' in the VCS which corresponds
			// to a directory in the project and blow things up.
			List<ProjectFile> filesToRemove = null;
			List<ProjectFile> filesToMove = null;
			try {
				//get the real ProjectFiles
				if (sourceProject != null) {
					if (sourceIsFolder) {
						var virtualPath = sourcePath.ToRelative (sourceProject.BaseDirectory);
						// Grab all the child nodes of the folder we just dragged/dropped
						filesToRemove = sourceProject.Files.GetFilesInVirtualPath (virtualPath).ToList ();
						// Add the folder itself so we can remove it from the soruce project if its a Move operation
						var folder = sourceProject.Files.Where (f => f.ProjectVirtualPath == virtualPath).FirstOrDefault ();
						if (folder != null)
							filesToRemove.Add (folder);
					} else {
						filesToRemove = new List<ProjectFile> ();
						var pf = sourceProject.Files.GetFileWithVirtualPath (sourceProject.GetRelativeChildPath (sourcePath));
						if (pf != null)
							filesToRemove.Add (pf);
					}
				}
				//get all the non-project files and create fake ProjectFiles
				if (!copyOnlyProjectFiles || sourceProject == null) {
					var col = new List<ProjectFile> ();
					GetAllFilesRecursive (sourcePath, col);
					if (sourceProject != null) {
						var names = new HashSet<string> (filesToRemove.Select (f => sourceProject.BaseDirectory.Combine (f.ProjectVirtualPath).ToString ()));
						foreach (var f in col)
							if (names.Add (f.Name))
							    filesToRemove.Add (f);
					} else {
						filesToRemove = col;
					}
				}
			} catch (Exception ex) {
				monitor.ReportError (GettextCatalog.GetString ("Could not get any file from '{0}'.", sourcePath), ex);
				return;
			}
			
			// Strip out all the directories to leave us with just the files.
			filesToMove = filesToRemove.Where (f => f.Subtype != Subtype.Directory).ToList ();
			
			// If copying a single file, bring any grouped children along
			ProjectFile sourceParent = null;
			if (filesToMove.Count == 1 && sourceProject != null) {
				var pf = filesToMove[0];
				if (pf != null && pf.HasChildren)
					foreach (ProjectFile child in pf.DependentChildren)
						filesToMove.Add (child);
				sourceParent = pf;
			}
			
			// Ensure that the destination folder is created, even if no files
			// are copied
			
			try {
				if (sourceIsFolder && !Directory.Exists (targetPath) && !movingFolder)
					FileService.CreateDirectory (targetPath);
			} catch (Exception ex) {
				monitor.ReportError (GettextCatalog.GetString ("Could not create directory '{0}'.", targetPath), ex);
				return;
			}

			// Transfer files
			// If moving a folder, do it all at once
			
			if (movingFolder) {
				try {
					FileService.MoveDirectory (sourcePath, targetPath);
				} catch (Exception ex) {
					monitor.ReportError (GettextCatalog.GetString ("Directory '{0}' could not be moved.", sourcePath), ex);
					return;
				}
			}
			
			monitor.BeginTask (GettextCatalog.GetString ("Copying files..."), filesToMove.Count);
			
			ProjectFile targetParent = null;
			foreach (ProjectFile file in filesToMove) {
				bool fileIsLink = file.Project != null && file.IsLink;
				
				var sourceFile = fileIsLink
					? file.Project.BaseDirectory.Combine (file.ProjectVirtualPath)
					: file.FilePath;
				
				FilePath newFile;
				if (sourceIsFolder)
					newFile = targetPath.Combine (sourceFile.ToRelative (sourcePath));
				else if (sourceFile == sourcePath)
					newFile = targetPath;
				else if (sourceFile.ParentDirectory != targetPath.ParentDirectory)
					newFile = targetPath.ParentDirectory.Combine (sourceFile.ToRelative (sourcePath.ParentDirectory));
				else
					newFile = GetTargetCopyName (sourceFile, false);
				
				if (!movingFolder && !fileIsLink) {
					try {
						FilePath fileDir = newFile.ParentDirectory;
						if (!Directory.Exists (fileDir) && !file.IsLink)
							FileService.CreateDirectory (fileDir);
						if (removeFromSource)
							FileService.MoveFile (sourceFile, newFile);
						else
							FileService.CopyFile (sourceFile, newFile);
					} catch (Exception ex) {
						monitor.ReportError (GettextCatalog.GetString ("File '{0}' could not be created.", newFile), ex);
						monitor.Step (1);
						continue;
					}
				}
				
				if (sourceProject != null) {
					if (fileIsLink) {
						var linkFile = (ProjectFile) file.Clone ();
						if (movingFolder) {
							var abs = linkFile.Link.ToAbsolute (sourceProject.BaseDirectory);
							var relSrc = abs.ToRelative (sourcePath);
							var absTarg = relSrc.ToAbsolute (targetPath);
							linkFile.Link = absTarg.ToRelative (targetProject.BaseDirectory);
						} else {
							linkFile.Link = newFile.ToRelative (targetProject.BaseDirectory);
						}
						targetProject.Files.Add (linkFile);
					} else if (targetProject.Files.GetFile (newFile) == null) {
						ProjectFile projectFile = (ProjectFile) file.Clone ();
						projectFile.Name = newFile;
						if (targetParent == null) {
							if (file == sourceParent)
								targetParent = projectFile;
						} else if (sourceParent != null) {
							if (projectFile.DependsOn == sourceParent.Name)
								projectFile.DependsOn = targetParent.Name;
						}
						targetProject.Files.Add (projectFile);
					}
				}
				
				monitor.Step (1);
			}
			
			if (removeFromSource) {
				// Remove all files and directories under 'sourcePath'
				foreach (var v in filesToRemove)
					sourceProject.Files.Remove (v);
			}
			
			var pfolder = sourcePath.ParentDirectory;
			
			// If this was the last item in the folder, make sure we keep
			// a reference to the folder, so it is not deleted from the tree.
			if (removeFromSource && sourceProject != null && pfolder.CanonicalPath != sourceProject.BaseDirectory.CanonicalPath && pfolder.IsChildPathOf (sourceProject.BaseDirectory)) {
				pfolder = pfolder.ToRelative (sourceProject.BaseDirectory);
				if (!sourceProject.Files.GetFilesInVirtualPath (pfolder).Any ()) {
					var folderFile = new ProjectFile (sourceProject.BaseDirectory.Combine (pfolder));
					folderFile.Subtype = Subtype.Directory;
					sourceProject.Files.Add (folderFile);
				}
			}
			
			monitor.EndTask ();
		}
Пример #3
0
		/// <summary>
		/// Gets the default namespace for the file, according to the naming policy.
		/// </summary>
		/// <remarks>Always returns a valid namespace, even if the fileName is null.</remarks>
		internal static string GetDefaultNamespace (Project project, string defaultNamespace, string fileName)
		{
			DotNetNamingPolicy pol = project.Policies.Get<DotNetNamingPolicy> ();

			string root = null;
			string dirNamespc = null;
			string defaultNmspc = !string.IsNullOrEmpty (defaultNamespace)
				? defaultNamespace
				: SanitisePotentialNamespace (project.Name) ?? "Application";
			
			if (string.IsNullOrEmpty (fileName)) {
				return defaultNmspc;
			}

			string dirname = Path.GetDirectoryName (fileName);
			string relativeDirname = null;
			if (!String.IsNullOrEmpty (dirname)) {
				relativeDirname = project.GetRelativeChildPath (dirname);
				if (string.IsNullOrEmpty (relativeDirname) || relativeDirname.StartsWith (".."))
					relativeDirname = null;
			}

			if (relativeDirname != null) {
				try {
					switch (pol.DirectoryNamespaceAssociation) {
					case DirectoryNamespaceAssociation.PrefixedFlat:
						root = defaultNmspc;
						goto case DirectoryNamespaceAssociation.Flat;
					case DirectoryNamespaceAssociation.Flat:
						//use the last component only
						dirNamespc = SanitisePotentialNamespace (Path.GetFileName (relativeDirname));
						break;

					case DirectoryNamespaceAssociation.PrefixedHierarchical:
						root = defaultNmspc;
						goto case DirectoryNamespaceAssociation.Hierarchical;
					case DirectoryNamespaceAssociation.Hierarchical:
						dirNamespc = SanitisePotentialNamespace (GetHierarchicalNamespace (relativeDirname));
						break;
					}
				} catch (IOException ex) {
					LoggingService.LogError ("Could not determine namespace for file '" + fileName + "'", ex);
				}

			}

			if (dirNamespc != null && root == null)
				return dirNamespc;
			if (dirNamespc != null && root != null)
				return root + "." + dirNamespc;
			return defaultNmspc;
		}
		public string GetCompilerFlags ( Project project, string configuration )
		{
			if ( !this.CanDeploy ( project ) )
				throw new Exception ( "Not a deployable project." );
			
			DotNetProjectConfiguration config = 
				project.Configurations [configuration] as DotNetProjectConfiguration;

			if ( config == null ) return "";
			
			CSharpCompilerParameters parameters = (CSharpCompilerParameters) config.CompilationParameters;
			ICSharpProject projectParameters = config.ParentItem as ICSharpProject;
			
			StringWriter writer = new StringWriter();
			
			writer.Write(" -noconfig");
			writer.Write(" -codepage:utf8");
			
			if (parameters.UnsafeCode) {
				writer.Write(" -unsafe");
			}
			writer.Write(" -warn:" + parameters.WarningLevel);
			if(parameters.Optimize)
				writer.Write(" -optimize+");
			else
				writer.Write(" -optimize-");

			if(parameters.NoWarnings != null && parameters.NoWarnings != "") {
				writer.Write(" \"-nowarn:" + parameters.NoWarnings + '"');
			}

			if(config.DebugSymbols) {
				writer.Write(" -debug");
				//Check whether we have a DEBUG define
				bool hasDebugDefine = false;
				foreach (string define in parameters.DefineSymbols.Split (';')) {
					if (String.Compare (define, "DEBUG") == 0) {
						hasDebugDefine = true;
						break;
					}
				}
				if (!hasDebugDefine)
					writer.Write (" -define:DEBUG");
			}

			switch (parameters.LangVersion) {
			case LangVersion.Default:
				break;
			case LangVersion.ISO_1:
				writer.Write (" -langversion:ISO-1 ");
				break;
			case LangVersion.ISO_2:
				writer.Write (" -langversion:ISO-2 ");
				break;
			default:
				throw new Exception ("Invalid LangVersion enum value '" + parameters.LangVersion.ToString () + "'");
			}
			
			
			// TODO check path and add to extradist...
			//if (parameters.Win32Icon != null && parameters.Win32Icon.Length > 0) {
			//	writer.Write(" \"-win32icon:" + compilerparameters.Win32Icon + "\"");
			//}
			
			if (parameters.DefineSymbols.Length > 0) {
				writer.Write (string.Format (" \"-define:{0}\"", parameters.DefineSymbols.TrimEnd(';')));
			}
				
			if (projectParameters.MainClass != null && projectParameters.MainClass != "") {
				writer.Write (" \"-main:" + projectParameters.MainClass + '"');
			}

			if (config.SignAssembly)
				writer.Write (" \"-keyfile:" + project.GetRelativeChildPath (config.AssemblyKeyFile) + '"');
			if (config.DelaySign)
				writer.Write (" -delaySign");

			// TODO check paths and add to extradist?
			//if (parameters.GenerateXmlDocumentation) {
			//	writer.WriteLine(" \"-doc:" + Path.ChangeExtension(exe, ".xml") + '"');
			//}
		
			return writer.ToString();
		}
		FilePath GetFileDestinationPath (ProjectFile file, Project source, Project target)
		{
			FilePath relativePath = source.GetRelativeChildPath (file.FilePath);
			return target.BaseDirectory.Combine (relativePath);
		}
Пример #6
0
		/// <summary>
		/// Adds files to a project, potentially asking the user whether to move, copy or link the files.
		/// </summary>
		public IList<ProjectFile> AddFilesToProject (Project project, FilePath[] files, FilePath targetDirectory,
			string buildAction)
		{
			int action = -1;
			IProgressMonitor monitor = null;
			
			if (files.Length > 10) {
				monitor = new MessageDialogProgressMonitor (true);
				monitor.BeginTask (GettextCatalog.GetString("Adding files..."), files.Length);
			}
			
			var newFileList = new List<ProjectFile> ();
			
			using (monitor) {
				foreach (FilePath file in files) {
					if (monitor != null) {
						monitor.Log.WriteLine (file);
						monitor.Step (1);
					}
					
					if (FileService.IsDirectory (file)) {
						//FIXME: warning about skipping?
						newFileList.Add (null);
						continue;
					}
					
					//files in the project directory get added directly in their current location without moving/copying
					if (file.IsChildPathOf (project.BaseDirectory)) {
						newFileList.Add (project.AddFile (file, buildAction));
						continue;
					}
					
					//for files outside the project directory, we ask the user whether to move, copy or link
					var md = new Gtk.MessageDialog (
						 IdeApp.Workbench.RootWindow,
						 Gtk.DialogFlags.Modal | Gtk.DialogFlags.DestroyWithParent,
						 Gtk.MessageType.Question, Gtk.ButtonsType.None,
						 GettextCatalog.GetString ("The file {0} is outside the project directory. What would you like to do?", file));

					try {
						Gtk.CheckButton remember = null;
						if (files.Length > 1) {
							remember = new Gtk.CheckButton (GettextCatalog.GetString ("Use the same action for all selected files."));
							md.VBox.PackStart (remember, false, false, 0);
						}
						
						const int ACTION_LINK = 3;
						const int ACTION_COPY = 1;
						const int ACTION_MOVE = 2;
						
						md.AddButton (GettextCatalog.GetString ("_Link"), ACTION_LINK);
						md.AddButton (Gtk.Stock.Copy, ACTION_COPY);
						md.AddButton (GettextCatalog.GetString ("_Move"), ACTION_MOVE);
						md.AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel);
						md.VBox.ShowAll ();
						
						int ret = -1;
						if (action < 0) {
							ret = MessageService.RunCustomDialog (md);
							if (ret < 0)
								return newFileList;
							if (remember != null && remember.Active) action = ret;
						} else {
							ret = action;
						}
						
						var targetName = targetDirectory.Combine (file.FileName);
						
						if (ret == ACTION_LINK) {
							var pf = project.AddFile (file, buildAction);
							pf.Link = project.GetRelativeChildPath (targetName);
							newFileList.Add (pf);
							continue;
						}
						
						try {
							if (MoveCopyFile (file, targetName, ret == ACTION_MOVE))
								newFileList.Add (project.AddFile (targetName, buildAction));
							else
								newFileList.Add (null);
						}
						catch (Exception ex) {
							MessageService.ShowException (ex, GettextCatalog.GetString (
								"An error occurred while attempt to move/copy that file. Please check your permissions."));
							newFileList.Add (null);
						}
					} finally {
						md.Destroy ();
					}
				}
			}
			return newFileList;
		}