UCOSPLogGregHysen

Kevin Brightwell edited this page Aug 26, 2015 · 1 revision
Clone this wiki locally

Each UCOSP participant is asked to log all their accomplishments as well as the difficulties they have getting set up to understand Umple and other experiences they have. Difficulties might include understanding how to model in Umple, using y UmpleOnline, code that is difficult to figure out, and development tools that are hard to figure out, or don't seem to work properly. The more log entries added the more we can better get a grip on the usability issues with Umple, and the more we can help future new contributors come up to speed.

Log entries in reverse chronological order

December 8

I just added complex attributes. It didn't take long; simple attributes are now represented using complex attributes because the generator always selects the most descriptive of a set of mutually exclusive clauses.

Commit for yesterday and today will be later tonight.

December 4-7

I've added the following changes/fixes:

  • Associations now working
  • Fixed bug with associations pointing to self. In this case, the association is duplicated by the parser.
  • Fixed bug with associations st only the declaring class includes the assoc
  • Fixed an issue with mutually exclusive clauses. State may be changed by a clause that is excluded, and therefore the modified states must be reverted. This was fixed by moving all state to a scope-level (of current grammar rule) rather than a global level. Only the state from the accepted clause is actually flushed.
  • Added "External" keyword
  • Added framework for SoftwarePatterns; implemented "isA" relationship
  • Added handling for subclasses
  • Added framework for attributes; implemented simple attributes
  • Added better handler for spacing with terminals: given a rule and a terminal name, whether the terminal requires a space after it can now be determined.

I will commit these changes tomorrow. My exams start in 4 days and run right through to the 18th, so this will probably be my final commit of the semester. If changes need to be made, then I am free to apply fixes after the 18th.

December 3rd

Almost have associations working. It seems to fail if there are multiple classes defined in the same file.

December 2nd

Issue 447 (on Google Code):

  • Fixed an issue where classes defined in the same input file were generated twice
  • Started integrating associations

umple++:

  • Added ability to test modifications to codebase (to be run before committing). umple++ generates a patch from the developer's working copy, and applies the patch to a fresh codebase, and then tries to build all.

November 28,29,30, Dec 1

Summary of Work from these days:

  • Fixed bug with mutually exclusive clauses in single scope (the '|' separator in definitions)
  • Added handling for mutually exclusive clauses in different scopes
  • Added handling for anonymous rules
  • Detection for cycles in the grammar, and preventing infinite loops.
  • Method code is generated
  • Indentation handling in different scopes
  • Added handling for parameter list in Methods with >2 parameters

The following details can also be found in Issue 447 (on Google Code)

Notes on Final Product: UmpleGenerator is an experimental module that generates code by associations between a grammar and the properties of an UmpleElement/UmpleModel. More specifically, code is generated using a graph of RuleTokens, generated by RuleBasedParser, and a graph of Rules, generated by an Analyzer. The graph of RuleTokens is the primary source of information, although more specific information about a given rule can be extracted from the corresponding node in a Rule graph. Generation starts from the grammar rule associated with an UmpleClassifier (class or interface). The graph is traversed and rules are satisfied by properties of the UmpleClassifier. The "most satisfied" path is accepted as the output code.

Current Implementation:

  • Generates Classes and Concrete Methods.
  • Generation starts at generateRuleOutput and is solved using mutual recursion with generateRuleTokenOutput.
  • Each rule, named or anonymous, is processed in its own Scope
  • A stack of Scopes is maintained, see 'scopes' and 'getScope'
  • Cycles in the graph are detected and handled via the isRecursing method.
  • Handles mutually exclusive clauses, (|), see handleMutexClause
  • Modifiers in the grammar (? and *) are handled, see 'generateRuleOutput'
  • Whitespace is highly configurable via the 'pad' methods.
  • Whitespace can be overridden by extensions of this class, for whitespace delimited languages.

This week, I also updated umple++ so that it can generate code using: 'umple++ generate name File2...'

November 20; November 25,26,27

It took a lot of work, but I now have a working code generator that uses our EBNF grammar to translate our internal model/elements to code. Right now, I am fixing a small bug with the '|' separator inside of definitions and parentheses. I was originally solving this using different buckets and then selecting the 'most full' or 'most satisfied' bucket to output. This is the algorithm I discussed a few logs ago, however I've realized that I can probably solve this problem just using mutual recursion. Once I have this in-place, I'll add my tests and commit the code.

