From Fedora Project Wiki

No edit summary
No edit summary
 
(One intermediate revision by the same user not shown)
Line 3: Line 3:
These directions are clearly not going to be the final workflow. If nothing else, i can't even get <code>brainfuck</code> to compile fully. But it demonstrates fundamentally how the workflow will follow. Most of the steps in this process are pretty generic to alot of kinds of packages. Implementing code to handle the bits for other packages is as simple as coding the steps into Python.
These directions are clearly not going to be the final workflow. If nothing else, i can't even get <code>brainfuck</code> to compile fully. But it demonstrates fundamentally how the workflow will follow. Most of the steps in this process are pretty generic to alot of kinds of packages. Implementing code to handle the bits for other packages is as simple as coding the steps into Python.


== Getting the Source ==
= Getting the Source =
In order to begin, you will need the latest source. Currently, this is only available through git. Open a handy terminal window and follow along.
In order to begin, you will need the latest source. Currently, this is only available through git.


<pre>
Follow the directions in the [[Devshell development | Development Guide]] in order to get the latest upstream.
$ git clone git://git.fedorapeople.org/home/fedora/ynemoy/public_git/fedora-devshell.git
 
</pre>
A package for Fedora is currently being submitted for review.


Since this is the raw upstream, there's a chance the code may not work.
Since this is the raw upstream, there's a chance the code may not work.


== Launching Ports ==
= Launching Ports =


Since there are no built in tools yet for building a package, the only way to interact with the code is via the source directory itself. Therefore it's necessary to modify the command line path to make this work.
Since there are no built in tools yet for building a package, the only way to interact with the code is via the source directory itself. Therefore it's necessary to modify the command line path to make this work.
Line 19: Line 19:
$ export PATH=/path/to/fedora-devshell/:$PATH
$ export PATH=/path/to/fedora-devshell/:$PATH


$ ports.py
$ ports  
  * PackageSource
  * PackageSource
  * SourceBall
  * SourceBall
Line 61: Line 61:
  * Package
  * Package
Traceback (most recent call last):
Traceback (most recent call last):
   File "/path/to/fedora-devshell/ports.py", line 36, in <module>
   File "/path/to/fedora-devshell/ports", line 36, in <module>
     main()
     main()
   File "/path/to/fedora-devshell/ports.py", line 31, in main
   File "/path/to/fedora-devshell/ports", line 31, in main
     output, module, params = do_command(args)
     output, module, params = do_command(args)
   File "/path/to/fedora-devshell/base/base.py", line 176, in do_command
   File "/path/to/fedora-devshell/base/base.py", line 176, in do_command
Line 73: Line 73:
This confirms that the code is running at least partially. The list of names there is a list of the available modules, albeit repeated.
This confirms that the code is running at least partially. The list of names there is a list of the available modules, albeit repeated.


== Setting up a project ==
= Setting up a project =


Currently, Fedora Devshell can only work with Haskell programs, especially ones hosted on Hackage, the Haskell package repository. It also only works with packages managed by Darcs, the Haskell distributed version control system.  Let's get a package and start playing with it.
Currently, Fedora Devshell can only work with Haskell programs, especially ones hosted on Hackage, the Haskell package repository. It also only works with packages managed by Darcs, the Haskell distributed version control system.  Let's get a package and start playing with it.
<pre>
<pre>
$ ports.py package brainfuck
$ ports package brainfuck


$ cd brainfuck/
$ cd brainfuck/
Line 92: Line 92:
We've started a new package called brainfuck.
We've started a new package called brainfuck.
<pre>
<pre>
brainfuck $ ports.py haskellport add_latest brainfuck
brainfuck $ ports haskellport add_latest brainfuck


brainfuck $ ls -Al
brainfuck $ ls -Al
Line 132: Line 132:
</pre>
</pre>


== Editing the package ==
= Editing the package =


