Getting Started with Origen
Understanding Gems
Ruby gems is the de facto standard package manager used by the Ruby community. This allows Ruby code to be packaged up so that it can be used throughout the community while being maintained from a single source. RubyGems.org provides free, centralized hosting for these gems and anyone can create a new gem and upload it there.
The job of a dependency manager is to resolve the gem version requirements of all gems used within an application (an application can depend on a gem, which may itself depend on other gems), so that they will all have access to a runtime environment containing the correct versions of the gems that they need. At the time of writing, the Ruby gems system does not provide dependency management and this roll is fulfilled by a 3rd party tool called Bundler (though it is planned for Bundler to be integrated into Ruby gems in future).
Origen and all of its plugins are distributed as Ruby gems and Bundler is used for the dependency management.
This guide will teach you how to use Ruby gems within your applications, tell you what you need to know about using Bundler within the context of an Origen application, and give you an appreciation for how the Origen runtime environment works.
Every Origen application has a file named Gemfile
in its root directory, this is where
the gem dependencies for the given application will be specified.
Here is an example Gemfile:
source 'https://rubygems.org' gem 'origen', '>= 0.5' gem 'origen_debuggers' gem 'roo' gem 'origen_testers', path: '/path/to/local/origen_testers' gem 'origen_jtag', git: 'https://github.com/Origen-SDK/origen_jtag.git', ref: 'ad323f'
Points to note on the above:
- The source line specifies the gem library where the gems are hosted, in the Ruby community every gem is hosted on rubygems.org. Multiple sources can be used, and in practice for an Origen application this means that you can also add a company internal gem server to host private Origen plugins (see below).
- The
origen
gem import line shows how you can specify a dependency on a specific (or in this case minimum) version of a given gem. See this section section of the RubyGems.org documentation for details on how to specify version numbers within a semantic versioning system. - The
origen_debuggers
androo
lines show how to add Origen plugins and non-Origen gems to your application - the process is identical. Note that with no version specifier the latest production version will be fetched when your gem bundle is built. - The
origen_testers
line shows how to use a local copy of a given gem/plugin, this allows you to make changes to the given gem to add a feature or fix a bug, and then try it out within your application. Origen will not allow execution with a path reference in production mode, since it is an inherently a non-reproducible environment for the future. - Git references can also be used, here to pick up a specific commit of the
origen_jtag
gem direct from its repository. This can be used to pick up a pre-release version of a gem that contains a specific feature or bug fix that you need immediately.
The Gemfile system is provided by Bundler and the Bundler guide on Gemfiles can be consulted for more information.
Origen takes care of setting up Bundler so that it will work in the common corporate scenario where the user does not have the root access required to install the gems to the system Ruby installation. To ensure that Bundler is properly configured, it is critical that an Origen command is run first in a new application workspace, before any attempts are made to run Bundler directly.
A common way of doing this is simply to run the origen -v
command upon first setting
up a new application workspace. This command will invoke Bundler with the required configuration
automatically and all of the required gems will be installed to ~/.origen/gems
.
Unfortunately Origen has not yet managed to completely wrap Bundler and sometimes there will be a need to invoke it directly. This usually occurs when you have changed the version requirements of a particular gem within your Gemfile.
Once you have changed the requirement you should run:
bundle update <gem_name>
This will tell Bundler to update the version of the given gem, but leave the versions of everything else as they are. Sometimes however the new version of the given gem will itself require a new version of some other dependent gem, in that case you will get an error and you can try running this command to resolve it:
bundle
If you still have an error, then updating the complete bundle will resolve it:
bundle update
Note that this will fetch the latest version of every gem in your bundle that has an open-ended version dependency. This can result in more changes to your environment than you really want/need and is therefore usually best kept as a last resort.
As experience with Origen grows, you will begin to start creating your own plugins/gems, many of which will contain company proprietary IP that you will not want to release via the open source community. Therefore a way of privately hosting these gems is required.
An easy way of doing this initially is to use Git as the revision control tool for your plugins, then you can use Git references within your Gemfiles as discussed above.
A better solution though, is to setup a gem server within your company intranet, and we recommend this server. You will likely need to work with your IT department to get this setup and maintained.
When it is available, simply update your Gemfiles with the additional server like this:
source 'https://rubygems.org' source 'https://gems.mycompany.net:9292' gem 'origen' gem 'private_test_block' #...
At that point you should also update your company’s Origen configuration
with the details of the new server, in that way the origen new
command will automatically
configure your new applications with the required source reference in the Gemfiles.
A file called Gemfile.lock
will be created by Bundler in the application’s top-level
directory and this should be checked into the revision control system.
The purpose of this file is to record the absolute versions of all gems that are currently used by the given application. This means that when another developer, or one of your application’s users, checks out a given version of your application into a new workspace, then the exact same gem versions will be used as when it was originally tested and checked in.
This means that it safe (and in fact recommend) to leave the gem versions largely unspecified by your Gemfile, as it does not mean that different user environments will be running different gem versions.
If your gems provide command line executables that you wish to run, then these need to be invoked through
Bundler to make them run within the context of the application’s gem environment (bundle).
Say for example that a given gem provides an executable called clean
, then to run this from your
application’s command line you should do:
bundle exec clean
This applies to the origen
executable too, however as this is cumbersome to write and
easy to forget, Origen employs some tricks that will enforce this wrapping automatically, so Origen
can always be invoked with just:
origen <command>
Bundler will build wrapped executables within an application’s lbin
directory, these
can be invoked directly without the need for the bundle exec
prefix, so for example the
clean
executable could be correctly invoked by running:
./lbin/clean
This is arguably easier to write than bundle exec
, but it can still be easy to forget. Therefore
if your application has a need to run 3rd party executables a lot, then it is recommend to add
the application’s lbin
directory to your path so that you can simply run:
clean
It was noted in the Origen installation guide that the base Origen version installed to your system Ruby does not really matter, and it does not need to be updated to the latest version of Origen on a regular basis.
This is because the base Origen is only used to either create a new Origen application, or to initially boot an Origen command within an existing application. In both cases, the version used to initially boot Origen is unimportant.
In the case of creating a new application, Origen will always pull in the latest and greatest application generator and this is not statically linked to the version of Origen that is being executed to build the new app. Similarly, when running an Origen application the thread will immediately switch over to run the version of Origen specified in the Gemfile instead of the system version.
This system therefore ensures that application owners are in control of what version of Origen is used by the users of their application, however neither the application owner or their users need permissions to update the system Ruby installation in order to achieve the required runtime environment. They simply checkout the version of the given application that they want, and then Origen/Bundler takes care of guaranteeing that the runtime environment is the correct one.
gem install
process will update
the Origen version for you, so this is more of an FYI in case you see your Origen version change after installing
a plugin in the system Ruby.