Notes: The generator currently does a full generation of only method and class declarations, although extending is just a matter of outputting the data from the UmpleElement/Method as it is requested. I just have not had time to write output statements for every property.

Additional Details on Work from these days: I hit a roadblock last week because I had been using the rules graph, which represents everything as regex. I rewrote this aspect using the Rule Token graph that is generated as an intermediate step by the RuleBasedParser. I then traverse the graph from the starting point (corresponding to the input UmpleElement) satisfying the rules with properties of the UmpleElement and children of the UmpleElement. However, I've kept the Rule Graph search in-place since it has details about rules that are generated by the Analyzer, and hence are not present in the Rule Token Graph.

November 19

I wrapped up the dev tool, debatably aptly named 'umple++' ('umple' was taken). It does some really cool stuff (I think), and empowers users like me who prefer to work solely from a CLI. Features:

  • Compile components of Umple (jet, compiler, version, online, etc)
  • Clean directories (revert java output files)
  • Update to the latest umple.jar (I have to do this all the time when developing; see earlier logs)
  • Open Umple's interactive debugging info from the latest build (lynx or w3m supported).
  • This allows users who have not setup apache on their system to analyze debugging output
  • Developers can have multiple workspaces (!!) This was one of my original motivations because I have 4 workspaces and those aliases just were not working out.

The application is only about 250 lines, and it should be very simple for others to add functionality in the future. Run 'umple++' to see following info:

-- Description --
umple++ is a tool for building and debugging Umple.
Multiple Umple workspaces are supported; see below for details.

-- umple++ --
Compile various components of Umple:              build [all|compiler|jet|online|quick|version]
Revert generated files:                           clean [all|compiler|jet]
Download latest version of umple.jar:             update [umple.jar]
Display debug info for latest build:              debug
Print current workspace directory:                cwd
Description, print_usage and compatibility:       info
Help:                                             help

-- Adding an Umple Workspace --
- Store workspaces in the the environment variable, 'UMPLE_WORKSPACES'
- UMPLE_WORKSPACES is a colon-separated list, ex: 'dir1:dir2:dirN'
- umple++ determines which workspace to perform an action on by looking at your working directory (pwd)
- Workspaces should not be nested

-- Compatibility --
Tested on the following platforms:
- Mac OS X 10.8.5

Tested with the following applications:
- curl 7.24.0
- Lynx Version 2.8.7rel.2
- Wget 1.13.4
- w3m 0.5.3

I created an issue for this app, Issue 459 (on Google Code).

November 12-13

after this week's Hangout

I worked for a few hours on step (2) from last week's log, although I have already written several hundred lines of code and don't have anything worth committing. It was mentioned in my midterm review that frequent commits are recommended if I want to maintain a good grade, and this has been reiterated in our past few hangouts. As always with new projects, it is easy to underestimate how much time will be needed. I definitely did this because I was originally thinking that a prototype could be done fairly easily in a few weeks. Although the more I learn, plan, and code, I begin to see how much work really is required. For the most part this is because my idea moves so far away from the current paradigm, and I don't want to break any existing code. But nevertheless, I am still enjoying working on this and certainly don't regret taking on such a large project. I think that I am still on track to have a prototype and I have been writing a design document to go along with the idea; however, time is winding down very quickly and I have not committed anything for a few weeks. So, I am taking some time to follow up on a suggestion from Timothy earlier this term and move my aliases into a single, simple program for all developers to use. I found that, for me anyways, there was a relatively steep learning curve just to begin development on Umple. This application will make it easier for future developers to get started, and will (hopefully) be helpful for current developers. Commit coming next week, after more testing and finalized features.

November 4-6

In my last log, I discussed not wanting to make assumptions about the grammar. To make this decision we have to consider the duality between grammar and language. If we make no assumptions, then we have to have a deeper knowledge of the language. If we make assumptions, then we can abstract more functionality and reduce code duplication. Since the goal is to simplify, I decided to make assumptions about the naming of grammar rules. For example, a class definition must be defined by the root rule, classDefinition. I figured that to make grammars consistent, we would probably want similar naming conventions anyway, so I don't think we lose anything from this decision.

Making assumptions means can reduce the complexity of the best-fit algorithm: since we know the root token (of a tokenized grammar) of a given element, we can search the graph for that root token. We can then extract the rules for the root token and then "simply" fit the input to the grammar rules.