This gets the latest upstream tarball from hackage. Let's do a bit of hacking. Let's assume that brainfuck's not FHS compliant, and we need to put a quick patch in to get it into Fedora. Eventually we will send that patch upstream, but the tools for that are still in the works. For now, i'm going to assume that adding lines to the LICENSE file will make it FHS compliant. (In my imaginary world, we also have cookies.)
This gets the latest upstream tarball from hackage. Let's do a bit of hacking. Let's assume that brainfuck's not FHS compliant, and we need to put a quick patch in to get it into Fedora. Eventually we will send that patch upstream, but the tools for that are still in the works. For now, i'm going to assume that adding lines to the LICENSE file will make it FHS compliant. (In my imaginary world, we also have cookies.)
Line 173: Line 173:


<pre>
<pre>
brainfuck/brainfuck-0.1 $ ports.py sourceball generate_patch FHS.compliance
brainfuck/brainfuck-0.1 $ ports sourceball generate_patch FHS.compliance


brainfuck/brainfuck-0.1 $ ls .pkg_src/
brainfuck/brainfuck-0.1 $ ls .pkg_src/
Line 194: Line 194:
  authors' reputations.
  authors' reputations.


brainfuck/brainfuck-0.1 $ ports.py sourceball import_other_patch ../moar.FHS.patch 0
brainfuck/brainfuck-0.1 $ ports sourceball import_other_patch ../moar.FHS.patch 0


brainfuck/brainfuck-0.1 $ ls .pkg_src/
brainfuck/brainfuck-0.1 $ ls .pkg_src/
Line 200: Line 200:
0002.moar.FHS.patch        branches/            patch.log
0002.moar.FHS.patch        branches/            patch.log


brainfuck/brainfuck-0.1 $ ports.py sourceball clean_orig
brainfuck/brainfuck-0.1 $ ports sourceball clean_orig


brainfuck/brainfuck-0.1 $ ports.py sourceball verify_patches 'orig'
brainfuck/brainfuck-0.1 $ ports sourceball verify_patches 'orig'
[INFO] Verified clean patches: True
[INFO] Verified clean patches: True
</pre>
</pre>
Line 208: Line 208:
The 0 in the last command is what would ordinarily be passed to the argument <code>-p</code> to <code>patch</code>. We can also tell that the patches apply to the source code cleanly. Next we want to make a spec file.
The 0 in the last command is what would ordinarily be passed to the argument <code>-p</code> to <code>patch</code>. We can also tell that the patches apply to the source code cleanly. Next we want to make a spec file.


== Creating an RPM ==
= Creating an RPM =


<pre>
<pre>
brainfuck/brainfuck-0.1 $ ports.py cabal . gen_spec brainfuck
brainfuck/brainfuck-0.1 $ ports cabal . gen_spec brainfuck


brainfuck/brainfuck-0.1 $ ls -A
brainfuck/brainfuck-0.1 $ ls -A
Line 227: Line 227:
brainfuck $ cd ..
brainfuck $ cd ..


$ ports.py profile profiles/devel configure_from_system devel
$ ports profile profiles/devel configure_from_system devel


$ cd brainfuck/
$ cd brainfuck/


brainfuck $ ports.py package fetch_sourceballs
brainfuck $ ports package fetch_sourceballs


brainfuck $ ls -Al
brainfuck $ ls -Al
Line 255: Line 255:
~/rpmbuild/SRPMS:
~/rpmbuild/SRPMS:


$ ports.py build ~/rpmbuild setup_source brainfuck
$ ports build ~/rpmbuild setup_source brainfuck


