I clone a repository as bare on my local disk using JGit. Now, I need to read the contents of a file at any given commit id (SHA1). How do I do this ?
The comment of Rüdiger Herrmann in this answer contains the relevant hints; but to make it easier for the friends of copy & paste solutions here my complete self-contained example code of a junit test that creates a revision of a file and then retrieves the contents of this revision. Works with jGit 4.2.0.
#Test
public void test() throws IOException, GitAPIException
{
//
// init the git repository in a temporary directory
//
File repoDir = Files.createTempDirectory("jgit-test").toFile();
Git git = Git.init().setDirectory(repoDir).call();
//
// add file with simple text content
//
String testFileName = "testFile.txt";
File testFile = new File(repoDir, testFileName);
writeContent(testFile, "initial content");
git.add().addFilepattern(testFileName).call();
RevCommit firstCommit = git.commit().setMessage("initial commit").call();
//
// given the "firstCommit": use its "tree" and
// localize the test file by its name with the help of a tree parser
//
Repository repository = git.getRepository();
try (ObjectReader reader = repository.newObjectReader())
{
CanonicalTreeParser treeParser = new CanonicalTreeParser(null, reader, firstCommit.getTree());
boolean haveFile = treeParser.findFile(testFileName);
assertTrue("test file in commit", haveFile);
assertEquals(testFileName, treeParser.getEntryPathString());
ObjectId objectForInitialVersionOfFile = treeParser.getEntryObjectId();
// now we have the object id of the file in the commit:
// open and read it from the reader
ObjectLoader oLoader = reader.open(objectForInitialVersionOfFile);
ByteArrayOutputStream contentToBytes = new ByteArrayOutputStream();
oLoader.copyTo(contentToBytes);
assertEquals("initial content", new String(contentToBytes.toByteArray(), "utf-8"));
}
git.close();
}
// simple helper to keep the main code shorter
private void writeContent(File testFile, String content) throws IOException
{
try (OutputStreamWriter wr = new OutputStreamWriter(new FileOutputStream(testFile), Charset.forName("utf-8")))
{
wr.append(content);
}
}
Edit to add: another, probably better example is at https://github.com/centic9/jgit-cookbook/blob/master/src/main/java/org/dstadler/jgit/api/ReadFileFromCommit.java
By using this. Iterable<RevCommit> gitLog = gitRepo.log().call(); you can get all the commit hash from that object.
Related
I am using extent reports in appium with testng and its working fine for me.whenver my tests run is completed then extent report generates html file in my project folder and that is what expected.
Issue is that when I again run my tests then extent report generate new html report file by overwrting the name of previously created html file.
I want extent report to generate html file with unique names or name with date in in, each time when I run my tests
You can create your file name to be the current timestamp. This way, it will be easy to have a unique name for your report file -
String timeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
extent = new ExtentReports (userDir +"\\test-output\\" + timeStamp + ".html", true);
You can do it by setting unique name:
String reportFile = resultDirectory + fileName + ".html";
than method for saving report to certain folder:
public void saveReportFolder() throws IOException {
File srcDir = new
File(System.getProperty("user.home")+"/Automation/target");
File destDir = new File(System.getProperty("user.home") + "/reports/"+ System.getProperty("user.name")+"/"+dateTimeGenerator());
FileUtils.copyDirectory(srcDir, destDir);
}
...and utility for setting dateTime:
public static String dateTimeGenerate(){
Format formatter = new SimpleDateFormat("YYYYMMdd_HHmmssSSS");
Date date = new Date(System.currentTimeMillis());
return formatter.format(date);
}
Or simply use klov reports start server and have everything in database (MongoDb), it is more elegant way to go.
Hope this helps,
I use:
private static String timestamp = new SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance().getTime()).replaceAll(":", "-");
public static String reportFullPath = getReportsPath() + "\\AutomationReport_" + timestamp + ".html";
I have done it like this, simple and crisp.
String Outputfilename= ExecutionConfig.FileOutname;
System.err.close(); // written to remove JAVA 9 incompatibility.. continued below
System.setErr(System.out); // continue.. and remove the warnings
extent = new ExtentReports(System.getProperty("user.dir") + "/test-output/"+Outputfilename+".html", true);
So here ExecutionConfig.FileOutname is called from the class ExecutionConfig where i am reading the values from the config.properties file. and then here assigning it to the output-file.
Also it worked for me.
I also faced a similar issue. As in the real-world, we need old reports as well. Below is the solution in Java for Extent PDF report
I added an event listener method. Event used- TestRunStarted. We further need to register for this event too. The solution can be done for HTML report too.
public void setCustomReportName(TestRunStarted event)
{
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
String currenttimestamp =sdf.format(timestamp);
Properties prop=new Properties();
//extent.reporter.pdf.out is the name of property which tell the report path
prop.setProperty("extent.reporter.pdf.out", "test output/PdfReport/ExtentPdf_"+currenttimestamp+".pdf");
ExtentService e1 =new ExtentService();
//ExtentReportsLoader is the inner class of ExtentService and initPdf is its private method which takes the path for report
Class<?>[] a=e1.getClass().getDeclaredClasses();
Method met;
//Even there is exception test run wont fail and report will also be generated (ExtentPdf.pdf)
try {
met = a[0].getDeclaredMethod("initPdf", Properties.class);
met.setAccessible(true);
met.invoke(a[0], prop);
} catch (NoSuchMethodException e) {
System.out.println("There is no method with name initPdf");
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
System.out.println("Argument passed to method initPdf are not correct");
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
I work with alfresco 4.0
I have a problem to save document in special space in alfresco named in arabic language.
for this example I didn't have problem :
/app:company_home/cm:تجربة
but I have problem when the space witch is created in alfresco is named in arabic language and have blank character . like this :
/app:company_home/cm:تجربة ثانية
in this case I can't save document in alfresco
updated :
also I have the same problem when I have a folder named in english and have escape character like this :
His Excellency the Secretary
Reporter Secretariat
this is the document to save document in alfresco
public String saveDocument(File file, String name, String folderName, String userName, String pwd, String code)
throws Exception {
File file_BC = file;
try {
BarCodeEngine barCodeEngine = new BarCodeEngine(file, code);
file_BC = barCodeEngine.setBarCode();
} catch (Exception e) {
e.printStackTrace();
}
byte[] contentByte = IOUtils.toByteArray(new FileInputStream(file_BC));
// Start the session
AuthenticationUtils.startSession(userName, pwd);
try {
// Create a reference to the parent where we want to create content
Store storeRef = new Store(Constants.WORKSPACE_STORE, "SpacesStore");
ParentReference companyHomeParent = new ParentReference(storeRef, null, folderName, Constants.ASSOC_CONTAINS, null);
// Assign name
companyHomeParent.setChildName("cm:" + name);
// Construct CML statement to create content node
// Note: Assign "1" as a local id, so we can refer to it in subsequent
// CML statements within the same CML block
NamedValue[] contentProps = new NamedValue[1];
contentProps[0] = Utils.createNamedValue(Constants.PROP_NAME, name);
CMLCreate create = new CMLCreate("1", companyHomeParent, null, null, null, Constants.TYPE_CONTENT, contentProps);
// Construct CML statement to add titled aspect
NamedValue[] titledProps = new NamedValue[2];
titledProps[0] = Utils.createNamedValue(Constants.PROP_TITLE, name);
titledProps[1] = Utils.createNamedValue(Constants.PROP_DESCRIPTION, name);
CMLAddAspect addAspect = new CMLAddAspect(Constants.ASPECT_TITLED, titledProps, null, "1");
// Construct CML Block
CML cml = new CML();
cml.setCreate(new CMLCreate[] { create });
cml.setAddAspect(new CMLAddAspect[] { addAspect });
// Issue CML statement via Repository Web Service and retrieve result
// Note: Batching of multiple statements into a single web call
UpdateResult[] result = WebServiceFactory.getRepositoryService().update(cml);
Reference content = result[0].getDestination();
// Write some content
ContentServiceSoapBindingStub contentService = WebServiceFactory.getContentService();
//String text = "The quick brown fox jumps over the lazy dog";
ContentFormat contentFormat = new ContentFormat("text/plain", "UTF-8");
Content contentRef = contentService.write(content, Constants.PROP_CONTENT, contentByte, contentFormat);
System.out.println("Document are created successfully. UID:= " + content.getUuid());
return content.getUuid();
} catch (Throwable e) {
System.out.println(e.toString());
} finally {
// End the session
AuthenticationUtils.endSession();
//System.exit(0);
}
return null;
}
I try to replace espace with this character : + without success
saveAttachement(file,
fileName +
System.currentTimeMillis(), container.replace(" ","+"),
USER_NAME, PASSWORD,
code);
this is the old container with espace
/app:company_home/cm:His Excellency the Secretary/cm:Reporter Secretariat
and this is the container with +
/app:company_home/cm:His+Excellency+the Secretary/cm:Reporter+Secretariat
in alfresco's log I didn't find any error
Try encoding your folderName with ISO9075.encode(folderName).
Lucene search syntax needs encoding of spaces using ISO9075. I thik this is what happens somewhere behind the scenes of your ParentReference usage.
If files are posted to my webapp, then I read them via MultipartFormDataStreamProvider.FileData.
I Initialize the provider like this:
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
And the provider nicely stores them as "~App_Data/BodyPart_{someguid}"
But how do I clean up those files after I'm done with them?
I know this question is old, but the best way I found to delete the temporary file was after processing it.
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
foreach (var file in provider.Files)
{
// process file upload...
// delete temporary file
System.IO.File.Delete(file.LocalFileName);
}
You could delete all files that are older than a certain timespan. e.g.
private void CleanTempFiles(string dir, int ageInMinutes)
{
string[] files = Directory.GetFiles(dir);
foreach (string file in files)
{
var time = File.GetCreationTime(file);
if (time.AddMinutes(ageInMinutes) < DateTime.Now)
{
File.Delete(file);
}
}
}
Then call it with something like:
CleanTempFiles(root, 60); // Delete all files older than 1 hour
I'm trying to drop in sqlite support for saving the score and some flags. I need to open the db if it exists, then init game values based on db. If the db does not exist, I need to create/init it. The code below compiles but crashes for unknown reason.
package mygame;
<snip imports>
import sys.db.Types;
class ScoreDB extends sys.db.Object {
public var id : SId;
public var dbscore1 : SInt;
public var dbsound : SInt;
public var dbscore2 : SInt;
}
class mygame extends Sprite {
<snip var defines>
public function new () {
// start sqlite code
sys.db.Manager.initialize();
// db does exist
// then read values
// currentScore = score1.dbscore1;
// doSound = score1.dbsound;
// doScore = score1.dbscore2;
// db does not exist:
var cnx = sys.db.Sqlite.open("mybase.db");
sys.db.Manager.cnx = cnx;
sys.db.TableCreate.create(ScoreDB.manager);
var score1 = new ScoreDB();
score1.id = 0;
score1.dbscore1 = 0;
score1.dbsound = 0;
score1.dbscore2 = 0;
score1.insert();
currentScore = 0;
doSound = 0;
doScore = 0;
cnx.close();
// end sqlite code
super ();
initialize ();
construct ();
newGame ();
}
I actually just solved the same issue.
The problem is that the app is essentially a .zip file and cannot be edited. You need to create (and later access) the DB in the app storage directory.
To access the directory use following code:
private static var localStoragePath:String = openfl.utils.SystemPath.applicationStorageDirectory;
There is a known bug that the IDE's don't show the SystemPath class, but don't mind it, it will compile without problem.
Later, with your common tools you can read and write the directory, create new folders etc.
Here's a quick test, to make sure it works and doesn't crash:
// creating a test folder
sys.FileSystem.createDirectory(openfl.utils.SystemPath.applicationStorageDirectory + "/testFolder");
var form:TextFormat = new TextFormat(null, 22, 0xFFFFFF);
// getting contents of the storage dir
var arr = sys.FileSystem.readDirectory(openfl.utils.SystemPath.applicationStorageDirectory);
var tf:TextField = new TextField();
tf.defaultTextFormat = form;
tf.width = Lib.current.stage.stageWidth;
tf.height = Lib.current.stage.stageHeight;
tf.multiline = true;
tf.wordWrap = true;
tf.text = arr.toString();
addChild(tf);
as you'll see, the newly created folder is there. You can delete the line that creates the folder and you'll see it's safe.
Oh, an don't forget to add Android permissions in the XML file:
<android permission="android.permission.WRITE_EXTERNAL_STORAGE"/>
As far as I know there is no sqlite definitions in openfl. And the ones you use are just normal cpp target definition. I suppose the problem is they don't work on android. Even more: I'm quite sure the api definitions are ok, but it tries to load dll with a wrong name, which probably kills your app without even letting out an error. Try to look into implementation(it is short and easy to understand) and change the dll name.
I encounter this exception when I try to updating a record with following statement.
UPDATE GroupTable SET groupId=100 WHERE groupId=101
I tested the statement under SQLite Manager of Firefox plug-in, and it works.
The error message is as following image. It crashed at the os_win_c.cs, the method named getTempname().
Well, I modified the original codes and fixed this bug.
The Path.GetTempPath() doesn't work because the sandbox enviroment. It has no access right.
I fixed by following codes. And it works now.
static int getTempname(int nBuf, StringBuilder zBuf)
{
const string zChars = "abcdefghijklmnopqrstuvwxyz0123456789";
StringBuilder zRandom = new StringBuilder(20);
i64 iRandom = 0;
for (int i = 0; i < 20; i++)
{
sqlite3_randomness(1, ref iRandom);
zRandom.Append((char)zChars[(int)(iRandom % (zChars.Length - 1))]);
}
//! Modified by Toro, 2011,05,10
string tmpDir = "tmpDir";
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
store.CreateDirectory(tmpDir);
//zBuf.Append(Path.GetTempPath() + SQLITE_TEMP_FILE_PREFIX + zRandom.ToString());
zBuf.Append(tmpDir + "/" + SQLITE_TEMP_FILE_PREFIX + zRandom.ToString());
return SQLITE_OK;
}
The above patch will result in an extra folder tmpDir in the isolatedstorage, and the temp files won't be deleted automatically, so it needs to be delete by self. I tried to delete those files in tmpDir in the method of winClose inside os_win_c.cs, and I found it will result in crash when I do VACUUM. Finally, I delete those tmp files when I closed the database. The following is a Dispose method in SQLiteConnection class.
public void Dispose()
{
if (_open)
{
// Original codes for close sqlite database
Sqlite3.sqlite3_close(_db);
_db = null;
_open = false;
// Clear tmp files in tmpDir, added by Toro 2011,05,13
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
string tmpDir = "tmpDir";
if (store.DirectoryExists(tmpDir) == false) return;
string searchPath = System.IO.Path.Combine(tmpDir, "*.*");
foreach (string file in store.GetFileNames(searchPath)) {
store.DeleteFile(System.IO.Path.Combine(tmpDir, file));
}
}
}