Steps:

(1) Have Built: Given a set of grammar files (currently using the Umple Grammar), my code uses a breadth-first search scan of the AST to find the token for the input element. An instance of the RuleBasedParser is used to generate the tokens. Once found, the token (really a pointer to the token in the tree) is stored in a cache cache local to the module. The cache is static across instances of the module, so I am hoping that this will make the process significantly more efficient. Especially when/if we add larger grammars.

(2) Needs to be built: The GrammarAnalyzer populates tokens as it tokenizes the code. I need to invert this process so that the data is instead extracted from an UmpleElment and UmpleModel. This is also where the assumptions we've made about naming can really be useful. If the general analyzer cannot handle a given input, then it can delegate it to a language-specific grammar analyzer. In my code so far, I have used the term 'contextual analysis' to be the broad, generic analysis based on the root token. 'Language-specific' analysis handles delegation.

Right now the elements and model have a whole bunch of getters for different properties. I don't want to do an overhaul of this, but in my design I would like to have a single properties map so that I can easily find and handle exactly the attributes of a Classifier (for example).

(3) Have Built: A depth-first traversal of the parsed tokens graph to generate the output code. It currently uses a stringbuilder, although once I have my code doing full translations of large codebases, I want to see if we can make it more efficient by writing to the output files on this pass. I know in Java we can control flushing, to an extent. But I am not sure if this kind of overhead (ie, writing to a buffer on each recursion) will yield any benefit.

I mentioned last week that my goal was to have empty classes generated by this week. I suppose the code could output an empty shell since it can locate the classDefinition in the graph and any empty class is composed of just Terminals. But it's sort of pointless right now as I am working on step (2) which will encapsulate this. If I can make good headway on (2) this week, then I will be tres pleased.

October 23-27

I spent this time researching and strategizing for issue 447 (on Google Code), and I have a plan and have written the base template for my code. I see now that there is going to be a substantial amount of code in my solution, so I want to make frequent commits (without breaking anything else). I would like to be translating into empty classes this week, which means I need the base of my algorithm completed. With this in-place, I will probably spend half of my time understanding the exact implementation of other aspects of the application (like associations and state machines) and the other half fitting it into my template.

How is language translation currently done? Independent language generators solve the problem with the help of the jet template output (language ClassGenerator or InterfaceGenerator). The generator acts as the manager, handling output and exceptional cases. The generator also handles some of the translation through the overloaded translate functions, which are called by ClassGenerator and InterfaceGenerator. I am not really sure why this happens, perhaps for logical organization or to prevent code duplication.

Files are processed asynchronously by the generator in a multithreaded fashion. I wonder if this is the race condition that was producing the missing symbol issue that some of us have had? This would depend on when the code is pushed to the language-specific compilers. Note to look into this.

Algorithm Template Instance: A set of n boxes that can be composed of other boxes within the set; "terminal boxes" have lexical value. A terminal box can be found by following a digraph from any box. An empty digraph implies a root box has been found. There is a special root box, call it , of which the output is the input or 'test token value'.

Problem: Given a set of m lexical entries, find the best-fit subset of boxes and produce the root boxes.

Idea: Solve the best-fit problem using the similar techniques to matching the longest substring (like KMP or something similar). Store result in hashmap for constant time lookup later (for something like a method declarations that are frequent, this will be very useful!). Follow the digraph to the root box and output its lexical value, which if the special box is simply the token value.

Now, this idea implies that we have no knowledge of the structure of a grammar. But, since this is the first implementation, I can make assumptions based on my knowledge of Umple's grammar. If we assume that some definitions will always exist, it becomes a simple binary test independent of the output language. For example, consider the concreteClassDeclaration in the grammar. If all languages use this as the template name, then I know when processing a class token that I want to use the concreteClassDeclaration all the time.

Whether or not I use these assumptions, I am not yet sure. Although it could be useful, we have to question whether the cost of using it is worth the cost of maintenance. That is, changing the name 'concreteClassDefinition' would have to also be changed in my code.. Do we "need" this? For now, I don't think so. Until I start adding complex analysis, I don't think it will make my impl any cleaner.

October 16th-17th

I committed changes to Issue 434 (on Google Code) and 422, although I must have linked incorrectly in my svn message because the comment/change did not appear on the issues.. For 422, I committed the fix so that creating an abstract method => an abstract class. I completed 434.