$ ls -l ~/rpmbuild/*  
$ ls -l ~/rpmbuild/*  
Line 285: Line 285:
<code>mock</code> will actually run setup_sources for us later on. This just demonstrates what it does. The code is also a bit half-baked.
<code>mock</code> will actually run setup_sources for us later on. This just demonstrates what it does. The code is also a bit half-baked.


== Building the RPM in Mock ==
= Building the RPM in Mock =


<pre>
<pre>
$ ports.py mock profiles/devel ~/rpmbuild build_rpm brainfuck
$ ports mock profiles/devel ~/rpmbuild build_rpm brainfuck
[INFO] mock compiling brainfuck-0.1-1.fc10.src.rpm... please wait
[INFO] mock compiling brainfuck-0.1-1.fc10.src.rpm... please wait


Line 343: Line 343:
In reality, setting up the source is not necessary. In the latest upstream, mock.build_rpm can actually set up the source for you.
In reality, setting up the source is not necessary. In the latest upstream, mock.build_rpm can actually set up the source for you.


== Conclusion ==
= Conclusion =


Clearly <code>mock</code> failed. I guess that spec file wasn't perfect. Because of the use of symlinks, however, i can simply edit the spec file, make the necessary changes, and rerun the command to initialize <code>mock</code>. Fedora Devshell will automatically build the source RPM, and send the appropriate command to <code>mock</code> to use a premade profile. There will be more you can do with this here.
Clearly <code>mock</code> failed. I guess that spec file wasn't perfect. Because of the use of symlinks, however, i can simply edit the spec file, make the necessary changes, and rerun the command to initialize <code>mock</code>. Fedora Devshell will automatically build the source RPM, and send the appropriate command to <code>mock</code> to use a premade profile. There will be more you can do with this here.

Latest revision as of 06:10, 30 April 2009

This guide explains in several easy steps how to get started with Devshell. It goes through the steps of getting the source, and building a sample Haskell package in not so many not so easy steps.

These directions are clearly not going to be the final workflow. If nothing else, i can't even get brainfuck to compile fully. But it demonstrates fundamentally how the workflow will follow. Most of the steps in this process are pretty generic to alot of kinds of packages. Implementing code to handle the bits for other packages is as simple as coding the steps into Python.

Getting the Source

In order to begin, you will need the latest source. Currently, this is only available through git.

Follow the directions in the Development Guide in order to get the latest upstream.

A package for Fedora is currently being submitted for review.

Since this is the raw upstream, there's a chance the code may not work.

Launching Ports

Since there are no built in tools yet for building a package, the only way to interact with the code is via the source directory itself. Therefore it's necessary to modify the command line path to make this work.

$ export PATH=/path/to/fedora-devshell/:$PATH

$ ports 
 * PackageSource
 * SourceBall
 * Audit
 * Directory
 * Profile
 * Directory
 * BuildSystem
 * Darcs
 * Hackage
 * HaskellPort
 * Port
 * SourceBall
 * Darcs
 * RevisionControl
 * Build
 * Directory
 * Package
 * Profile
 * BuildSystem
 * Cabal
 * SourceBall
 * Directory
 * Repo
 * Directory
 * PackageSource
 * Bugs
 * Mail
 * Source
 * Build
 * Mock
 * Package
 * Profile
 * Port
 * PackageSource
 * RevisionControl
 * Fetcher
 * Fetcher
 * Hackage
 * Directory
 * Package
Traceback (most recent call last):
  File "/path/to/fedora-devshell/ports", line 36, in <module>
    main()
  File "/path/to/fedora-devshell/ports", line 31, in main
    output, module, params = do_command(args)
  File "/path/to/fedora-devshell/base/base.py", line 176, in do_command
    output = top(*params)
TypeError: 'NoneType' object is not callable

This confirms that the code is running at least partially. The list of names there is a list of the available modules, albeit repeated.

Setting up a project

Currently, Fedora Devshell can only work with Haskell programs, especially ones hosted on Hackage, the Haskell package repository. It also only works with packages managed by Darcs, the Haskell distributed version control system. Let's get a package and start playing with it.

$ ports package brainfuck

$ cd brainfuck/

brainfuck $ ls -Al
totaal 4
-rw-r--r-- 1 yankee yankee 44 jan 20 22:19 .devshell
brainfuck $ cat .devshell 
type = package
name = brainfuck
sources = ,

We've started a new package called brainfuck.

brainfuck $ ports haskellport add_latest brainfuck

brainfuck $ ls -Al
totaal 8
drwxr-sr-x 4 yankee yankee 4096 jan 20 22:24 brainfuck-0.1/
-rw-r--r-- 1 yankee yankee   57 jan 20 22:24 .devshell

brainfuck $ cd brainfuck-0.1/

brainfuck/brainfuck-0.1 $ ls -Al
totaal 44
-rw------- 1 yankee yankee   852 jun  8  2008 brainfuck.cabal
-rw-r--r-- 1 yankee yankee   200 jan 20 22:24 .devshell
drwx------ 3 yankee yankee  4096 jun  8  2008 Language/
-rw------- 1 yankee yankee 17992 jun  8  2008 LICENSE
-rw------- 1 yankee yankee   439 jun  8  2008 Main.hs
drwxr-sr-x 3 yankee yankee  4096 jan 20 22:24 .pkg_src/
-rw------- 1 yankee yankee    95 jun  8  2008 Setup.hs

brainfuck/brainfuck-0.1 $ cat .devshell 
type = sourceball
name = brainfuck-0.1
tarball_source = http://hackage.haskell.org/packages/archive/brainfuck/0.1/brainfuck-0.1.tar.gz
sourceball = brainfuck-0.1.tar.gz
source = .
buildsystem = cabal

brainfuck/brainfuck-0.1 $ ls .pkg_src/

brainfuck-0.1.tar.gz  branches/
yankee@koan ~/haskell/brainfuck/brainfuck-0.1 $ ls .pkg_src/bra

brainfuck-0.1.tar.gz  branches/             
yankee@koan ~/haskell/brainfuck/brainfuck-0.1 $ ls .pkg_src/branches/

brainfuck-0.1_orig/
yankee@koan ~/haskell/brainfuck/brainfuck-0.1 $ ls .pkg_src/branches/brainfuck-0.1_orig/
brainfuck.cabal  Language/  LICENSE  Main.hs  Setup.hs

Editing the package

This gets the latest upstream tarball from hackage. Let's do a bit of hacking. Let's assume that brainfuck's not FHS compliant, and we need to put a quick patch in to get it into Fedora. Eventually we will send that patch upstream, but the tools for that are still in the works. For now, i'm going to assume that adding lines to the LICENSE file will make it FHS compliant. (In my imaginary world, we also have cookies.)

brainfuck/brainfuck-0.1 $ vi LICENSE

brainfuck/brainfuck-0.1 $ diff -ru -X /path/to/fedora-devshell/diff.excludes .pkg_src/branches/brainfuck-0.1_orig/ .
diff -ru -X /path/to/fedora-devshell/diff.excludes .pkg_src/branches/brainfuck-0.1_orig/LICENSE ./LICENSE
--- .pkg_src/branches/brainfuck-0.1_orig/LICENSE	2008-06-08 18:37:11.000000000 -0400
+++ ./LICENSE	2009-01-20 22:29:40.911210433 -0500
@@ -26,6 +26,8 @@
 in new free programs; and that you know you can do these things.
 
   To protect your rights, we need to make restrictions that forbid
+
+
 anyone to deny you these rights or to ask you to surrender the rights.
 These restrictions translate to certain responsibilities for you if you
 distribute copies of the software, or if you modify it.
@@ -33,6 +35,8 @@
   For example, if you distribute copies of such a program, whether
 gratis or for a fee, you must give the recipients all the rights that
 you have.  You must make sure that they, too, receive or can get the
+
+
 source code.  And you must show them these terms so they know their
 rights.
 
@@ -43,6 +47,7 @@
   Also, for each author's protection and ours, we want to make certain
 that everyone understands that there is no warranty for this free
 software.  If the software is modified by someone else and passed on, we
+RMS has a big beard.
 want its recipients to know that what they have is not the original, so
 that any problems introduced by others will not reflect on the original
 authors' reputations.

As you can see, keeping the original code tree around is convenient, because we can run diff's easily.

brainfuck/brainfuck-0.1 $ ports sourceball generate_patch FHS.compliance

brainfuck/brainfuck-0.1 $ ls .pkg_src/
0001.FHS.compliance.patch  brainfuck-0.1.tar.gz  branches/  diff.log  patch.log

This creates our first patch. It's ordered for reasons that will be obvious shortly. Later in the workflow, someone hands you a second patch, which you want to import into the package. Apparently you couldn't make the package FHS compliant enough.

brainfuck/brainfuck-0.1 $ cat ../moar.FHS.patch 
diff -ru -X /path/to/fedora-devshell/diff.excludes .pkg_src/branches/brainfuck-0.1_orig/LICENSE ./LICENSE
--- .pkg_src/branches/brainfuck-0.1_orig/LICENSE	2009-01-20 22:37:21.186153827 -0500
+++ ./LICENSE	2009-01-20 22:36:21.964170098 -0500
@@ -48,6 +48,7 @@
 that everyone understands that there is no warranty for this free
 software.  If the software is modified by someone else and passed on, we
 RMS has a big beard.
+It's probably going gray.
 want its recipients to know that what they have is not the original, so
 that any problems introduced by others will not reflect on the original
 authors' reputations.

brainfuck/brainfuck-0.1 $ ports sourceball import_other_patch ../moar.FHS.patch 0

brainfuck/brainfuck-0.1 $ ls .pkg_src/
0001.FHS.compliance.patch  brainfuck-0.1.tar.gz  diff.log
0002.moar.FHS.patch        branches/             patch.log

brainfuck/brainfuck-0.1 $ ports sourceball clean_orig

brainfuck/brainfuck-0.1 $ ports sourceball verify_patches 'orig'
[INFO] Verified clean patches: True

The 0 in the last command is what would ordinarily be passed to the argument -p to patch. We can also tell that the patches apply to the source code cleanly. Next we want to make a spec file.

Creating an RPM

brainfuck/brainfuck-0.1 $ ports cabal . gen_spec brainfuck

brainfuck/brainfuck-0.1 $ ls -A
brainfuck.cabal  .devshell   Language/  Main.hs    Setup.hs
brainfuck.spec   .devshell~  LICENSE    .pkg_src/

brainfuck/brainfuck-0.1 $ cd ..

brainfuck $ ls -A
brainfuck-0.1/  brainfuck.spec  .devshell  moar.FHS.patch

I've skipped the steps about integrating patches into the spec file, and updating it with all the vital bits. haskellports uses cabal2spec which means you have to fill in all the little bits later. Rather, we're going to jump right away to compiling RPMs. Currently, Haskell packages can only be built for rawhide, so we're going to use the 'devel' branch. profile will copy over mock configuration files, so we can tinker with them later. This segment is only half baked, so theres's not much you can do with profile except copy bits and use it with mock

brainfuck $ cd ..

$ ports profile profiles/devel configure_from_system devel

$ cd brainfuck/

brainfuck $ ports package fetch_sourceballs

brainfuck $ ls -Al
totaal 20
drwxr-sr-x 4 yankee yankee 4096 jan 20 23:07 brainfuck-0.1/
lrwxrwxrwx 1 yankee yankee   74 jan 20 23:17 brainfuck-0.1.tar.gz -> ~/haskell/brainfuck/brainfuck-0.1/.pkg_src/brainfuck-0.1.tar.gz
-rw-r--r-- 1 yankee yankee 2456 jan 20 23:11 brainfuck.spec
-rw-r--r-- 1 yankee yankee  115 jan 20 23:17 .devshell
-rw-r--r-- 1 yankee yankee  652 jan 20 22:37 moar.FHS.patch

$ ls ~/rpmbuild/*
~/rpmbuild/BUILD:

~/rpmbuild/BUILDROOT:

~/rpmbuild/RPMS:
i386/  noarch/  x86_64/

~/rpmbuild/SOURCES:

~/rpmbuild/SPECS:

~/rpmbuild/SRPMS:

$ ports build ~/rpmbuild setup_source brainfuck

$ ls -l ~/rpmbuild/* 
~/rpmbuild/BUILD:
totaal 0

~/rpmbuild/BUILDROOT:
totaal 0

~/rpmbuild/RPMS:
totaal 12
drwxr-sr-x 2 yankee yankee 4096 dec 16 00:22 i386/
drwxr-sr-x 2 yankee yankee 4096 dec 16 00:22 noarch/
drwxr-sr-x 2 yankee yankee 4096 jan  7 22:50 x86_64/

~/rpmbuild/SOURCES:
totaal 0
lrwxrwxrwx 1 yankee yankee 51 jan 20 23:19 brainfuck-0.1.tar.gz -> ~/haskell/brainfuck/brainfuck-0.1.tar.gz
lrwxrwxrwx 1 yankee yankee 45 jan 20 23:19 moar.FHS.patch -> ~/haskell/brainfuck/moar.FHS.patch

~/rpmbuild/SPECS:
totaal 0
lrwxrwxrwx 1 yankee yankee 45 jan 20 23:19 brainfuck.spec -> ~/haskell/brainfuck/brainfuck.spec

~/rpmbuild/SRPMS:
totaal 0

mock will actually run setup_sources for us later on. This just demonstrates what it does. The code is also a bit half-baked.

Building the RPM in Mock

$ ports mock profiles/devel ~/rpmbuild build_rpm brainfuck
[INFO] mock compiling brainfuck-0.1-1.fc10.src.rpm... please wait

$ cd profiles/devel/

profiles/devel $ ls -Al
totaal 92
-rw-r--r-- 1 yankee yankee 15078 jan 20 23:22 brainfuck-0.1-1.fc10.src.rpm
-rw-rw-r-- 1 yankee yankee 24873 jan 20 23:35 build.log
-rw-r--r-- 1 yankee yankee   117 jan 20 23:35 .devshell
drwxr-xr-x 2 yankee yankee  4096 jan  5 15:12 mock/
-rw-r--r-- 1 yankee yankee  1013 jan 20 23:35 mock.log
-rw-rw-r-- 1 yankee yankee 24794 jan 20 23:35 root.log
-rw-rw-r-- 1 yankee yankee   375 jan 20 23:35 state.log

profiles/devel $ cat .devshell 
type = profile
name = devel
branch = devel
koji_target = dist-devel
distval = rawhide
distvar = fedora
dist = .devel

profiles/devel $ cat mock.log 
-- Beginning log of mock.log at 2009-01-20 23:22:12.783201 --
INFO: mock.py version 0.9.13 starting...
State Changed: init plugins
State Changed: start
INFO: Start(brainfuck-0.1-1.fc10.src.rpm)  Config(fedora-rawhide-i386)
State Changed: lock buildroot
State Changed: clean
State Changed: init
State Changed: lock buildroot
INFO: enabled root cache
State Changed: unpacking root cache
INFO: enabled yum cache
State Changed: cleaning yum metadata
INFO: enabled ccache
State Changed: running yum
State Changed: setup
State Changed: build
ERROR: Exception(brainfuck-0.1-1.fc10.src.rpm) Config(fedora-rawhide-i386) 12 minutes 58 seconds
INFO: Results and/or logs in: ~/haskell/profiles/devel
INFO: Cleaning up build root ('clean_on_failure=True')
State Changed: lock buildroot
State Changed: clean
ERROR: Command failed. See logs for output.
 # ['bash', '--login', '-c', 'rpmbuild -bb --target i386 --nodeps builddir/build/SPECS/brainfuck.spec']
-- Ending log of mock.log at 2009-01-20 23:35:17.194359 --

In reality, setting up the source is not necessary. In the latest upstream, mock.build_rpm can actually set up the source for you.

Conclusion

Clearly mock failed. I guess that spec file wasn't perfect. Because of the use of symlinks, however, i can simply edit the spec file, make the necessary changes, and rerun the command to initialize mock. Fedora Devshell will automatically build the source RPM, and send the appropriate command to mock to use a premade profile. There will be more you can do with this here.

This concludes the tutorial section. For more information about what you can do with Fedora Devshell, have a look at the Developers Guide.