I also worked on replicating the class inheritance behaviour for interfaces, but it looks we actually want to differentiate handling mathods between implementation and extending. For implementing an interface, the methods are automatically added to its child. For extending classes, the subclasses will remain abstract until an implementation of the method is found. (Note: I kept my implementation for interfaces, in case we want to change this later on. It was not as trivial as I had hoped..)

I ran into an issue with committing because I was using the wrong password. It's unintuitive because I use my gmail password to checkout the code, but then commit with a different password. Note to future committers, you can find your password here.

svn: Commit failed (details follow):
svn: MKACTIVITY of '/svn/!svn/act/1e24d800-ada8-4a39-915b-ddf0c6e3edca': authorization failed: Could not authenticate to server: rejected Basic challenge (https://umple.googlecode.com)

As well, I created a formal wiki page for setting up a Vagrant VM: https://code.google.com/p/umple/wiki/DeveloperVirtualMachine

October 15th

This morning I eliminated the test failures caused by my abstract implementation. The issues was that because I handled it recursively, there was a potential for cycles. I didn't check this before because I saw that we already do a check for cycles; however, it seems that finding a cycle doesn't actually change the state of the compiler. So there isn't a way (that I found) to simply halt processing if a cycle is found. I'm curious why compilations isn't actually halted when a compromising error like this is found... Anyway, I fixed this with a simple visited parameter, since we assume a linear branch (1 superclass).

I am going to hold off committing this until after my exam tomorrow afternoon, on the off chance that it conflicts with someone else's work. Although all tests are passing, so this shouldn't be an issue. But, I remember at the code sprint it was mentioned that we shouldn't commit unless we have time to hang around, which I do not right now.

October 9th - Log 3

Regarding the grammars for different languages, which is my main project for the remainder of the term. I've realized that by adding these grammars, this will also enable users to import existing projects written in other languages into Umple. Future comments related to this will be added to issue 447 (on Google Code).

October 9th - Log 2

Unimplemented Methods in Ancestors => Abstract Class This was sort of tricky because classes are unordered when they're parsed and there are not bidirectional relationships from between classes and their children. However, I was able to use an recursive procedure to store the state as I did a bottom-up handling of each class' ancestors. This was added during the second-pass of token parsing, to ensure that relationships between classes have already been satisfied.

Right now my solution is causing a couple of tests to fail, which I expected because the compiler no longer adds methods with empty bodies of ancestry methods. I'll have to modify these tests.

October 9th

Solution to missing symbols: I narrowed a correlation, but don't quite yet understand the cause. Exact steps to reproduce:

  1. Break the compiler by referencing an unknown method (I broke UmpleInternalParser), then you'll get a missing symbol error when you compile Umple.
  2. Fix the missing symbol
  3. Recompile Umple
  4. You will still get the missing symbol error by Java's compiler.
  5. Okay, I'll remove the Java file so that Umple needs to recreate it. However, Umple will not. Instead, you'll get several seemingly unrelated Missing Symbol errors, referencing the now non-existent Java file.

Solution: Add the following aliases, and run 'ufclean'

alias cd-u='cd /Users/hysz/Documents/umple/workspace'     # Modify this to have your workspace
alias cd-ucruise='cd-u; cd cruise.umple'
alias clean-umple='cd-ucruise; cd src-gen-umple; svn revert -R .; cd -'
alias uclean='clean-umple; clean-jet'
alias ufclean='uclean; uget-compiler'

What this does is revert the Java files created by Umple and then fetch a new copy of the jar. This should be added as an Ant task so that running something like 'ant clean' will do this for you.

September 30 - October 7th

Earlier this week I worked on the issues I raised relevant to creating abstract classes and methods. I've made it so that if a method is abstract, it will make its containing class abstract as well. I originally didn't do this because it may not be a requirement for every language (ex, adding a virtual method in c++ doesn't require any class modifiers). However, since this is up to the language, we can set the property and if the language handler wants to ignore the attribute then it can. I also worked on a solution for the problem of inheriting abstract methods. In the issue, I had written that methods declared in interfaces are added to implementing classes, although I wasn't seeing that behaviour when I started working on the issue. Perhaps that has changed since I first raised it. Anyway, I figured the best solution was to leave it up to the developer to implement methods, rather than just adding an empty container. If the method hasn't been implemented, then it makes the class abstract. This is a little more tricky because the method may be implemented by a grand child, great grandchild, or a further descendent. In such cases, we don't want to have to query all the way back up the tree. The current implementation is that if a method not to be implemented, it is not added to the class object. I am currently modifying this so that it will store abstract methods that weren't implemented. That way, a class need only query its parent.

While working on these issue, I consistently ran into problems with 'missing symbols' that were completely unrelated to my code. I've seen this before with the order that files are compiled; which is often caused by missing dependencies. I was able to reproduce this when I deleted the class files in cruise.umple/bin, but with a fresh checkout the compiler I am not seeing this. I've had this issue before and resolved it by fetching a new jar file, but I really want to find out exactly what's causing this because it's a really annoying issue. I some time learning about apache ant.

I also uncovered some issues in PHP's jet file, while working on adding the 'abstract method => abstract class' update to PHP. I fixed them in my local copy by just removing the referenced jet files, although I can't commit that to svn. I think the actual issue was resolved by another developer over the weekend, so I'll look at that this week.

I also came up with an interesting idea that I will spend most of this term researching and building:

-- Idea --

While waiting for the PHP stuff to be resolved, I started reading more into the jet templates and the language-specific compiler modules. And from what I've read in the code, this seems to be the general workflow:

  1. Interpret Umple code and generate a token tree > 2. Parse the tokens and perform general logic (relationship mapping, etc.) > 3. Pass the tokens to language-specific modules for additional parsing > 4. Pass the tokens to the jet templates for output generation

Now, from what I've seen, there is a lot of duplicate logic embedded in the templates. This creates a lot of interdependencies within the system, and it means that making even small changes (like adding abstract classes/methods :D) need to be made in several places. Does it need to be so cumbersome, or can we completely abstract away the logic from the output generation?

Consider the following workflow:

  1. Interpret Umple code and generate a token tree > 2. Parse the tokens and perform general logic (relationship mapping, etc.) > 3. Pass the tokens to language-specific modules for additional parsing > 4. Pass the tokens to a single output module which generates the output language

How would such a module (#4) be implemented? It's actually simple. We replace jet templates with grammars for each language, and then query the grammar to construct the language-specific output. Now, modifying a language's syntax can be done very easily, and Umple becomes a standalone parser with no dependency on Jet. But best of all, we have self-contained logic!

One more benefit of this kind of setup is that we could then have perform bidirectional translations between languages.

I'll have a good chunk of time to work on this stuff in the latter half of this week.

September 22nd - Log 2

This weekend I accomplished adding abstract methods in PHP and Java, and adding abstract classes to PHP. I also cleaned up the method generation templates for PHP and Java. I raised a few more issues relevant to creating abstract classes and methods, for example making a class abstract if it does not implement an abstract method of the parent.

I plan to spend a few hours this week wrapping up abstract classes/methods. Also this week I will start adding the Factory pattern. I will then look into improving Ruby generation and possibly adding support for Python, if time permits. I may also look into improving the base framework for adding new languages.

September 22nd

This weekend at UCOSP was extremely productive. I mostly had issues with building and cleaning my build. I ran into some really strange problems, for example I would change a jet template, propagate the changes (ubuild-jet), and then run ubuild-all, but the java files would not be updated. Apparently this can be resolved by grabbing a new umple.jar (see uget-compiler).

I created the following aliases to make development faster:

alias cd-u='cd /Users/hysz/Documents/umple/workspace'
alias cd-ubuild='cd-u; cd build/'
alias cd-ucruise='cd-u; cd cruise.umple'
alias cd-usrc='cd-ucruise; cd src'
alias cd-udist='cd-u; cd dist'
alias ubuild-all='cd-ubuild; ant -Dmyenv=local -f build.umple.xml build; cd -'
alias ubuild-quick='cd-ubuild; ant -Dmyenv=local -f build.umple.xml pre_build; cd -'
alias ubuild-online='cd-ubuild; ant -Dmyenv=local; ant -DshouldPackageUmpleOnline=true -Dmyenv=local -f build.umple.xml packageUmpleonline; cd -'
alias ubuild-compiler='cd-ubuild; ant -Dmyenv=local -f build.umple.xml umpleSelf compile packageMainJar; cd -'
alias ubuild-jet='cd-ubuild; ant -f build.umple.xml -Dmyenv=local codegen; cd -'
alias ubuild-version='cd-ubuild; ant -Dmyenv=local -f build.umple.xml template.resetVersion compile'
alias utest='cd-ubuild; ant -Dmyenv=local -f build.umple.xml template.test; cd -'
alias uget-compiler='cd-udist; rm umple.jar; wget http://try.umple.org/scripts/umple.jar; cd -'
alias show-err='cat /Users/hysz/Documents/umple/workspace/umple-read-only/dist/qa/cruise.umple/index.html; cd -'
alias clean-umple='cd-ucruise; cd src-gen-umple; svn revert -R .; cd -'
alias clean-jet='cd-ucruise; cd src-gen-jet; svn revert -R .; cd -'
alias uclean='clean-umple; clean-jet'
alias make-umple='clean-umple && ubuild-all'

September 20th

I just setup umpleonline on my macbook and have some additional/modified steps for configuring apache2 for umpleonline.

  1. Devs need to ensure that the parent directories of umpleonline have execute permission for the web user
  1. umpleonline/ump needs to have write permissions for the web user

  2. If we swap the ip for the host when defining the VirtualHost, then we can access umpleonline without including the document root in the URL:

- <VirtualHost 127.0.0.1:80>
+ <VirtualHost cruise.local:80>
   DocumentRoot "/Users/hysz/Documents/umple/workspace/umpleonline"
   ServerName cruise.local
   ErrorDocument 404 /404.shtml
</VirtualHost>
  1. In case developers aren't familiar with apache2, we should recommend they look in /var/log/apache2 if errors arise.

September 13th-20th

This past week I started working on setting up a Vagrant VM.

Some high level steps: Prereq 1: have Ruby installed. I used RVM to get Ruby 1.9.3: rvm get stable rvm install 1.9.3 source ~/.rvm/scripts/rvm type rvm | head -n 1 rvm use 1.9.3 --default

Step 1. Get the latest version of VirtualBox Step 2. Get the latest version of Vagrant Step 3. Get the latest version of Packer to create a base Ubuntu box. I usually use Veewee, but find that it never works out of the box, whereas Packer seems to. Step 4. Create a JSON template for Packer: [ubuntu-13.04-template.json]

{
  "builders": [
    {
      "type": "virtualbox",
      "guest_os_type": "Ubuntu_64",
      "iso_url": "http://releases.ubuntu.com/13.04/ubuntu-13.04-desktop-amd64.iso",
      "iso_checksum": "8d72e2db7e72e13813731eab37a14d26",
      "iso_checksum_type": "md5",
      "ssh_username": "packer",
      "shutdown_command": "shutdown -P now"
    }
  ],

  "provisioners": [
  ],

  "post-processors": [
    {
        "type": "vagrant"
    }
  ]
}

Step 5. Run 'packer build ubuntu-13.04-template.json' Step 6. Shutdown the vm from VirtualBox interface Step 7: Package the box with Vagrant: "vagrant package --base 'name of VM as displayed in VirtualBox' Step 8: Create the following Vagrantfile [my.Vagrantfile]

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # All Vagrant configuration is done here. The most common configuration
  # options are documented and commented below. For a complete reference,
  # please see the online documentation at vagrantup.com.

  # Every Vagrant virtual environment requires a box to build off of.
  config.vm.box = "umple-dev"
  config.vm.hostname = "umple-dev"

  # The url from where the 'config.vm.box' box will be fetched if it
  # doesn't already exist on the user's system.
  # config.vm.box_url = "http://domain.com/path/to/above.box"

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine. In the example below,
  # accessing "localhost:8080" will access port 80 on the guest machine.
  # config.vm.network :forwarded_port, guest: 80, host: 8080

  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
   config.vm.network :private_network, ip: "192.168.33.10"

  # Create a public network, which generally matched to bridged network.
  # Bridged networks make the machine appear as another physical device on
  # your network.
   config.vm.network :public_network

  # If true, then any SSH connections made will enable agent forwarding.
  # Default value: false
  # config.ssh.forward_agent = true

  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
  # config.vm.synced_folder "../data", "/vagrant_data"

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  #
   config.vm.provider :virtualbox do |vb|
     # Don't boot with headless mode
     vb.gui = true

    # Use VBoxManage to customize the VM. For example to change memory:
    vb.customize ["modifyvm", :id, "--memory", "1024"]
  end
  #
  # View the documentation for the provider you're using for more
  # information on available options.

  # Enable provisioning with Puppet stand alone.  Puppet manifests
  # are contained in a directory path relative to this Vagrantfile.
  # You will need to create the manifests directory and a manifest in
  # the file base.pp in the manifests_path directory.
  #
  # An example Puppet manifest to provision the message of the day:
  #
  # # group { "puppet":
  # #   ensure => "present",
  # # }
  # #
  # # File { owner => 0, group => 0, mode => 0644 }
  # #
  # # file { '/etc/motd':
  # #   content => "Welcome to your Vagrant-built virtual machine!
  # #               Managed by Puppet.\n"
  # # }
  #
  # config.vm.provision :puppet do |puppet|
  #   puppet.manifests_path = "manifests"
  #   puppet.manifest_file  = "site.pp"
  # end

  # Enable provisioning with chef solo, specifying a cookbooks path, roles
  # path, and data_bags path (all relative to this Vagrantfile), and adding
  # some recipes and/or roles.
  #
  # config.vm.provision :chef_solo do |chef|
  #   chef.cookbooks_path = "../my-recipes/cookbooks"
  #   chef.roles_path = "../my-recipes/roles"
  #   chef.data_bags_path = "../my-recipes/data_bags"
  #   chef.add_recipe "mysql"
  #   chef.add_role "web"
  #
  #   # You may also specify custom JSON attributes:
  #   chef.json = { :mysql_password => "foo" }
  # end

  # Enable provisioning with chef server, specifying the chef server URL,
  # and the path to the validation key (relative to this Vagrantfile).
  #
  # The Opscode Platform uses HTTPS. Substitute your organization for
  # ORGNAME in the URL and validation key.
  #
  # If you have your own Chef Server, use the appropriate URL, which may be
  # HTTP instead of HTTPS depending on your configuration. Also change the
  # validation key to validation.pem.
  #
  # config.vm.provision :chef_client do |chef|
  #   chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
  #   chef.validation_key_path = "ORGNAME-validator.pem"
  # end
  #
  # If you're using the Opscode platform, your validator client is
  # ORGNAME-validator, replacing ORGNAME with your organization name.
  #
  # If you have your own Chef Server, the default validation client name is
  # chef-validator, unless you changed the configuration.
  #
  #   chef.validation_client_name = "ORGNAME-validator"
end

Step 9: Run the following Shell Script [install.sh]

#!/bin/bash

VM_NAME="umple-dev"
PACKAGE="package.box"
SOURCE_VAGRANTFILE="my.Vagrantfile"
SINK_VAGRANTFILE="Vagrantfile"

vagrant box add "$VM_NAME" "$PACKAGE" --force
vagrant init "$VM_NAME"
cp "$SOURCE_VAGRANTFILE" "$SINK_VAGRANTFILE"
vagrant up

exit 0

4.

September 11th - Post 2

I setup the dev environment last week, but I still don't have it working in eclipse.. I wonder if we would benefit from having an Umple Dev VM. That way, anyone who wants to start working on the project can just download the dev VM and go at it. This could be easily maintained, distributed, and installed using Vagrant. I am willing to set this up, if it's considered worthwhile. I will probably do it anyway for myself, as I've had to modify my Mac's environment just for this project.

EDIT: Got it working in Eclipse. I just had to import the source folders nested in cruise.umple manually.

September 11th

Last week, I spent time familiarizing myself with Umple and the development process. There was plenty of documentation, so this was not difficult. I also came across the list of open issues. One that caught my eye was regarding investigating design patterns. I headed back to the main site and found an area that listed different design patterns that are supported by Umple. This is really cool, and I think it would be worthwhile to integrate more patterns. Earlier this year, I purchased a book, Design Patterns, and it has helped speed up my design process significantly. Umple currently has only a small subset of patterns that are found in this book.

However, we need to think about which patterns would be most useful. Between now and the code sprint, I would like to investigate this further. On the same note, it may be interesting to look into different data structures we could implement. But, I'm getting a bit ahead of myself. I feel like I should build something useful with Umple, and see how my code could be simplified further if Umple had additional patterns and data structures. I would also like to tackle a few smaller issues between now and then to get more comfortable with the codebase.

I also finished working full-time at my co-op last week, so I have more time to spend working on Umple this week.